From 7ce08208381fa68118da0e1ae954368fc611f1d9 Mon Sep 17 00:00:00 2001 From: bde Date: Wed, 5 Mar 1997 17:51:21 +0000 Subject: Attempt to import Lite2's mount. --- sbin/mount/Makefile | 4 +- sbin/mount/getmntopts.3 | 32 ++++++--- sbin/mount/getmntopts.c | 26 +++++-- sbin/mount/mntopts.h | 38 ++++++----- sbin/mount/mount.8 | 15 ++++- sbin/mount/mount.c | 176 +++++++++++++++++++++--------------------------- sbin/mount/mount_ufs.c | 9 ++- sbin/mount/vfslist.c | 92 +++++++++++++++++++++++++ 8 files changed, 255 insertions(+), 137 deletions(-) create mode 100644 sbin/mount/vfslist.c (limited to 'sbin/mount') diff --git a/sbin/mount/Makefile b/sbin/mount/Makefile index b3efd4e..56aea1c 100644 --- a/sbin/mount/Makefile +++ b/sbin/mount/Makefile @@ -1,7 +1,7 @@ -# @(#)Makefile 8.5 (Berkeley) 3/27/94 +# @(#)Makefile 8.6 (Berkeley) 5/8/95 PROG= mount -SRCS= mount.c mount_ufs.c getmntopts.c +SRCS= mount.c mount_ufs.c getmntopts.c vfslist.c MAN8= mount.0 # We do NOT install the getmntopts.3 man page. diff --git a/sbin/mount/getmntopts.3 b/sbin/mount/getmntopts.3 index 642c57a..8424104 100644 --- a/sbin/mount/getmntopts.3 +++ b/sbin/mount/getmntopts.3 @@ -29,9 +29,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)getmntopts.3 8.1 (Berkeley) 3/27/94 +.\" @(#)getmntopts.3 8.3 (Berkeley) 3/30/95 .\" -.Dd March 27, 1994 +.Dd March 30, 1995 .Dt GETMNTOPTS 3 .Os BSD 4.4 .Sh NAME @@ -40,7 +40,7 @@ .Sh SYNOPSIS .Fd #include .Ft void -.Fn getmntopts "char *options" "struct mntopt *mopts" "int *flagp" +.Fn getmntopts "char *options" "struct mntopt *mopts" "int *flagp" "int *altflagp" .Sh DESCRIPTION The .Nm getmntopts @@ -54,10 +54,15 @@ is broken down into a sequence of comma separated tokens. Each token is looked up in the table described by .Dv mopts and the bits in -the word referenced by +the word referenced by either .Dv flagp +or +.Dv altflagp +(depending on the +.Dv m_altloc +field of the option's table entry) are updated. -The flag word is not initialized by +The flag words are not initialized by .Nm getmntopt . The table, .Dv mopts , @@ -67,6 +72,7 @@ struct mntopt { char *m_option; /* option name */ int m_inverse; /* is this a negative option, eg "dev" */ int m_flag; /* bit to set, eg MNT_RDONLY */ + int m_altloc; /* non-zero to use altflagp rather than flagp */ }; .Ed .Pp @@ -100,6 +106,11 @@ by the letters The .Dv m_inverse flag causes these two operations to be reversed. +.It Fa m_altloc +the bit should be set or cleared in +.Dv altflagp +rather than +.Dv flagp . .El .Pp Each of the user visible @@ -143,16 +154,21 @@ struct mntopt mopts[] = { }; ... - mntflags = 0; + mntflags = mntaltflags = 0; ... - getmntopts(options, mopts, &mntflags) + getmntopts(options, mopts, &mntflags, &mntaltflags); ... .Ed .Sh DIAGNOSTICS -The +If the external integer variable +.Dv getmnt_silent +is non-zero then the .Nm getmntopts function displays an error message and exits if an unrecognized option is encountered. +By default +.Dv getmnt_silent +is zero. .Sh SEE ALSO .Xr err 3 , .Xr mount 8 diff --git a/sbin/mount/getmntopts.c b/sbin/mount/getmntopts.c index 2c84ae5..8f972ca 100644 --- a/sbin/mount/getmntopts.c +++ b/sbin/mount/getmntopts.c @@ -32,7 +32,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)getmntopts.c 8.1 (Berkeley) 3/27/94"; +static char sccsid[] = "@(#)getmntopts.c 8.3 (Berkeley) 3/29/95"; #endif /* not lint */ #include @@ -46,15 +46,19 @@ static char sccsid[] = "@(#)getmntopts.c 8.1 (Berkeley) 3/27/94"; #include "mntopts.h" +int getmnt_silent = 0; + void -getmntopts(options, m0, flagp) +getmntopts(options, m0, flagp, altflagp) const char *options; const struct mntopt *m0; int *flagp; + int *altflagp; { const struct mntopt *m; int negative; - char *opt, *optbuf; + char *opt, *optbuf, *p; + int *thisflagp; /* Copy option string, since it is about to be torn asunder... */ if ((optbuf = strdup(options)) == NULL) @@ -68,6 +72,14 @@ getmntopts(options, m0, flagp) } else negative = 0; + /* + * for options with assignments in them (ie. quotas) + * ignore the assignment as it's handled elsewhere + */ + p = strchr(opt, '='); + if (p) + *p = '\0'; + /* Scan option table. */ for (m = m0; m->m_option != NULL; ++m) if (strcasecmp(opt, m->m_option) == 0) @@ -75,12 +87,14 @@ getmntopts(options, m0, flagp) /* Save flag, or fail if option is not recognised. */ if (m->m_option) { + thisflagp = m->m_altloc ? altflagp : flagp; if (negative == m->m_inverse) - *flagp |= m->m_flag; + *thisflagp |= m->m_flag; else - *flagp &= ~m->m_flag; - } else + *thisflagp &= ~m->m_flag; + } else if (!getmnt_silent) { errx(1, "-o %s: option not supported", opt); + } } free(optbuf); diff --git a/sbin/mount/mntopts.h b/sbin/mount/mntopts.h index a89f63d..621b0e9 100644 --- a/sbin/mount/mntopts.h +++ b/sbin/mount/mntopts.h @@ -30,38 +30,45 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)mntopts.h 8.3 (Berkeley) 3/27/94 + * @(#)mntopts.h 8.7 (Berkeley) 3/29/95 */ struct mntopt { const char *m_option; /* option name */ int m_inverse; /* if a negative option, eg "dev" */ int m_flag; /* bit to set, eg. MNT_RDONLY */ + int m_altloc; /* 1 => set bit in altflags */ }; /* User-visible MNT_ flags. */ -#define MOPT_ASYNC { "async", 0, MNT_ASYNC } -#define MOPT_NODEV { "dev", 1, MNT_NODEV } -#define MOPT_NOEXEC { "exec", 1, MNT_NOEXEC } -#define MOPT_NOSUID { "suid", 1, MNT_NOSUID } -#define MOPT_RDONLY { "rdonly", 0, MNT_RDONLY } -#define MOPT_SYNC { "sync", 0, MNT_SYNCHRONOUS } -#define MOPT_UNION { "union", 0, MNT_UNION } +#define MOPT_ASYNC { "async", 0, MNT_ASYNC, 0 } +#define MOPT_NODEV { "dev", 1, MNT_NODEV, 0 } +#define MOPT_NOEXEC { "exec", 1, MNT_NOEXEC, 0 } +#define MOPT_NOSUID { "suid", 1, MNT_NOSUID, 0 } +#define MOPT_RDONLY { "rdonly", 0, MNT_RDONLY, 0 } +#define MOPT_SYNC { "sync", 0, MNT_SYNCHRONOUS, 0 } +#define MOPT_UNION { "union", 0, MNT_UNION, 0 } +#define MOPT_USERQUOTA { "userquota", 0, 0, 0 } +#define MOPT_GROUPQUOTA { "groupquota", 0, 0, 0 } /* Control flags. */ -#define MOPT_FORCE { "force", 1, MNT_FORCE } -#define MOPT_UPDATE { "update", 0, MNT_UPDATE } +#define MOPT_FORCE { "force", 0, MNT_FORCE, 0 } +#define MOPT_UPDATE { "update", 0, MNT_UPDATE, 0 } +#define MOPT_RO { "ro", 0, MNT_RDONLY, 0 } +#define MOPT_RW { "rw", 1, MNT_RDONLY, 0 } -/* Support for old-style "ro", "rw" flags. */ -#define MOPT_RO { "ro", 0, MNT_RDONLY } -#define MOPT_RW { "rw", 1, MNT_RDONLY } +/* This is parsed by mount(8), but is ignored by specific mount_*(8)s. */ +#define MOPT_AUTO { "auto", 0, 0, 0 } #define MOPT_FSTAB_COMPAT \ MOPT_RO, \ - MOPT_RW + MOPT_RW, \ + MOPT_AUTO /* Standard options which all mounts can understand. */ #define MOPT_STDOPTS \ + MOPT_USERQUOTA, \ + MOPT_GROUPQUOTA, \ MOPT_FSTAB_COMPAT, \ MOPT_NODEV, \ MOPT_NOEXEC, \ @@ -69,4 +76,5 @@ struct mntopt { MOPT_RDONLY, \ MOPT_UNION -void getmntopts __P((const char *, const struct mntopt *, int *)); +void getmntopts __P((const char *, const struct mntopt *, int *, int *)); +extern int getmnt_silent; diff --git a/sbin/mount/mount.8 b/sbin/mount/mount.8 index e2c53c8..5767c2f 100644 --- a/sbin/mount/mount.8 +++ b/sbin/mount/mount.8 @@ -29,9 +29,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)mount.8 8.7 (Berkeley) 3/27/94 +.\" @(#)mount.8 8.8 (Berkeley) 6/16/94 .\" -.Dd March 27, 1994 +.Dd June 16, 1994 .Dt MOUNT 8 .Os BSD 4 .Sh NAME @@ -74,6 +74,13 @@ this list is printed. .Pp The options are as follows: .Bl -tag -width indent +.It Fl a +All the filesystems described in +.Xr fstab 5 +are mounted. +Exceptions are those marked as ``noauto'' or are excluded by the +.Fl t +flag (see below). .It Fl d Causes everything to be done except for the actual system call. This option is useful in conjunction with the @@ -105,6 +112,10 @@ The same as .Fl f ; forces the revocation of write access when trying to downgrade a filesystem mount status from read-write to read-only. +.It noauto +This filesystem should be skipped when mount is run with the +.Fl a +flag. .It nodev Do not interpret character or block special devices on the file system. This option is useful for a server that has file systems containing diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c index f0ff782..7d6252b 100644 --- a/sbin/mount/mount.c +++ b/sbin/mount/mount.c @@ -38,7 +38,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)mount.c 8.19 (Berkeley) 4/19/94"; +static char sccsid[] = "@(#)mount.c 8.25 (Berkeley) 5/8/95"; #endif /* not lint */ #include @@ -48,6 +48,7 @@ static char sccsid[] = "@(#)mount.c 8.19 (Berkeley) 4/19/94"; #include #include #include +#include #include #include #include @@ -56,19 +57,19 @@ static char sccsid[] = "@(#)mount.c 8.19 (Berkeley) 4/19/94"; #include "pathnames.h" -int debug, verbose, skipvfs; +int debug, verbose; -int badvfsname __P((const char *, const char **)); -int badvfstype __P((int, const char **)); +int checkvfsname __P((const char *, const char **)); char *catopt __P((char *, const char *)); struct statfs *getmntpt __P((const char *)); +int hasopt __P((const char *, const char *)); const char **makevfslist __P((char *)); void mangle __P((char *, int *, const char **)); int mountfs __P((const char *, const char *, const char *, int, const char *, const char *)); -void prmount __P((const char *, const char *, int)); +void prmount __P((struct statfs *)); void usage __P((void)); /* From mount_ufs.c. */ @@ -89,7 +90,6 @@ static struct opt { { MNT_RDONLY, "read-only" }, { MNT_SYNCHRONOUS, "synchronous" }, { MNT_UNION, "union" }, - { MNT_USER, "user mount" }, { NULL } }; @@ -98,7 +98,7 @@ main(argc, argv) int argc; char * const argv[]; { - const char *mntonname, **vfslist, *vfstype; + const char *mntfromname, **vfslist, *vfstype; struct fstab *fs; struct statfs *mntbuf; FILE *mountdfp; @@ -162,7 +162,9 @@ main(argc, argv) while ((fs = getfsent()) != NULL) { if (BADTYPE(fs->fs_type)) continue; - if (badvfsname(fs->fs_vfstype, vfslist)) + if (checkvfsname(fs->fs_vfstype, vfslist)) + continue; + if (hasopt(fs->fs_mntops, "noauto")) continue; if (mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file, init_flags, options, @@ -173,10 +175,9 @@ main(argc, argv) if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) err(1, "getmntinfo"); for (i = 0; i < mntsize; i++) { - if (badvfstype(mntbuf[i].f_type, vfslist)) + if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) continue; - prmount(mntbuf[i].f_mntfromname, - mntbuf[i].f_mntonname, mntbuf[i].f_flags); + prmount(&mntbuf[i]); } } exit(rval); @@ -189,25 +190,23 @@ main(argc, argv) errx(1, "unknown special file or file system %s.", *argv); - if ((fs = getfsfile(mntbuf->f_mntonname)) == NULL) - errx(1, "can't find fstab entry for %s.", - *argv); - /* If it's an update, ignore the fstab file options. */ - fs->fs_mntops = NULL; - mntonname = mntbuf->f_mntonname; - } else { - if ((fs = getfsfile(*argv)) == NULL && - (fs = getfsspec(*argv)) == NULL) - errx(1, - "%s: unknown special file or file system.", - *argv); - if (BADTYPE(fs->fs_type)) - errx(1, "%s has unknown file system type.", - *argv); - mntonname = fs->fs_file; + if ((fs = getfsfile(mntbuf->f_mntonname)) != NULL) + mntfromname = fs->fs_spec; + else + mntfromname = mntbuf->f_mntfromname; + rval = mountfs(mntbuf->f_fstypename, mntfromname, + mntbuf->f_mntonname, init_flags, options, 0); + break; } - rval = mountfs(fs->fs_vfstype, fs->fs_spec, - mntonname, init_flags, options, fs->fs_mntops); + if ((fs = getfsfile(*argv)) == NULL && + (fs = getfsspec(*argv)) == NULL) + errx(1, "%s: unknown special file or file system.", + *argv); + if (BADTYPE(fs->fs_type)) + errx(1, "%s has unknown file system type.", + *argv); + rval = mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file, + init_flags, options, fs->fs_mntops); break; case 2: /* @@ -241,6 +240,31 @@ main(argc, argv) } int +hasopt(mntopts, option) + const char *mntopts, *option; +{ + int negative, found; + char *opt, *optbuf; + + if (option[0] == 'n' && option[1] == 'o') { + negative = 1; + option += 2; + } else + negative = 0; + optbuf = strdup(mntopts); + found = 0; + for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) { + if (opt[0] == 'n' && opt[1] == 'o') { + if (!strcasecmp(opt + 2, option)) + found = negative; + } else if (!strcasecmp(opt, option)) + found = !negative; + } + free(optbuf); + return (found); +} + +int mountfs(vfstype, spec, name, flags, options, mntopts) const char *vfstype, *spec, *name, *options, *mntopts; int flags; @@ -258,18 +282,21 @@ mountfs(vfstype, spec, name, flags, options, mntopts) char *optbuf, execname[MAXPATHLEN + 1], mntpath[MAXPATHLEN]; if (realpath(name, mntpath) == NULL) { - warn("%s", mntpath); + warn("realpath %s", mntpath); return (1); } name = mntpath; + if (mntopts == NULL) + mntopts = ""; if (options == NULL) { - if (mntopts == NULL || *mntopts == '\0') + if (*mntopts == '\0') { options = "rw"; - else + } else { options = mntopts; - mntopts = ""; + mntopts = ""; + } } optbuf = catopt(strdup(mntopts), options); @@ -344,10 +371,10 @@ mountfs(vfstype, spec, name, flags, options, mntopts) if (verbose) { if (statfs(name, &sf) < 0) { - warn("%s", name); + warn("statfs %s", name); return (1); } - prmount(sf.f_mntfromname, sf.f_mntonname, sf.f_flags); + prmount(&sf); } break; } @@ -356,21 +383,29 @@ mountfs(vfstype, spec, name, flags, options, mntopts) } void -prmount(spec, name, flags) - const char *spec, *name; - int flags; +prmount(sfp) + struct statfs *sfp; { + int flags; struct opt *o; + struct passwd *pw; int f; - (void)printf("%s on %s", spec, name); + (void)printf("%s on %s", sfp->f_mntfromname, sfp->f_mntonname); - flags &= MNT_VISFLAGMASK; + flags = sfp->f_flags & MNT_VISFLAGMASK; for (f = 0, o = optnames; flags && o->o_opt; o++) if (flags & o->o_opt) { (void)printf("%s%s", !f++ ? " (" : ", ", o->o_name); flags &= ~o->o_opt; } + if (sfp->f_owner) { + (void)printf("%smounted by ", !f++ ? " (" : ", "); + if ((pw = getpwuid(sfp->f_owner)) != NULL) + (void)printf("%s", pw->pw_name); + else + (void)printf("%d", sfp->f_owner); + } (void)printf(f ? ")\n" : "\n"); } @@ -389,67 +424,6 @@ getmntpt(name) return (NULL); } -int -badvfsname(vfsname, vfslist) - const char *vfsname; - const char **vfslist; -{ - - if (vfslist == NULL) - return (0); - while (*vfslist != NULL) { - if (strcmp(vfsname, *vfslist) == 0) - return (skipvfs); - ++vfslist; - } - return (!skipvfs); -} - -int -badvfstype(vfstype, vfslist) - int vfstype; - const char **vfslist; -{ -static const char *vfsnames[] = INITMOUNTNAMES; - - if ((vfstype < 0) || (vfstype > MOUNT_MAXTYPE)) - return (0); - - return (badvfsname(vfsnames[vfstype], vfslist)); -} - -const char ** -makevfslist(fslist) - char *fslist; -{ - const char **av; - int i; - char *nextcp; - - if (fslist == NULL) - return (NULL); - if (fslist[0] == 'n' && fslist[1] == 'o') { - fslist += 2; - skipvfs = 1; - } - for (i = 0, nextcp = fslist; *nextcp; nextcp++) - if (*nextcp == ',') - i++; - if ((av = malloc((size_t)(i + 2) * sizeof(char *))) == NULL) { - warn(NULL); - return (NULL); - } - nextcp = fslist; - i = 0; - av[i++] = nextcp; - while ((nextcp = strchr(nextcp, ',')) != NULL) { - *nextcp++ = '\0'; - av[i++] = nextcp; - } - av[i++] = NULL; - return (av); -} - char * catopt(s0, s1) char *s0; diff --git a/sbin/mount/mount_ufs.c b/sbin/mount/mount_ufs.c index babb760..e14a26a 100644 --- a/sbin/mount/mount_ufs.c +++ b/sbin/mount/mount_ufs.c @@ -38,7 +38,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)mount_ufs.c 8.2 (Berkeley) 3/27/94"; +static char sccsid[] = "@(#)mount_ufs.c 8.4 (Berkeley) 4/26/95"; #endif /* not lint */ #include @@ -51,6 +51,8 @@ static char sccsid[] = "@(#)mount_ufs.c 8.2 (Berkeley) 3/27/94"; #include #include +#include + #include "mntopts.h" void ufs_usage __P((void)); @@ -60,6 +62,7 @@ static struct mntopt mopts[] = { MOPT_ASYNC, MOPT_SYNC, MOPT_UPDATE, + MOPT_FORCE, { NULL } }; @@ -78,7 +81,7 @@ mount_ufs(argc, argv) while ((ch = getopt(argc, argv, "o:")) != EOF) switch (ch) { case 'o': - getmntopts(optarg, mopts, &mntflags); + getmntopts(optarg, mopts, &mntflags, 0); break; case '?': default: @@ -100,7 +103,7 @@ mount_ufs(argc, argv) else args.export.ex_flags = 0; - if (mount(MOUNT_UFS, fs_name, mntflags, &args) < 0) { + if (mount("ufs", fs_name, mntflags, &args) < 0) { (void)fprintf(stderr, "%s on %s: ", args.fspec, fs_name); switch (errno) { case EMFILE: diff --git a/sbin/mount/vfslist.c b/sbin/mount/vfslist.c new file mode 100644 index 0000000..1a00a23 --- /dev/null +++ b/sbin/mount/vfslist.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 1995 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)vfslist.c 8.1 (Berkeley) 5/8/95"; +#endif /* not lint */ + +#include +#include +#include + +int checkvfsname __P((const char *, const char **)); +const char **makevfslist __P((char *)); +static int skipvfs; + +int +checkvfsname(vfsname, vfslist) + const char *vfsname; + const char **vfslist; +{ + + if (vfslist == NULL) + return (0); + while (*vfslist != NULL) { + if (strcmp(vfsname, *vfslist) == 0) + return (skipvfs); + ++vfslist; + } + return (!skipvfs); +} + +const char ** +makevfslist(fslist) + char *fslist; +{ + const char **av; + int i; + char *nextcp; + + if (fslist == NULL) + return (NULL); + if (fslist[0] == 'n' && fslist[1] == 'o') { + fslist += 2; + skipvfs = 1; + } + for (i = 0, nextcp = fslist; *nextcp; nextcp++) + if (*nextcp == ',') + i++; + if ((av = malloc((size_t)(i + 2) * sizeof(char *))) == NULL) { + warn(NULL); + return (NULL); + } + nextcp = fslist; + i = 0; + av[i++] = nextcp; + while ((nextcp = strchr(nextcp, ',')) != NULL) { + *nextcp++ = '\0'; + av[i++] = nextcp; + } + av[i++] = NULL; + return (av); +} -- cgit v1.1