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*66130Spendry static char sccsid[] = "@(#)mount.c 8.7 (Berkeley) 02/17/94"; 1639322Smckusick #endif /* not lint */ 1721156Sdist 1812808Ssam #include <sys/param.h> 1938445Smckusick #include <sys/time.h> 2039133Smckusick #include <sys/wait.h> 2145524Sbostic #include <sys/errno.h> 22*66130Spendry #include <signal.h> 2338445Smckusick #include <sys/mount.h> 2445524Sbostic #include <fstab.h> 2545524Sbostic #include <string.h> 2645524Sbostic #include <stdio.h> 2745524Sbostic #include <stdlib.h> 28*66130Spendry #include <unistd.h> 2945524Sbostic #include "pathnames.h" 301057Sbill 3140369Smckusick #define DEFAULT_ROOTUID -2 3240369Smckusick 3335339Sbostic #define BADTYPE(type) \ 3435339Sbostic (strcmp(type, FSTAB_RO) && strcmp(type, FSTAB_RW) && \ 3535339Sbostic strcmp(type, FSTAB_RQ)) 3635339Sbostic #define SETTYPE(type) \ 3735339Sbostic (!strcmp(type, FSTAB_RW) || !strcmp(type, FSTAB_RQ)) 381057Sbill 3956841Smckusick int debug, force, verbose, updateflg, mnttype; 40*66130Spendry char *mntname; 41*66130Spendry char **vfslist; 42*66130Spendry static int badvfstype __P((int, char **)); 43*66130Spendry static int badvfsname __P((char *, char **)); 44*66130Spendry static int getexecopts __P((char *, char **)); 45*66130Spendry static struct statfs *getmntpt __P((char *)); 46*66130Spendry static int getmnttype __P((char *)); 47*66130Spendry static void getstdopts __P((char *, int *)); 48*66130Spendry static void getufsopts __P((char *, int *)); 49*66130Spendry static char **makevfslist __P((char *)); 50*66130Spendry static int mountfs __P((char *, char *, int, char *, char *, char *)); 51*66130Spendry static void prmount __P((char *, char *, int)); 52*66130Spendry static void usage __P((void)); 5339131Smckusick 54*66130Spendry int 55*66130Spendry main(argc, argv) 565073Sroot int argc; 575073Sroot char **argv; 581057Sbill { 59*66130Spendry struct fstab *fs; 6040496Smckusick int all, ch, rval, flags, ret, pid, i; 6138632Smckusick long mntsize; 62*66130Spendry struct statfs *mntbuf; 6339131Smckusick char *type, *options = NULL; 6440496Smckusick FILE *pidfile; 651057Sbill 6635339Sbostic all = 0; 6735339Sbostic type = NULL; 6838445Smckusick mnttype = MOUNT_UFS; 6939322Smckusick mntname = "ufs"; 7056841Smckusick while ((ch = getopt(argc, argv, "adfrwuvt:o:")) != EOF) 7135339Sbostic switch((char)ch) { 7235339Sbostic case 'a': 7335339Sbostic all = 1; 7435339Sbostic break; 7556841Smckusick case 'd': 7656841Smckusick debug = 1; 7756841Smckusick break; 7835339Sbostic case 'f': 7956841Smckusick force = 1; 8035339Sbostic break; 8135339Sbostic case 'r': 8212808Ssam type = FSTAB_RO; 8335339Sbostic break; 8439333Smckusick case 'u': 8541403Smckusick updateflg = MNT_UPDATE; 8639333Smckusick break; 8735339Sbostic case 'v': 8835339Sbostic verbose = 1; 8935339Sbostic break; 9035339Sbostic case 'w': 9135339Sbostic type = FSTAB_RW; 9235339Sbostic break; 9339131Smckusick case 'o': 9439131Smckusick options = optarg; 9539131Smckusick break; 9638445Smckusick case 't': 9740051Smckusick vfslist = makevfslist(optarg); 9839322Smckusick mnttype = getmnttype(optarg); 9939322Smckusick break; 10035339Sbostic case '?': 10135339Sbostic default: 10235339Sbostic usage(); 10339131Smckusick /* NOTREACHED */ 1045073Sroot } 10535339Sbostic argc -= optind; 10635339Sbostic argv += optind; 10735339Sbostic 10835339Sbostic /* NOSTRICT */ 10935339Sbostic 1104460Sroot if (all) { 11135369Sbostic rval = 0; 11239333Smckusick while (fs = getfsent()) { 11335372Sbostic if (BADTYPE(fs->fs_type)) 11435372Sbostic continue; 11540844Smckusick if (badvfsname(fs->fs_vfstype, vfslist)) 11640051Smckusick continue; 11735372Sbostic /* `/' is special, it's always mounted */ 11835372Sbostic if (!strcmp(fs->fs_file, "/")) 11941403Smckusick flags = MNT_UPDATE; 12039333Smckusick else 12139333Smckusick flags = updateflg; 12239333Smckusick mnttype = getmnttype(fs->fs_vfstype); 12339333Smckusick rval |= mountfs(fs->fs_spec, fs->fs_file, flags, 12439333Smckusick type, options, fs->fs_mntops); 12535372Sbostic } 12635341Sbostic exit(rval); 12735339Sbostic } 1285073Sroot 12935339Sbostic if (argc == 0) { 13056841Smckusick if (verbose || debug || type) 13135339Sbostic usage(); 13240337Smckusick if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) { 13345689Smckusick (void) fprintf(stderr, 13439319Smckusick "mount: cannot get mount information\n"); 13538632Smckusick exit(1); 13638632Smckusick } 13740844Smckusick for (i = 0; i < mntsize; i++) { 13840844Smckusick if (badvfstype(mntbuf[i].f_type, vfslist)) 13940844Smckusick continue; 14038632Smckusick prmount(mntbuf[i].f_mntfromname, mntbuf[i].f_mntonname, 14139316Smckusick mntbuf[i].f_flags); 14240844Smckusick } 1434460Sroot exit(0); 1441057Sbill } 14512808Ssam 14639465Smckusick if (argc == 1 && updateflg) { 14739465Smckusick if ((mntbuf = getmntpt(*argv)) == NULL) { 14845689Smckusick (void) fprintf(stderr, 14939465Smckusick "mount: unknown special file or file system %s.\n", 15039465Smckusick *argv); 15139465Smckusick exit(1); 15239465Smckusick } 15339465Smckusick mnttype = mntbuf->f_type; 15453711Smckusick if ((fs = getfsfile(mntbuf->f_mntonname)) == NULL) { 15553711Smckusick (void) fprintf(stderr, 15653711Smckusick "mount: can't find fstab entry for %s.\n", *argv); 15753711Smckusick exit(1); 15840124Smckusick } 15953711Smckusick mntname = fs->fs_vfstype; 16053711Smckusick 16153711Smckusick /* 16253711Smckusick * Default type to fstab version if none specified on the 16353711Smckusick * command line. 16453711Smckusick */ 16553711Smckusick if (type == NULL) 16653711Smckusick type = fs->fs_type; 16753711Smckusick 16853711Smckusick /* 16953711Smckusick * Default options to fstab version if none specified on the 17053711Smckusick * command line. 17153711Smckusick */ 17253711Smckusick if (options == NULL) 17353711Smckusick options = fs->fs_mntops; 17453711Smckusick else { 175*66130Spendry char *cp; 17653711Smckusick 17753711Smckusick /* 17853711Smckusick * Concat the two strings with the command line 17953711Smckusick * options last so that they will override the 18053711Smckusick * fstab options. 18153711Smckusick */ 18253711Smckusick i = strlen(fs->fs_mntops) + strlen(options) + 2; 18353711Smckusick if ((cp = malloc((size_t)i)) == NULL) { 18453711Smckusick (void) fprintf(stderr, 18553711Smckusick "mount: -u malloc failed\n"); 18653711Smckusick exit(1); 18753711Smckusick } 18853711Smckusick sprintf(cp, "%s,%s", fs->fs_mntops, options); 18953711Smckusick options = cp; 19053711Smckusick } 19153711Smckusick ret = mountfs(fs->fs_spec, mntbuf->f_mntonname, 19242253Sbostic updateflg, type, options, (char *)NULL); 19340496Smckusick } else if (argc == 1) { 19435339Sbostic if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) { 19545689Smckusick (void) fprintf(stderr, 19635339Sbostic "mount: unknown special file or file system %s.\n", 19735339Sbostic *argv); 19835339Sbostic exit(1); 19935339Sbostic } 20035339Sbostic if (BADTYPE(fs->fs_type)) { 20145689Smckusick (void) fprintf(stderr, 20235339Sbostic "mount: %s has unknown file system type.\n", *argv); 20335339Sbostic exit(1); 20435339Sbostic } 20539333Smckusick mnttype = getmnttype(fs->fs_vfstype); 20640496Smckusick ret = mountfs(fs->fs_spec, fs->fs_file, updateflg, 20740496Smckusick type, options, fs->fs_mntops); 20840496Smckusick } else if (argc != 2) { 20940496Smckusick usage(); 21040496Smckusick ret = 1; 21140496Smckusick } else { 21242857Smckusick /* 21342857Smckusick * If -t flag has not been specified, and spec 21442857Smckusick * contains either a ':' or a '@' then assume that 21542857Smckusick * an NFS filesystem is being specified ala Sun. 21642857Smckusick */ 21742857Smckusick if (vfslist == (char **)0 && 21852182Smckusick (index(argv[0], ':') || index(argv[0], '@'))) { 21942857Smckusick mnttype = MOUNT_NFS; 22052182Smckusick mntname = "nfs"; 22152182Smckusick } 22242253Sbostic ret = mountfs(argv[0], argv[1], updateflg, type, options, 22342253Sbostic (char *)NULL); 22412808Ssam } 22540496Smckusick if ((pidfile = fopen(_PATH_MOUNTDPID, "r")) != NULL) { 22640496Smckusick pid = 0; 22740496Smckusick fscanf(pidfile, "%d", &pid); 22840496Smckusick fclose(pidfile); 22940496Smckusick if (pid > 0) 23040496Smckusick kill(pid, SIGHUP); 23140496Smckusick } 23240496Smckusick exit (ret); 23312808Ssam } 23412808Ssam 235*66130Spendry static int 23639333Smckusick mountfs(spec, name, flags, type, options, mntopts) 23739131Smckusick char *spec, *name, *type, *options, *mntopts; 23839333Smckusick int flags; 23912808Ssam { 240*66130Spendry int status; 24142253Sbostic pid_t pid; 24242253Sbostic int argc, i; 24338070Smckusick struct ufs_args args; 24439131Smckusick char *argp, *argv[50]; 24539322Smckusick char execname[MAXPATHLEN + 1], flagval[12]; 2461057Sbill 24739333Smckusick if (mntopts) 24839333Smckusick getstdopts(mntopts, &flags); 24939316Smckusick if (options) 25039316Smckusick getstdopts(options, &flags); 25139333Smckusick if (type) 25239333Smckusick getstdopts(type, &flags); 25356841Smckusick if (force) 25456841Smckusick flags |= MNT_FORCE; 25539316Smckusick switch (mnttype) { 25639316Smckusick case MOUNT_UFS: 25739333Smckusick if (mntopts) 25839333Smckusick getufsopts(mntopts, &flags); 25939316Smckusick if (options) 26039316Smckusick getufsopts(options, &flags); 26139316Smckusick args.fspec = spec; 26265714Shibler args.export.ex_root = DEFAULT_ROOTUID; 26341403Smckusick if (flags & MNT_RDONLY) 26465714Shibler args.export.ex_flags = MNT_EXRDONLY; 26540496Smckusick else 26665714Shibler args.export.ex_flags = 0; 26739316Smckusick argp = (caddr_t)&args; 26839316Smckusick break; 26938632Smckusick 27052110Smckusick case MOUNT_MFS: 27139316Smckusick case MOUNT_NFS: 27239322Smckusick default: 27339322Smckusick argv[0] = mntname; 27439329Smckusick argc = 1; 27539322Smckusick if (flags) { 27639322Smckusick argv[argc++] = "-F"; 27739322Smckusick sprintf(flagval, "%d", flags); 27839322Smckusick argv[argc++] = flagval; 27939322Smckusick } 28039333Smckusick if (mntopts) 28139333Smckusick argc += getexecopts(mntopts, &argv[argc]); 28239329Smckusick if (options) 28339329Smckusick argc += getexecopts(options, &argv[argc]); 28439316Smckusick argv[argc++] = spec; 28539316Smckusick argv[argc++] = name; 28639521Smckusick argv[argc++] = NULL; 28739603Smckusick sprintf(execname, "%s/mount_%s", _PATH_EXECDIR, mntname); 28839316Smckusick if (verbose) { 28942253Sbostic (void)printf("exec: %s", execname); 29042253Sbostic for (i = 1; i < argc - 1; i++) 29142253Sbostic (void)printf(" %s", argv[i]); 29242253Sbostic (void)printf("\n"); 29339316Smckusick } 29456841Smckusick if (debug) 29539316Smckusick break; 29642253Sbostic if (pid = vfork()) { 29742253Sbostic if (pid == -1) { 29839322Smckusick perror("mount: vfork starting file system"); 29939316Smckusick return (1); 30039131Smckusick } 301*66130Spendry if (waitpid(pid, &status, 0) != -1 && 30239316Smckusick WIFEXITED(status) && 30339316Smckusick WEXITSTATUS(status) != 0) 30439316Smckusick return (WEXITSTATUS(status)); 30539322Smckusick spec = mntname; 30639316Smckusick goto out; 30739316Smckusick } 308*66130Spendry execv(execname, argv); 30945689Smckusick (void) fprintf(stderr, "mount: cannot exec %s for %s: ", 31039603Smckusick execname, name); 31142253Sbostic perror((char *)NULL); 312*66130Spendry exit(1); 31339316Smckusick /* NOTREACHED */ 31438632Smckusick 31539316Smckusick } 31656841Smckusick if (!debug && mount(mnttype, name, flags, argp)) { 31745689Smckusick (void) fprintf(stderr, "%s on %s: ", spec, name); 31839316Smckusick switch (errno) { 31939316Smckusick case EMFILE: 32045689Smckusick (void) fprintf(stderr, "Mount table full\n"); 32139316Smckusick break; 32239316Smckusick case EINVAL: 32341403Smckusick if (flags & MNT_UPDATE) 32445689Smckusick (void) fprintf(stderr, "Specified device %s\n", 32545689Smckusick "does not match mounted device"); 32645569Skarels else if (mnttype == MOUNT_UFS) 32745689Smckusick (void) fprintf(stderr, "Bogus super block\n"); 32839333Smckusick else 32945569Skarels perror((char *)NULL); 33039316Smckusick break; 33139316Smckusick default: 33239316Smckusick perror((char *)NULL); 33339316Smckusick break; 3344460Sroot } 335*66130Spendry return (1); 3364460Sroot } 33735339Sbostic 33839131Smckusick out: 33912808Ssam if (verbose) 34039316Smckusick prmount(spec, name, flags); 34135339Sbostic 342*66130Spendry return (0); 3431057Sbill } 34435339Sbostic 34546708Sbostic static void 34639316Smckusick prmount(spec, name, flags) 34739316Smckusick char *spec, *name; 348*66130Spendry int flags; 34935339Sbostic { 350*66130Spendry int first; 35138632Smckusick 35242253Sbostic (void)printf("%s on %s", spec, name); 35342253Sbostic if (!(flags & MNT_VISFLAGMASK)) { 35442253Sbostic (void)printf("\n"); 35542253Sbostic return; 35642253Sbostic } 35742253Sbostic first = 0; 35842253Sbostic #define PR(msg) (void)printf("%s%s", !first++ ? " (" : ", ", msg) 35941403Smckusick if (flags & MNT_RDONLY) 36042253Sbostic PR("read-only"); 36141403Smckusick if (flags & MNT_NOEXEC) 36242253Sbostic PR("noexec"); 36341403Smckusick if (flags & MNT_NOSUID) 36442253Sbostic PR("nosuid"); 36541403Smckusick if (flags & MNT_NODEV) 36642253Sbostic PR("nodev"); 36741403Smckusick if (flags & MNT_SYNCHRONOUS) 36842253Sbostic PR("synchronous"); 36965609Smckusick if (flags & MNT_ASYNC) 37065609Smckusick PR("asynchronous"); 37141403Smckusick if (flags & MNT_QUOTA) 37242253Sbostic PR("with quotas"); 37341403Smckusick if (flags & MNT_LOCAL) 37442253Sbostic PR("local"); 37555394Spendry if (flags & MNT_UNION) 37655394Spendry PR("union"); 37741403Smckusick if (flags & MNT_EXPORTED) 37852110Smckusick PR("NFS exported"); 37942253Sbostic (void)printf(")\n"); 38035339Sbostic } 38135339Sbostic 382*66130Spendry static int 38339133Smckusick getmnttype(fstype) 38439133Smckusick char *fstype; 38539133Smckusick { 38639133Smckusick 38739322Smckusick mntname = fstype; 38839133Smckusick if (!strcmp(fstype, "ufs")) 38939133Smckusick return (MOUNT_UFS); 39039133Smckusick return (0); 39139133Smckusick } 39239133Smckusick 393*66130Spendry static void 39438632Smckusick usage() 39535339Sbostic { 39640871Smckusick 39745689Smckusick (void) fprintf(stderr, 39845689Smckusick "usage:\n mount %s %s\n mount %s\n mount %s\n", 39952110Smckusick "[ -frwu ] [ -t ufs | external_type ]", 40040871Smckusick "[ -o options ] special node", 40152110Smckusick "[ -afrwu ] [ -t ufs | external_type ]", 40240871Smckusick "[ -frwu ] special | node"); 40335339Sbostic exit(1); 40435339Sbostic } 40535339Sbostic 406*66130Spendry static void 40739316Smckusick getstdopts(options, flagp) 40839316Smckusick char *options; 40942253Sbostic int *flagp; 41039316Smckusick { 411*66130Spendry 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, ",")) { 41765852Smckusick if (opt[0] == '-') 41865852Smckusick continue; 41939316Smckusick if (opt[0] == 'n' && opt[1] == 'o') { 42039316Smckusick negative++; 42139316Smckusick opt += 2; 42239316Smckusick } else { 42339316Smckusick negative = 0; 42439316Smckusick } 42539333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RO)) { 42641403Smckusick *flagp |= MNT_RDONLY; 42739333Smckusick continue; 42839333Smckusick } 42939333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RW)) { 43041403Smckusick *flagp &= ~MNT_RDONLY; 43139333Smckusick continue; 43239333Smckusick } 43339316Smckusick if (!strcasecmp(opt, "exec")) { 43439316Smckusick if (negative) 43541403Smckusick *flagp |= MNT_NOEXEC; 43639333Smckusick else 43741403Smckusick *flagp &= ~MNT_NOEXEC; 43839316Smckusick continue; 43939316Smckusick } 44039316Smckusick if (!strcasecmp(opt, "suid")) { 44139316Smckusick if (negative) 44241403Smckusick *flagp |= MNT_NOSUID; 44339333Smckusick else 44441403Smckusick *flagp &= ~MNT_NOSUID; 44539316Smckusick continue; 44639316Smckusick } 44739316Smckusick if (!strcasecmp(opt, "dev")) { 44839316Smckusick if (negative) 44941403Smckusick *flagp |= MNT_NODEV; 45039333Smckusick else 45141403Smckusick *flagp &= ~MNT_NODEV; 45239316Smckusick continue; 45339316Smckusick } 45439316Smckusick if (!strcasecmp(opt, "synchronous")) { 45539316Smckusick if (!negative) 45641403Smckusick *flagp |= MNT_SYNCHRONOUS; 45739333Smckusick else 45841403Smckusick *flagp &= ~MNT_SYNCHRONOUS; 45939316Smckusick continue; 46039316Smckusick } 46165609Smckusick if (!strcasecmp(opt, "asynchronous")) { 46265609Smckusick if (!negative) 46365609Smckusick *flagp |= MNT_ASYNC; 46465609Smckusick else 46565609Smckusick *flagp &= ~MNT_ASYNC; 46665609Smckusick continue; 46765609Smckusick } 46855394Spendry if (!strcasecmp(opt, "union")) { 46955394Spendry if (!negative) 47055394Spendry *flagp |= MNT_UNION; 47155394Spendry else 47255394Spendry *flagp &= ~MNT_UNION; 47355394Spendry continue; 47455394Spendry } 47565852Smckusick (void) fprintf(stderr, "mount: %s: unknown option\n", opt); 47639316Smckusick } 47739316Smckusick } 47839316Smckusick 47942253Sbostic /* ARGSUSED */ 480*66130Spendry static void 48139131Smckusick getufsopts(options, flagp) 48239131Smckusick char *options; 48342253Sbostic int *flagp; 48439131Smckusick { 485*66130Spendry 48639131Smckusick return; 48739131Smckusick } 48839131Smckusick 489*66130Spendry static int 49039329Smckusick getexecopts(options, argv) 49139131Smckusick char *options; 49239131Smckusick char **argv; 49339131Smckusick { 494*66130Spendry int argc = 0; 495*66130Spendry char *opt; 49639131Smckusick 49742253Sbostic for (opt = strtok(options, ","); opt; opt = strtok((char *)NULL, ",")) { 49839131Smckusick if (opt[0] != '-') 49939131Smckusick continue; 50039131Smckusick argv[argc++] = opt; 50139131Smckusick if (opt[2] == '\0' || opt[2] != '=') 50239131Smckusick continue; 50339131Smckusick opt[2] = '\0'; 50439131Smckusick argv[argc++] = &opt[3]; 50539131Smckusick } 50639131Smckusick return (argc); 50739131Smckusick } 50839131Smckusick 509*66130Spendry static struct statfs * 51039465Smckusick getmntpt(name) 51139465Smckusick char *name; 51239465Smckusick { 51339465Smckusick long mntsize; 514*66130Spendry long i; 51539465Smckusick struct statfs *mntbuf; 51639465Smckusick 51740337Smckusick mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 51839465Smckusick for (i = 0; i < mntsize; i++) { 51939465Smckusick if (!strcmp(mntbuf[i].f_mntfromname, name) || 52039465Smckusick !strcmp(mntbuf[i].f_mntonname, name)) 52139465Smckusick return (&mntbuf[i]); 52239465Smckusick } 52339465Smckusick return ((struct statfs *)0); 52439465Smckusick } 52539465Smckusick 52640051Smckusick static int skipvfs; 52740051Smckusick 528*66130Spendry static int 52940051Smckusick badvfstype(vfstype, vfslist) 530*66130Spendry int vfstype; 53140051Smckusick char **vfslist; 53240051Smckusick { 53340051Smckusick 53440051Smckusick if (vfslist == 0) 535*66130Spendry return (0); 53640051Smckusick while (*vfslist) { 53740844Smckusick if (vfstype == getmnttype(*vfslist)) 538*66130Spendry return (skipvfs); 53940051Smckusick vfslist++; 54040051Smckusick } 54140051Smckusick return (!skipvfs); 54240051Smckusick } 54340051Smckusick 544*66130Spendry static int 54540844Smckusick badvfsname(vfsname, vfslist) 54640844Smckusick char *vfsname; 54740844Smckusick char **vfslist; 54840844Smckusick { 54940844Smckusick 55040844Smckusick if (vfslist == 0) 551*66130Spendry return (0); 55240844Smckusick while (*vfslist) { 55340844Smckusick if (strcmp(vfsname, *vfslist) == 0) 554*66130Spendry return (skipvfs); 55540844Smckusick vfslist++; 55640844Smckusick } 55740844Smckusick return (!skipvfs); 55840844Smckusick } 55940844Smckusick 560*66130Spendry static char ** 56140051Smckusick makevfslist(fslist) 56240051Smckusick char *fslist; 56340051Smckusick { 564*66130Spendry char **av, *nextcp; 565*66130Spendry int i; 56640051Smckusick 56740051Smckusick if (fslist == NULL) 56840051Smckusick return (NULL); 56940051Smckusick if (fslist[0] == 'n' && fslist[1] == 'o') { 57040051Smckusick fslist += 2; 57140051Smckusick skipvfs = 1; 57240051Smckusick } 57340051Smckusick for (i = 0, nextcp = fslist; *nextcp; nextcp++) 57440051Smckusick if (*nextcp == ',') 57540051Smckusick i++; 57642253Sbostic av = (char **)malloc((size_t)(i+2) * sizeof(char *)); 57740051Smckusick if (av == NULL) 57840051Smckusick return (NULL); 57940051Smckusick nextcp = fslist; 58040051Smckusick i = 0; 58140051Smckusick av[i++] = nextcp; 58240051Smckusick while (nextcp = index(nextcp, ',')) { 58340051Smckusick *nextcp++ = '\0'; 58440051Smckusick av[i++] = nextcp; 58540051Smckusick } 58640051Smckusick av[i++] = 0; 58740051Smckusick return (av); 58840051Smckusick } 589