xref: /csrg-svn/sbin/mount/mount.c (revision 52182)
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*52182Smckusick static char sccsid[] = "@(#)mount.c	5.48 (Berkeley) 01/13/92";
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 
4039333Smckusick int fake, 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";
6439333Smckusick 	while ((ch = getopt(argc, argv, "afrwuvt:o:")) != EOF)
6535339Sbostic 		switch((char)ch) {
6635339Sbostic 		case 'a':
6735339Sbostic 			all = 1;
6835339Sbostic 			break;
6935339Sbostic 		case 'f':
7035339Sbostic 			fake = 1;
7135339Sbostic 			break;
7235339Sbostic 		case 'r':
7312808Ssam 			type = FSTAB_RO;
7435339Sbostic 			break;
7539333Smckusick 		case 'u':
7641403Smckusick 			updateflg = MNT_UPDATE;
7739333Smckusick 			break;
7835339Sbostic 		case 'v':
7935339Sbostic 			verbose = 1;
8035339Sbostic 			break;
8135339Sbostic 		case 'w':
8235339Sbostic 			type = FSTAB_RW;
8335339Sbostic 			break;
8439131Smckusick 		case 'o':
8539131Smckusick 			options = optarg;
8639131Smckusick 			break;
8738445Smckusick 		case 't':
8840051Smckusick 			vfslist = makevfslist(optarg);
8939322Smckusick 			mnttype = getmnttype(optarg);
9039322Smckusick 			break;
9135339Sbostic 		case '?':
9235339Sbostic 		default:
9335339Sbostic 			usage();
9439131Smckusick 			/* NOTREACHED */
955073Sroot 		}
9635339Sbostic 	argc -= optind;
9735339Sbostic 	argv += optind;
9835339Sbostic 
9935339Sbostic 	/* NOSTRICT */
10035339Sbostic 
1014460Sroot 	if (all) {
10235369Sbostic 		rval = 0;
10339333Smckusick 		while (fs = getfsent()) {
10435372Sbostic 			if (BADTYPE(fs->fs_type))
10535372Sbostic 				continue;
10640844Smckusick 			if (badvfsname(fs->fs_vfstype, vfslist))
10740051Smckusick 				continue;
10835372Sbostic 			/* `/' is special, it's always mounted */
10935372Sbostic 			if (!strcmp(fs->fs_file, "/"))
11041403Smckusick 				flags = MNT_UPDATE;
11139333Smckusick 			else
11239333Smckusick 				flags = updateflg;
11339333Smckusick 			mnttype = getmnttype(fs->fs_vfstype);
11439333Smckusick 			rval |= mountfs(fs->fs_spec, fs->fs_file, flags,
11539333Smckusick 			    type, options, fs->fs_mntops);
11635372Sbostic 		}
11735341Sbostic 		exit(rval);
11835339Sbostic 	}
1195073Sroot 
12035339Sbostic 	if (argc == 0) {
12135339Sbostic 		if (verbose || fake || type)
12235339Sbostic 			usage();
12340337Smckusick 		if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
12445689Smckusick 			(void) fprintf(stderr,
12539319Smckusick 				"mount: cannot get mount information\n");
12638632Smckusick 			exit(1);
12738632Smckusick 		}
12840844Smckusick 		for (i = 0; i < mntsize; i++) {
12940844Smckusick 			if (badvfstype(mntbuf[i].f_type, vfslist))
13040844Smckusick 				continue;
13138632Smckusick 			prmount(mntbuf[i].f_mntfromname, mntbuf[i].f_mntonname,
13239316Smckusick 				mntbuf[i].f_flags);
13340844Smckusick 		}
1344460Sroot 		exit(0);
1351057Sbill 	}
13612808Ssam 
13739465Smckusick 	if (argc == 1 && updateflg) {
13839465Smckusick 		if ((mntbuf = getmntpt(*argv)) == NULL) {
13945689Smckusick 			(void) fprintf(stderr,
14039465Smckusick 			    "mount: unknown special file or file system %s.\n",
14139465Smckusick 			    *argv);
14239465Smckusick 			exit(1);
14339465Smckusick 		}
14439465Smckusick 		mnttype = mntbuf->f_type;
14540124Smckusick 		if (!strcmp(mntbuf->f_mntfromname, "root_device")) {
14640124Smckusick 			fs = getfsfile("/");
14740124Smckusick 			strcpy(mntbuf->f_mntfromname, fs->fs_spec);
14840124Smckusick 		}
14940496Smckusick 		ret = mountfs(mntbuf->f_mntfromname, mntbuf->f_mntonname,
15042253Sbostic 		    updateflg, type, options, (char *)NULL);
15140496Smckusick 	} else if (argc == 1) {
15235339Sbostic 		if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) {
15345689Smckusick 			(void) fprintf(stderr,
15435339Sbostic 			    "mount: unknown special file or file system %s.\n",
15535339Sbostic 			    *argv);
15635339Sbostic 			exit(1);
15735339Sbostic 		}
15835339Sbostic 		if (BADTYPE(fs->fs_type)) {
15945689Smckusick 			(void) fprintf(stderr,
16035339Sbostic 			    "mount: %s has unknown file system type.\n", *argv);
16135339Sbostic 			exit(1);
16235339Sbostic 		}
16339333Smckusick 		mnttype = getmnttype(fs->fs_vfstype);
16440496Smckusick 		ret = mountfs(fs->fs_spec, fs->fs_file, updateflg,
16540496Smckusick 		    type, options, fs->fs_mntops);
16640496Smckusick 	} else if (argc != 2) {
16740496Smckusick 		usage();
16840496Smckusick 		ret = 1;
16940496Smckusick 	} else {
17042857Smckusick 		/*
17142857Smckusick 		 * If -t flag has not been specified, and spec
17242857Smckusick 		 * contains either a ':' or a '@' then assume that
17342857Smckusick 		 * an NFS filesystem is being specified ala Sun.
17442857Smckusick 		 */
17542857Smckusick 		if (vfslist == (char **)0 &&
176*52182Smckusick 		    (index(argv[0], ':') || index(argv[0], '@'))) {
17742857Smckusick 			mnttype = MOUNT_NFS;
178*52182Smckusick 			mntname = "nfs";
179*52182Smckusick 		}
18042253Sbostic 		ret = mountfs(argv[0], argv[1], updateflg, type, options,
18142253Sbostic 		    (char *)NULL);
18212808Ssam 	}
18340496Smckusick 	if ((pidfile = fopen(_PATH_MOUNTDPID, "r")) != NULL) {
18440496Smckusick 		pid = 0;
18540496Smckusick 		fscanf(pidfile, "%d", &pid);
18640496Smckusick 		fclose(pidfile);
18740496Smckusick 		if (pid > 0)
18840496Smckusick 			kill(pid, SIGHUP);
18940496Smckusick 	}
19040496Smckusick 	exit (ret);
19112808Ssam }
19212808Ssam 
19339333Smckusick mountfs(spec, name, flags, type, options, mntopts)
19439131Smckusick 	char *spec, *name, *type, *options, *mntopts;
19539333Smckusick 	int flags;
19612808Ssam {
19742253Sbostic 	union wait status;
19842253Sbostic 	pid_t pid;
19942253Sbostic 	int argc, i;
20038070Smckusick 	struct ufs_args args;
20139131Smckusick 	char *argp, *argv[50];
20239322Smckusick 	char execname[MAXPATHLEN + 1], flagval[12];
2031057Sbill 
20439333Smckusick 	if (mntopts)
20539333Smckusick 		getstdopts(mntopts, &flags);
20639316Smckusick 	if (options)
20739316Smckusick 		getstdopts(options, &flags);
20839333Smckusick 	if (type)
20939333Smckusick 		getstdopts(type, &flags);
21039316Smckusick 	switch (mnttype) {
21152097Sbostic 	case MOUNT_LFS:
21239316Smckusick 	case MOUNT_UFS:
21339333Smckusick 		if (mntopts)
21439333Smckusick 			getufsopts(mntopts, &flags);
21539316Smckusick 		if (options)
21639316Smckusick 			getufsopts(options, &flags);
21739316Smckusick 		args.fspec = spec;
21840369Smckusick 		args.exroot = DEFAULT_ROOTUID;
21941403Smckusick 		if (flags & MNT_RDONLY)
22041403Smckusick 			args.exflags = MNT_EXRDONLY;
22140496Smckusick 		else
22240496Smckusick 			args.exflags = 0;
22339316Smckusick 		argp = (caddr_t)&args;
22439316Smckusick 		break;
22538632Smckusick 
22652110Smckusick 	case MOUNT_MFS:
22739316Smckusick 	case MOUNT_NFS:
22839322Smckusick 	default:
22939322Smckusick 		argv[0] = mntname;
23039329Smckusick 		argc = 1;
23139322Smckusick 		if (flags) {
23239322Smckusick 			argv[argc++] = "-F";
23339322Smckusick 			sprintf(flagval, "%d", flags);
23439322Smckusick 			argv[argc++] = flagval;
23539322Smckusick 		}
23639333Smckusick 		if (mntopts)
23739333Smckusick 			argc += getexecopts(mntopts, &argv[argc]);
23839329Smckusick 		if (options)
23939329Smckusick 			argc += getexecopts(options, &argv[argc]);
24039316Smckusick 		argv[argc++] = spec;
24139316Smckusick 		argv[argc++] = name;
24239521Smckusick 		argv[argc++] = NULL;
24339603Smckusick 		sprintf(execname, "%s/mount_%s", _PATH_EXECDIR, mntname);
24439316Smckusick 		if (verbose) {
24542253Sbostic 			(void)printf("exec: %s", execname);
24642253Sbostic 			for (i = 1; i < argc - 1; i++)
24742253Sbostic 				(void)printf(" %s", argv[i]);
24842253Sbostic 			(void)printf("\n");
24939316Smckusick 		}
25039316Smckusick 		if (fake)
25139316Smckusick 			break;
25242253Sbostic 		if (pid = vfork()) {
25342253Sbostic 			if (pid == -1) {
25439322Smckusick 				perror("mount: vfork starting file system");
25539316Smckusick 				return (1);
25639131Smckusick 			}
25746708Sbostic 			if (waitpid(pid, (int *)&status, 0) != -1 &&
25839316Smckusick 			    WIFEXITED(status) &&
25939316Smckusick 			    WEXITSTATUS(status) != 0)
26039316Smckusick 				return (WEXITSTATUS(status));
26139322Smckusick 			spec = mntname;
26239316Smckusick 			goto out;
26339316Smckusick 		}
26439322Smckusick 		execve(execname, argv, envp);
26545689Smckusick 		(void) fprintf(stderr, "mount: cannot exec %s for %s: ",
26639603Smckusick 			execname, name);
26742253Sbostic 		perror((char *)NULL);
26839316Smckusick 		exit (1);
26939316Smckusick 		/* NOTREACHED */
27038632Smckusick 
27139316Smckusick 	}
27239316Smckusick 	if (!fake && mount(mnttype, name, flags, argp)) {
27345689Smckusick 		(void) fprintf(stderr, "%s on %s: ", spec, name);
27439316Smckusick 		switch (errno) {
27539316Smckusick 		case EMFILE:
27645689Smckusick 			(void) fprintf(stderr, "Mount table full\n");
27739316Smckusick 			break;
27839316Smckusick 		case EINVAL:
27941403Smckusick 			if (flags & MNT_UPDATE)
28045689Smckusick 				(void) fprintf(stderr, "Specified device %s\n",
28145689Smckusick 					"does not match mounted device");
28245569Skarels 			else if (mnttype == MOUNT_UFS)
28345689Smckusick 				(void) fprintf(stderr, "Bogus super block\n");
28439333Smckusick 			else
28545569Skarels 				perror((char *)NULL);
28639316Smckusick 			break;
28739316Smckusick 		default:
28839316Smckusick 			perror((char *)NULL);
28939316Smckusick 			break;
2904460Sroot 		}
29139316Smckusick 		return(1);
2924460Sroot 	}
29335339Sbostic 
29439131Smckusick out:
29512808Ssam 	if (verbose)
29639316Smckusick 		prmount(spec, name, flags);
29735339Sbostic 
29842253Sbostic 	return(0);
2991057Sbill }
30035339Sbostic 
30146708Sbostic static void
30239316Smckusick prmount(spec, name, flags)
30339316Smckusick 	char *spec, *name;
30442253Sbostic 	register short flags;
30535339Sbostic {
30642253Sbostic 	register int first;
30738632Smckusick 
30842253Sbostic 	(void)printf("%s on %s", spec, name);
30942253Sbostic 	if (!(flags & MNT_VISFLAGMASK)) {
31042253Sbostic 		(void)printf("\n");
31142253Sbostic 		return;
31242253Sbostic 	}
31342253Sbostic 	first = 0;
31442253Sbostic #define	PR(msg)	(void)printf("%s%s", !first++ ? " (" : ", ", msg)
31541403Smckusick 	if (flags & MNT_RDONLY)
31642253Sbostic 		PR("read-only");
31741403Smckusick 	if (flags & MNT_NOEXEC)
31842253Sbostic 		PR("noexec");
31941403Smckusick 	if (flags & MNT_NOSUID)
32042253Sbostic 		PR("nosuid");
32141403Smckusick 	if (flags & MNT_NODEV)
32242253Sbostic 		PR("nodev");
32341403Smckusick 	if (flags & MNT_SYNCHRONOUS)
32442253Sbostic 		PR("synchronous");
32541403Smckusick 	if (flags & MNT_QUOTA)
32642253Sbostic 		PR("with quotas");
32741403Smckusick 	if (flags & MNT_LOCAL)
32842253Sbostic 		PR("local");
32941403Smckusick 	if (flags & MNT_EXPORTED)
33052110Smckusick 		PR("NFS exported");
33142253Sbostic 	(void)printf(")\n");
33235339Sbostic }
33335339Sbostic 
33439133Smckusick getmnttype(fstype)
33539133Smckusick 	char *fstype;
33639133Smckusick {
33739133Smckusick 
33839322Smckusick 	mntname = fstype;
33939133Smckusick 	if (!strcmp(fstype, "ufs"))
34039133Smckusick 		return (MOUNT_UFS);
34139133Smckusick 	if (!strcmp(fstype, "nfs"))
34239133Smckusick 		return (MOUNT_NFS);
34339133Smckusick 	if (!strcmp(fstype, "mfs"))
34439133Smckusick 		return (MOUNT_MFS);
34552097Sbostic 	if (!strcmp(fstype, "lfs"))
34652097Sbostic 		return (MOUNT_LFS);
34739133Smckusick 	return (0);
34839133Smckusick }
34939133Smckusick 
35038632Smckusick usage()
35135339Sbostic {
35240871Smckusick 
35345689Smckusick 	(void) fprintf(stderr,
35445689Smckusick 		"usage:\n  mount %s %s\n  mount %s\n  mount %s\n",
35552110Smckusick 		"[ -frwu ] [ -t ufs | external_type ]",
35640871Smckusick 		"[ -o options ] special node",
35752110Smckusick 		"[ -afrwu ] [ -t ufs | external_type ]",
35840871Smckusick 		"[ -frwu ] special | node");
35935339Sbostic 	exit(1);
36035339Sbostic }
36135339Sbostic 
36239316Smckusick getstdopts(options, flagp)
36339316Smckusick 	char *options;
36442253Sbostic 	int *flagp;
36539316Smckusick {
36639316Smckusick 	register char *opt;
36739316Smckusick 	int negative;
36842253Sbostic 	char optbuf[BUFSIZ];
36939316Smckusick 
37042253Sbostic 	(void)strcpy(optbuf, options);
37142253Sbostic 	for (opt = strtok(optbuf, ","); opt; opt = strtok((char *)NULL, ",")) {
37239316Smckusick 		if (opt[0] == 'n' && opt[1] == 'o') {
37339316Smckusick 			negative++;
37439316Smckusick 			opt += 2;
37539316Smckusick 		} else {
37639316Smckusick 			negative = 0;
37739316Smckusick 		}
37839333Smckusick 		if (!negative && !strcasecmp(opt, FSTAB_RO)) {
37941403Smckusick 			*flagp |= MNT_RDONLY;
38039333Smckusick 			continue;
38139333Smckusick 		}
38239333Smckusick 		if (!negative && !strcasecmp(opt, FSTAB_RW)) {
38341403Smckusick 			*flagp &= ~MNT_RDONLY;
38439333Smckusick 			continue;
38539333Smckusick 		}
38639316Smckusick 		if (!strcasecmp(opt, "exec")) {
38739316Smckusick 			if (negative)
38841403Smckusick 				*flagp |= MNT_NOEXEC;
38939333Smckusick 			else
39041403Smckusick 				*flagp &= ~MNT_NOEXEC;
39139316Smckusick 			continue;
39239316Smckusick 		}
39339316Smckusick 		if (!strcasecmp(opt, "suid")) {
39439316Smckusick 			if (negative)
39541403Smckusick 				*flagp |= MNT_NOSUID;
39639333Smckusick 			else
39741403Smckusick 				*flagp &= ~MNT_NOSUID;
39839316Smckusick 			continue;
39939316Smckusick 		}
40039316Smckusick 		if (!strcasecmp(opt, "dev")) {
40139316Smckusick 			if (negative)
40241403Smckusick 				*flagp |= MNT_NODEV;
40339333Smckusick 			else
40441403Smckusick 				*flagp &= ~MNT_NODEV;
40539316Smckusick 			continue;
40639316Smckusick 		}
40739316Smckusick 		if (!strcasecmp(opt, "synchronous")) {
40839316Smckusick 			if (!negative)
40941403Smckusick 				*flagp |= MNT_SYNCHRONOUS;
41039333Smckusick 			else
41141403Smckusick 				*flagp &= ~MNT_SYNCHRONOUS;
41239316Smckusick 			continue;
41339316Smckusick 		}
41439316Smckusick 	}
41539316Smckusick }
41639316Smckusick 
41742253Sbostic /* ARGSUSED */
41839131Smckusick getufsopts(options, flagp)
41939131Smckusick 	char *options;
42042253Sbostic 	int *flagp;
42139131Smckusick {
42239131Smckusick 	return;
42339131Smckusick }
42439131Smckusick 
42539329Smckusick getexecopts(options, argv)
42639131Smckusick 	char *options;
42739131Smckusick 	char **argv;
42839131Smckusick {
42939131Smckusick 	register int argc = 0;
43039131Smckusick 	register char *opt;
43139131Smckusick 
43242253Sbostic 	for (opt = strtok(options, ","); opt; opt = strtok((char *)NULL, ",")) {
43339131Smckusick 		if (opt[0] != '-')
43439131Smckusick 			continue;
43539131Smckusick 		argv[argc++] = opt;
43639131Smckusick 		if (opt[2] == '\0' || opt[2] != '=')
43739131Smckusick 			continue;
43839131Smckusick 		opt[2] = '\0';
43939131Smckusick 		argv[argc++] = &opt[3];
44039131Smckusick 	}
44139131Smckusick 	return (argc);
44239131Smckusick }
44339131Smckusick 
44439465Smckusick struct statfs *
44539465Smckusick getmntpt(name)
44639465Smckusick 	char *name;
44739465Smckusick {
44839465Smckusick 	long mntsize;
44939465Smckusick 	register long i;
45039465Smckusick 	struct statfs *mntbuf;
45139465Smckusick 
45240337Smckusick 	mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
45339465Smckusick 	for (i = 0; i < mntsize; i++) {
45439465Smckusick 		if (!strcmp(mntbuf[i].f_mntfromname, name) ||
45539465Smckusick 		    !strcmp(mntbuf[i].f_mntonname, name))
45639465Smckusick 			return (&mntbuf[i]);
45739465Smckusick 	}
45839465Smckusick 	return ((struct statfs *)0);
45939465Smckusick }
46039465Smckusick 
46140051Smckusick static int skipvfs;
46240051Smckusick 
46340051Smckusick badvfstype(vfstype, vfslist)
46442253Sbostic 	short vfstype;
46540051Smckusick 	char **vfslist;
46640051Smckusick {
46740051Smckusick 
46840051Smckusick 	if (vfslist == 0)
46940051Smckusick 		return(0);
47040051Smckusick 	while (*vfslist) {
47140844Smckusick 		if (vfstype == getmnttype(*vfslist))
47240051Smckusick 			return(skipvfs);
47340051Smckusick 		vfslist++;
47440051Smckusick 	}
47540051Smckusick 	return (!skipvfs);
47640051Smckusick }
47740051Smckusick 
47840844Smckusick badvfsname(vfsname, vfslist)
47940844Smckusick 	char *vfsname;
48040844Smckusick 	char **vfslist;
48140844Smckusick {
48240844Smckusick 
48340844Smckusick 	if (vfslist == 0)
48440844Smckusick 		return(0);
48540844Smckusick 	while (*vfslist) {
48640844Smckusick 		if (strcmp(vfsname, *vfslist) == 0)
48740844Smckusick 			return(skipvfs);
48840844Smckusick 		vfslist++;
48940844Smckusick 	}
49040844Smckusick 	return (!skipvfs);
49140844Smckusick }
49240844Smckusick 
49340051Smckusick char **
49440051Smckusick makevfslist(fslist)
49540051Smckusick 	char *fslist;
49640051Smckusick {
49740051Smckusick 	register char **av, *nextcp;
49840051Smckusick 	register int i;
49940051Smckusick 
50040051Smckusick 	if (fslist == NULL)
50140051Smckusick 		return (NULL);
50240051Smckusick 	if (fslist[0] == 'n' && fslist[1] == 'o') {
50340051Smckusick 		fslist += 2;
50440051Smckusick 		skipvfs = 1;
50540051Smckusick 	}
50640051Smckusick 	for (i = 0, nextcp = fslist; *nextcp; nextcp++)
50740051Smckusick 		if (*nextcp == ',')
50840051Smckusick 			i++;
50942253Sbostic 	av = (char **)malloc((size_t)(i+2) * sizeof(char *));
51040051Smckusick 	if (av == NULL)
51140051Smckusick 		return (NULL);
51240051Smckusick 	nextcp = fslist;
51340051Smckusick 	i = 0;
51440051Smckusick 	av[i++] = nextcp;
51540051Smckusick 	while (nextcp = index(nextcp, ',')) {
51640051Smckusick 		*nextcp++ = '\0';
51740051Smckusick 		av[i++] = nextcp;
51840051Smckusick 	}
51940051Smckusick 	av[i++] = 0;
52040051Smckusick 	return (av);
52140051Smckusick }
522