121156Sdist /* 261503Sbostic * Copyright (c) 1980, 1989, 1993 361503Sbostic * The Regents of the University of California. All rights reserved. 439322Smckusick * 542702Sbostic * %sccs.include.redist.c% 621156Sdist */ 721156Sdist 810811Ssam #ifndef lint 961503Sbostic static char copyright[] = 1061503Sbostic "@(#) Copyright (c) 1980, 1989, 1993\n\ 1161503Sbostic The Regents of the University of California. All rights reserved.\n"; 1239322Smckusick #endif /* not lint */ 131057Sbill 1421156Sdist #ifndef lint 15*65714Shibler static char sccsid[] = "@(#)mount.c 8.3 (Berkeley) 01/12/94"; 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> 2245524Sbostic #include <sys/errno.h> 2345524Sbostic #include <sys/signal.h> 2452110Smckusick #include <sys/ucred.h> 2538445Smckusick #include <sys/mount.h> 2645524Sbostic #include <fstab.h> 2745524Sbostic #include <string.h> 2845524Sbostic #include <stdio.h> 2945524Sbostic #include <stdlib.h> 3045524Sbostic #include "pathnames.h" 311057Sbill 3240369Smckusick #define DEFAULT_ROOTUID -2 3340369Smckusick 3435339Sbostic #define BADTYPE(type) \ 3535339Sbostic (strcmp(type, FSTAB_RO) && strcmp(type, FSTAB_RW) && \ 3635339Sbostic strcmp(type, FSTAB_RQ)) 3735339Sbostic #define SETTYPE(type) \ 3835339Sbostic (!strcmp(type, FSTAB_RW) || !strcmp(type, FSTAB_RQ)) 391057Sbill 4056841Smckusick int debug, force, verbose, updateflg, mnttype; 4139322Smckusick char *mntname, **envp; 4240051Smckusick char **vfslist, **makevfslist(); 4346708Sbostic static void prmount(); 4439131Smckusick 4539131Smckusick main(argc, argv, arge) 465073Sroot int argc; 475073Sroot char **argv; 4839131Smckusick char **arge; 491057Sbill { 5035339Sbostic extern char *optarg; 5135339Sbostic extern int optind; 5235339Sbostic register struct fstab *fs; 5340496Smckusick int all, ch, rval, flags, ret, pid, i; 5438632Smckusick long mntsize; 5539465Smckusick struct statfs *mntbuf, *getmntpt(); 5639131Smckusick char *type, *options = NULL; 5740496Smckusick FILE *pidfile; 581057Sbill 5939131Smckusick envp = arge; 6035339Sbostic all = 0; 6135339Sbostic type = NULL; 6238445Smckusick mnttype = MOUNT_UFS; 6339322Smckusick mntname = "ufs"; 6456841Smckusick while ((ch = getopt(argc, argv, "adfrwuvt:o:")) != EOF) 6535339Sbostic switch((char)ch) { 6635339Sbostic case 'a': 6735339Sbostic all = 1; 6835339Sbostic break; 6956841Smckusick case 'd': 7056841Smckusick debug = 1; 7156841Smckusick break; 7235339Sbostic case 'f': 7356841Smckusick force = 1; 7435339Sbostic break; 7535339Sbostic case 'r': 7612808Ssam type = FSTAB_RO; 7735339Sbostic break; 7839333Smckusick case 'u': 7941403Smckusick updateflg = MNT_UPDATE; 8039333Smckusick break; 8135339Sbostic case 'v': 8235339Sbostic verbose = 1; 8335339Sbostic break; 8435339Sbostic case 'w': 8535339Sbostic type = FSTAB_RW; 8635339Sbostic break; 8739131Smckusick case 'o': 8839131Smckusick options = optarg; 8939131Smckusick break; 9038445Smckusick case 't': 9140051Smckusick vfslist = makevfslist(optarg); 9239322Smckusick mnttype = getmnttype(optarg); 9339322Smckusick break; 9435339Sbostic case '?': 9535339Sbostic default: 9635339Sbostic usage(); 9739131Smckusick /* NOTREACHED */ 985073Sroot } 9935339Sbostic argc -= optind; 10035339Sbostic argv += optind; 10135339Sbostic 10235339Sbostic /* NOSTRICT */ 10335339Sbostic 1044460Sroot if (all) { 10535369Sbostic rval = 0; 10639333Smckusick while (fs = getfsent()) { 10735372Sbostic if (BADTYPE(fs->fs_type)) 10835372Sbostic continue; 10940844Smckusick if (badvfsname(fs->fs_vfstype, vfslist)) 11040051Smckusick continue; 11135372Sbostic /* `/' is special, it's always mounted */ 11235372Sbostic if (!strcmp(fs->fs_file, "/")) 11341403Smckusick flags = MNT_UPDATE; 11439333Smckusick else 11539333Smckusick flags = updateflg; 11639333Smckusick mnttype = getmnttype(fs->fs_vfstype); 11739333Smckusick rval |= mountfs(fs->fs_spec, fs->fs_file, flags, 11839333Smckusick type, options, fs->fs_mntops); 11935372Sbostic } 12035341Sbostic exit(rval); 12135339Sbostic } 1225073Sroot 12335339Sbostic if (argc == 0) { 12456841Smckusick if (verbose || debug || type) 12535339Sbostic usage(); 12640337Smckusick if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) { 12745689Smckusick (void) fprintf(stderr, 12839319Smckusick "mount: cannot get mount information\n"); 12938632Smckusick exit(1); 13038632Smckusick } 13140844Smckusick for (i = 0; i < mntsize; i++) { 13240844Smckusick if (badvfstype(mntbuf[i].f_type, vfslist)) 13340844Smckusick continue; 13438632Smckusick prmount(mntbuf[i].f_mntfromname, mntbuf[i].f_mntonname, 13539316Smckusick mntbuf[i].f_flags); 13640844Smckusick } 1374460Sroot exit(0); 1381057Sbill } 13912808Ssam 14039465Smckusick if (argc == 1 && updateflg) { 14139465Smckusick if ((mntbuf = getmntpt(*argv)) == NULL) { 14245689Smckusick (void) fprintf(stderr, 14339465Smckusick "mount: unknown special file or file system %s.\n", 14439465Smckusick *argv); 14539465Smckusick exit(1); 14639465Smckusick } 14739465Smckusick mnttype = mntbuf->f_type; 14853711Smckusick if ((fs = getfsfile(mntbuf->f_mntonname)) == NULL) { 14953711Smckusick (void) fprintf(stderr, 15053711Smckusick "mount: can't find fstab entry for %s.\n", *argv); 15153711Smckusick exit(1); 15240124Smckusick } 15353711Smckusick mntname = fs->fs_vfstype; 15453711Smckusick 15553711Smckusick /* 15653711Smckusick * Default type to fstab version if none specified on the 15753711Smckusick * command line. 15853711Smckusick */ 15953711Smckusick if (type == NULL) 16053711Smckusick type = fs->fs_type; 16153711Smckusick 16253711Smckusick /* 16353711Smckusick * Default options to fstab version if none specified on the 16453711Smckusick * command line. 16553711Smckusick */ 16653711Smckusick if (options == NULL) 16753711Smckusick options = fs->fs_mntops; 16853711Smckusick else { 16953711Smckusick register char *cp; 17053711Smckusick 17153711Smckusick /* 17253711Smckusick * Concat the two strings with the command line 17353711Smckusick * options last so that they will override the 17453711Smckusick * fstab options. 17553711Smckusick */ 17653711Smckusick i = strlen(fs->fs_mntops) + strlen(options) + 2; 17753711Smckusick if ((cp = malloc((size_t)i)) == NULL) { 17853711Smckusick (void) fprintf(stderr, 17953711Smckusick "mount: -u malloc failed\n"); 18053711Smckusick exit(1); 18153711Smckusick } 18253711Smckusick sprintf(cp, "%s,%s", fs->fs_mntops, options); 18353711Smckusick options = cp; 18453711Smckusick } 18553711Smckusick ret = mountfs(fs->fs_spec, mntbuf->f_mntonname, 18642253Sbostic updateflg, type, options, (char *)NULL); 18740496Smckusick } else if (argc == 1) { 18835339Sbostic if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) { 18945689Smckusick (void) fprintf(stderr, 19035339Sbostic "mount: unknown special file or file system %s.\n", 19135339Sbostic *argv); 19235339Sbostic exit(1); 19335339Sbostic } 19435339Sbostic if (BADTYPE(fs->fs_type)) { 19545689Smckusick (void) 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 && 21252182Smckusick (index(argv[0], ':') || index(argv[0], '@'))) { 21342857Smckusick mnttype = MOUNT_NFS; 21452182Smckusick mntname = "nfs"; 21552182Smckusick } 21642253Sbostic ret = mountfs(argv[0], argv[1], updateflg, type, options, 21742253Sbostic (char *)NULL); 21812808Ssam } 21940496Smckusick if ((pidfile = fopen(_PATH_MOUNTDPID, "r")) != NULL) { 22040496Smckusick pid = 0; 22140496Smckusick fscanf(pidfile, "%d", &pid); 22240496Smckusick fclose(pidfile); 22340496Smckusick if (pid > 0) 22440496Smckusick kill(pid, SIGHUP); 22540496Smckusick } 22640496Smckusick exit (ret); 22712808Ssam } 22812808Ssam 22939333Smckusick mountfs(spec, name, flags, type, options, mntopts) 23039131Smckusick char *spec, *name, *type, *options, *mntopts; 23139333Smckusick int flags; 23212808Ssam { 23342253Sbostic union wait status; 23442253Sbostic pid_t pid; 23542253Sbostic int argc, i; 23638070Smckusick struct ufs_args args; 23739131Smckusick char *argp, *argv[50]; 23839322Smckusick char execname[MAXPATHLEN + 1], flagval[12]; 2391057Sbill 24039333Smckusick if (mntopts) 24139333Smckusick getstdopts(mntopts, &flags); 24239316Smckusick if (options) 24339316Smckusick getstdopts(options, &flags); 24439333Smckusick if (type) 24539333Smckusick getstdopts(type, &flags); 24656841Smckusick if (force) 24756841Smckusick flags |= MNT_FORCE; 24839316Smckusick switch (mnttype) { 24939316Smckusick case MOUNT_UFS: 25039333Smckusick if (mntopts) 25139333Smckusick getufsopts(mntopts, &flags); 25239316Smckusick if (options) 25339316Smckusick getufsopts(options, &flags); 25439316Smckusick args.fspec = spec; 255*65714Shibler args.export.ex_root = DEFAULT_ROOTUID; 25641403Smckusick if (flags & MNT_RDONLY) 257*65714Shibler args.export.ex_flags = MNT_EXRDONLY; 25840496Smckusick else 259*65714Shibler args.export.ex_flags = 0; 26039316Smckusick argp = (caddr_t)&args; 26139316Smckusick break; 26238632Smckusick 26352110Smckusick case MOUNT_MFS: 26439316Smckusick case MOUNT_NFS: 26539322Smckusick default: 26639322Smckusick argv[0] = mntname; 26739329Smckusick argc = 1; 26839322Smckusick if (flags) { 26939322Smckusick argv[argc++] = "-F"; 27039322Smckusick sprintf(flagval, "%d", flags); 27139322Smckusick argv[argc++] = flagval; 27239322Smckusick } 27339333Smckusick if (mntopts) 27439333Smckusick argc += getexecopts(mntopts, &argv[argc]); 27539329Smckusick if (options) 27639329Smckusick argc += getexecopts(options, &argv[argc]); 27739316Smckusick argv[argc++] = spec; 27839316Smckusick argv[argc++] = name; 27939521Smckusick argv[argc++] = NULL; 28039603Smckusick sprintf(execname, "%s/mount_%s", _PATH_EXECDIR, mntname); 28139316Smckusick if (verbose) { 28242253Sbostic (void)printf("exec: %s", execname); 28342253Sbostic for (i = 1; i < argc - 1; i++) 28442253Sbostic (void)printf(" %s", argv[i]); 28542253Sbostic (void)printf("\n"); 28639316Smckusick } 28756841Smckusick if (debug) 28839316Smckusick break; 28942253Sbostic if (pid = vfork()) { 29042253Sbostic if (pid == -1) { 29139322Smckusick perror("mount: vfork starting file system"); 29239316Smckusick return (1); 29339131Smckusick } 29446708Sbostic if (waitpid(pid, (int *)&status, 0) != -1 && 29539316Smckusick WIFEXITED(status) && 29639316Smckusick WEXITSTATUS(status) != 0) 29739316Smckusick return (WEXITSTATUS(status)); 29839322Smckusick spec = mntname; 29939316Smckusick goto out; 30039316Smckusick } 30139322Smckusick execve(execname, argv, envp); 30245689Smckusick (void) fprintf(stderr, "mount: cannot exec %s for %s: ", 30339603Smckusick execname, name); 30442253Sbostic perror((char *)NULL); 30539316Smckusick exit (1); 30639316Smckusick /* NOTREACHED */ 30738632Smckusick 30839316Smckusick } 30956841Smckusick if (!debug && mount(mnttype, name, flags, argp)) { 31045689Smckusick (void) fprintf(stderr, "%s on %s: ", spec, name); 31139316Smckusick switch (errno) { 31239316Smckusick case EMFILE: 31345689Smckusick (void) fprintf(stderr, "Mount table full\n"); 31439316Smckusick break; 31539316Smckusick case EINVAL: 31641403Smckusick if (flags & MNT_UPDATE) 31745689Smckusick (void) fprintf(stderr, "Specified device %s\n", 31845689Smckusick "does not match mounted device"); 31945569Skarels else if (mnttype == MOUNT_UFS) 32045689Smckusick (void) fprintf(stderr, "Bogus super block\n"); 32139333Smckusick else 32245569Skarels perror((char *)NULL); 32339316Smckusick break; 32439316Smckusick default: 32539316Smckusick perror((char *)NULL); 32639316Smckusick break; 3274460Sroot } 32839316Smckusick return(1); 3294460Sroot } 33035339Sbostic 33139131Smckusick out: 33212808Ssam if (verbose) 33339316Smckusick prmount(spec, name, flags); 33435339Sbostic 33542253Sbostic return(0); 3361057Sbill } 33735339Sbostic 33846708Sbostic static void 33939316Smckusick prmount(spec, name, flags) 34039316Smckusick char *spec, *name; 34142253Sbostic register short flags; 34235339Sbostic { 34342253Sbostic register int first; 34438632Smckusick 34542253Sbostic (void)printf("%s on %s", spec, name); 34642253Sbostic if (!(flags & MNT_VISFLAGMASK)) { 34742253Sbostic (void)printf("\n"); 34842253Sbostic return; 34942253Sbostic } 35042253Sbostic first = 0; 35142253Sbostic #define PR(msg) (void)printf("%s%s", !first++ ? " (" : ", ", msg) 35241403Smckusick if (flags & MNT_RDONLY) 35342253Sbostic PR("read-only"); 35441403Smckusick if (flags & MNT_NOEXEC) 35542253Sbostic PR("noexec"); 35641403Smckusick if (flags & MNT_NOSUID) 35742253Sbostic PR("nosuid"); 35841403Smckusick if (flags & MNT_NODEV) 35942253Sbostic PR("nodev"); 36041403Smckusick if (flags & MNT_SYNCHRONOUS) 36142253Sbostic PR("synchronous"); 36265609Smckusick if (flags & MNT_ASYNC) 36365609Smckusick PR("asynchronous"); 36441403Smckusick if (flags & MNT_QUOTA) 36542253Sbostic PR("with quotas"); 36641403Smckusick if (flags & MNT_LOCAL) 36742253Sbostic PR("local"); 36855394Spendry if (flags & MNT_UNION) 36955394Spendry PR("union"); 37041403Smckusick if (flags & MNT_EXPORTED) 37152110Smckusick PR("NFS exported"); 37242253Sbostic (void)printf(")\n"); 37335339Sbostic } 37435339Sbostic 37539133Smckusick getmnttype(fstype) 37639133Smckusick char *fstype; 37739133Smckusick { 37839133Smckusick 37939322Smckusick mntname = fstype; 38039133Smckusick if (!strcmp(fstype, "ufs")) 38139133Smckusick return (MOUNT_UFS); 38239133Smckusick if (!strcmp(fstype, "nfs")) 38339133Smckusick return (MOUNT_NFS); 38439133Smckusick if (!strcmp(fstype, "mfs")) 38539133Smckusick return (MOUNT_MFS); 38652097Sbostic if (!strcmp(fstype, "lfs")) 38752097Sbostic return (MOUNT_LFS); 388*65714Shibler if (!strcmp(fstype, "isofs")) 389*65714Shibler return (MOUNT_ISOFS); 39039133Smckusick return (0); 39139133Smckusick } 39239133Smckusick 39338632Smckusick usage() 39435339Sbostic { 39540871Smckusick 39645689Smckusick (void) fprintf(stderr, 39745689Smckusick "usage:\n mount %s %s\n mount %s\n mount %s\n", 39852110Smckusick "[ -frwu ] [ -t ufs | external_type ]", 39940871Smckusick "[ -o options ] special node", 40052110Smckusick "[ -afrwu ] [ -t ufs | external_type ]", 40140871Smckusick "[ -frwu ] special | node"); 40235339Sbostic exit(1); 40335339Sbostic } 40435339Sbostic 40539316Smckusick getstdopts(options, flagp) 40639316Smckusick char *options; 40742253Sbostic int *flagp; 40839316Smckusick { 40939316Smckusick register char *opt; 41039316Smckusick int negative; 41142253Sbostic char optbuf[BUFSIZ]; 41239316Smckusick 41342253Sbostic (void)strcpy(optbuf, options); 41442253Sbostic for (opt = strtok(optbuf, ","); opt; opt = strtok((char *)NULL, ",")) { 41539316Smckusick if (opt[0] == 'n' && opt[1] == 'o') { 41639316Smckusick negative++; 41739316Smckusick opt += 2; 41839316Smckusick } else { 41939316Smckusick negative = 0; 42039316Smckusick } 42139333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RO)) { 42241403Smckusick *flagp |= MNT_RDONLY; 42339333Smckusick continue; 42439333Smckusick } 42539333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RW)) { 42641403Smckusick *flagp &= ~MNT_RDONLY; 42739333Smckusick continue; 42839333Smckusick } 42939316Smckusick if (!strcasecmp(opt, "exec")) { 43039316Smckusick if (negative) 43141403Smckusick *flagp |= MNT_NOEXEC; 43239333Smckusick else 43341403Smckusick *flagp &= ~MNT_NOEXEC; 43439316Smckusick continue; 43539316Smckusick } 43639316Smckusick if (!strcasecmp(opt, "suid")) { 43739316Smckusick if (negative) 43841403Smckusick *flagp |= MNT_NOSUID; 43939333Smckusick else 44041403Smckusick *flagp &= ~MNT_NOSUID; 44139316Smckusick continue; 44239316Smckusick } 44339316Smckusick if (!strcasecmp(opt, "dev")) { 44439316Smckusick if (negative) 44541403Smckusick *flagp |= MNT_NODEV; 44639333Smckusick else 44741403Smckusick *flagp &= ~MNT_NODEV; 44839316Smckusick continue; 44939316Smckusick } 45039316Smckusick if (!strcasecmp(opt, "synchronous")) { 45139316Smckusick if (!negative) 45241403Smckusick *flagp |= MNT_SYNCHRONOUS; 45339333Smckusick else 45441403Smckusick *flagp &= ~MNT_SYNCHRONOUS; 45539316Smckusick continue; 45639316Smckusick } 45765609Smckusick if (!strcasecmp(opt, "asynchronous")) { 45865609Smckusick if (!negative) 45965609Smckusick *flagp |= MNT_ASYNC; 46065609Smckusick else 46165609Smckusick *flagp &= ~MNT_ASYNC; 46265609Smckusick continue; 46365609Smckusick } 46455394Spendry if (!strcasecmp(opt, "union")) { 46555394Spendry if (!negative) 46655394Spendry *flagp |= MNT_UNION; 46755394Spendry else 46855394Spendry *flagp &= ~MNT_UNION; 46955394Spendry continue; 47055394Spendry } 47139316Smckusick } 47239316Smckusick } 47339316Smckusick 47442253Sbostic /* ARGSUSED */ 47539131Smckusick getufsopts(options, flagp) 47639131Smckusick char *options; 47742253Sbostic int *flagp; 47839131Smckusick { 47939131Smckusick return; 48039131Smckusick } 48139131Smckusick 48239329Smckusick getexecopts(options, argv) 48339131Smckusick char *options; 48439131Smckusick char **argv; 48539131Smckusick { 48639131Smckusick register int argc = 0; 48739131Smckusick register char *opt; 48839131Smckusick 48942253Sbostic for (opt = strtok(options, ","); opt; opt = strtok((char *)NULL, ",")) { 49039131Smckusick if (opt[0] != '-') 49139131Smckusick continue; 49239131Smckusick argv[argc++] = opt; 49339131Smckusick if (opt[2] == '\0' || opt[2] != '=') 49439131Smckusick continue; 49539131Smckusick opt[2] = '\0'; 49639131Smckusick argv[argc++] = &opt[3]; 49739131Smckusick } 49839131Smckusick return (argc); 49939131Smckusick } 50039131Smckusick 50139465Smckusick struct statfs * 50239465Smckusick getmntpt(name) 50339465Smckusick char *name; 50439465Smckusick { 50539465Smckusick long mntsize; 50639465Smckusick register long i; 50739465Smckusick struct statfs *mntbuf; 50839465Smckusick 50940337Smckusick mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 51039465Smckusick for (i = 0; i < mntsize; i++) { 51139465Smckusick if (!strcmp(mntbuf[i].f_mntfromname, name) || 51239465Smckusick !strcmp(mntbuf[i].f_mntonname, name)) 51339465Smckusick return (&mntbuf[i]); 51439465Smckusick } 51539465Smckusick return ((struct statfs *)0); 51639465Smckusick } 51739465Smckusick 51840051Smckusick static int skipvfs; 51940051Smckusick 52040051Smckusick badvfstype(vfstype, vfslist) 52142253Sbostic short vfstype; 52240051Smckusick char **vfslist; 52340051Smckusick { 52440051Smckusick 52540051Smckusick if (vfslist == 0) 52640051Smckusick return(0); 52740051Smckusick while (*vfslist) { 52840844Smckusick if (vfstype == getmnttype(*vfslist)) 52940051Smckusick return(skipvfs); 53040051Smckusick vfslist++; 53140051Smckusick } 53240051Smckusick return (!skipvfs); 53340051Smckusick } 53440051Smckusick 53540844Smckusick badvfsname(vfsname, vfslist) 53640844Smckusick char *vfsname; 53740844Smckusick char **vfslist; 53840844Smckusick { 53940844Smckusick 54040844Smckusick if (vfslist == 0) 54140844Smckusick return(0); 54240844Smckusick while (*vfslist) { 54340844Smckusick if (strcmp(vfsname, *vfslist) == 0) 54440844Smckusick return(skipvfs); 54540844Smckusick vfslist++; 54640844Smckusick } 54740844Smckusick return (!skipvfs); 54840844Smckusick } 54940844Smckusick 55040051Smckusick char ** 55140051Smckusick makevfslist(fslist) 55240051Smckusick char *fslist; 55340051Smckusick { 55440051Smckusick register char **av, *nextcp; 55540051Smckusick register int i; 55640051Smckusick 55740051Smckusick if (fslist == NULL) 55840051Smckusick return (NULL); 55940051Smckusick if (fslist[0] == 'n' && fslist[1] == 'o') { 56040051Smckusick fslist += 2; 56140051Smckusick skipvfs = 1; 56240051Smckusick } 56340051Smckusick for (i = 0, nextcp = fslist; *nextcp; nextcp++) 56440051Smckusick if (*nextcp == ',') 56540051Smckusick i++; 56642253Sbostic av = (char **)malloc((size_t)(i+2) * sizeof(char *)); 56740051Smckusick if (av == NULL) 56840051Smckusick return (NULL); 56940051Smckusick nextcp = fslist; 57040051Smckusick i = 0; 57140051Smckusick av[i++] = nextcp; 57240051Smckusick while (nextcp = index(nextcp, ',')) { 57340051Smckusick *nextcp++ = '\0'; 57440051Smckusick av[i++] = nextcp; 57540051Smckusick } 57640051Smckusick av[i++] = 0; 57740051Smckusick return (av); 57840051Smckusick } 579