[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: diff: getmntopts()



On Wed, 9 Jun 2004, Otto Moerbeek wrote:

An updated diff, fixing the handling of inverse nfs flags (like noconn)  
and a parsing error when the -o string ends with a ','.

Please be aware than if you run cvs up after applying the diff (don't
forget the -E) the two removed files mount_nfs/getmntopts.c and
mount_nfs/mntopts.h will reappear. This will break things. A slution is to 
cvs remove those two files.

I received valuable suggestions from Zvezdan Petkovic, thanks a lot.

	-Otto

> Hi,
> 
> This diff cleans up getmntopts(), a function used by the various
> mount helpers to parse their -o argument list.  Currenly, there are
> two versions of this function, one used by mount_nfs and mount_procfs,
> and another used by the other helpers.
> 
> This diff unifies the two versions and fixes various bugs, like a
> segfault when doing things like specyfying an option that needs a
> value without one:
> 
> 	$ mount -t nfs -oport a b
> 	mount: /home/otto/b: Segmentation fault
> 
> 
> Applying the diff:
> 
> 	cd /usr/src/sbin
> 	patch -p0 -E < getmntopts.diff
> 	make cleandir
> 	make depend
> 	make
> 	make install
> 
> Testing the diff:
> 
> Check if you filesystems get mounted with the desired options (both
> when mounting by hand and when using fstab).  Also test invalid
> options, like the one above. Use your imagination!
> 
> Also check
> <http://cvs.openbsd.org/cgi-bin/query-pr-wrapper?full=yes&numbers=3642>
> 
> This is joint work with Todd Miller.
> 
> Thanks in advance for testing,
> 

Index: mount/getmntopts.c
===================================================================
RCS file: /cvs/src/sbin/mount/getmntopts.c,v
retrieving revision 1.7
diff -u -p -r1.7 getmntopts.c
--- mount/getmntopts.c	18 May 2004 11:07:53 -0000	1.7
+++ mount/getmntopts.c	10 Jun 2004 21:36:33 -0000
@@ -49,47 +49,85 @@ static char rcsid[] = "$OpenBSD: getmnto
 
 #include "mntopts.h"
 
-void
-getmntopts(const char *options, const struct mntopt *m0, int *flagp)
+int
+getmntopts(const char *optionp, const struct mntopt *m0, int *flagp)
 {
-	const struct mntopt *m;
-	int negative;
-	char *opt, *optbuf, *p;
+	char *p, *q;
+	union mntval val;
+	int ret = 0;
 
-	/* Copy option string, since it is about to be torn asunder... */
-	if ((optbuf = strdup(options)) == NULL)
+	p = q = strdup(optionp);
+	if (p == NULL)
 		err(1, NULL);
-
-	for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
-		/* Check for "no" prefix. */
-		if (opt[0] == 'n' && opt[1] == 'o') {
-			negative = 1;
-			opt += 2;
-		} else
-			negative = 0;
-
-		/*
-		 * for options with assignments in them (ie. quotas)
-		 * ignore the assignment as it's handled elsewhere
-		 */
-		p = strchr(opt, '=');
-		if (p != NULL)
-			 *p = '\0';
-
-		/* Scan option table. */
-		for (m = m0; m->m_option != NULL; ++m)
-			if (strcasecmp(opt, m->m_option) == 0)
-				break;
-
-		/* Save flag, or fail if option is not recognised. */
-		if (m->m_option) {
-			if (negative == m->m_inverse)
+	while (p != NULL) {
+		ret |= getmntopt(&p, &val, m0, flagp);
+	}
+	free(q);
+	return (ret);
+}
+
+int
+getmntopt(char **optionp, union mntval *valuep, const struct mntopt *m0,
+    int *flagp)
+{
+	const struct mntopt *m;
+	char *opt, *value, *endp;
+	long l;
+	int inverse, negative, needval, ret = 0;
+
+	/* Pull out the next option. */
+	do {
+		if (*optionp == NULL)
+			return (0);
+		opt = strsep(optionp, ",");
+	} while (opt == NULL || *opt == '\0');
+
+	/* Check for "no" prefix. */
+	if (opt[0] == 'n' && opt[1] == 'o') {
+		negative = 1;
+		opt += 2;
+	} else
+		negative = 0;
+
+	/* Stash the value for options with assignments in them. */
+	if ((value = strchr(opt, '=')) != NULL)
+		*value++ = '\0';
+
+	/* Scan option table. */
+	for (m = m0; m->m_option != NULL; ++m)
+		if (strcasecmp(opt, m->m_option) == 0)
+			break;
+
+	/* Save flag, or fail if option is not recognised. */
+	if (m->m_option) {
+		needval = (m->m_oflags & (MFLAG_INTVAL|MFLAG_STRVAL)) != 0;
+		if (needval != (value != NULL))
+			errx(1, "-o %s: option %s a value", opt,
+			    needval ? "needs" : "does not need");
+		inverse = (m->m_oflags & MFLAG_INVERSE) ? 1 : 0;
+		if (m->m_oflags & MFLAG_SET) {
+			if (negative == inverse)
 				*flagp |= m->m_flag;
 			else
 				*flagp &= ~m->m_flag;
+		}
+		else if (negative == inverse)
+			ret = m->m_flag;
+	} else
+		errx(1, "-o %s: option not supported", opt);
+
+	/* Store the value for options with assignments in them. */
+	if (value != NULL) {
+		if (m->m_oflags & MFLAG_INTVAL) {
+			l = strtol(value, &endp, 10);
+			if (endp == value || l < 0 || l > INT_MAX ||
+			    (l == LONG_MAX && errno == ERANGE))
+				errx(1, "%s: illegal value '%s'",
+				    opt, value);
+			valuep->ival = (int)l;
 		} else
-			errx(1, "-o %s: option not supported", opt);
-	}
-
-	free(optbuf);
+			valuep->strval = value;
+	} else
+		memset(valuep, 0, sizeof(*valuep));
+	return (ret);
 }
Index: mount/mntopts.h
===================================================================
RCS file: /cvs/src/sbin/mount/mntopts.h,v
retrieving revision 1.12
diff -u -p -r1.12 mntopts.h
--- mount/mntopts.h	18 May 2004 11:07:53 -0000	1.12
+++ mount/mntopts.h	10 Jun 2004 20:59:04 -0000
@@ -32,37 +32,49 @@
  *	@(#)mntopts.h	8.3 (Berkeley) 3/27/94
  */
 
+#define MFLAG_INVERSE		0x01	/* if a negative option, eg "dev" */
+#define MFLAG_SET		0x02	/* 1 => set bit in mntflags,
+					   0 => return flag */
+#define MFLAG_STRVAL		0x04	/* option needs a string value */
+#define MFLAG_INTVAL		0x08	/* option needs an int value */
+
 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_oflags;
+};
+
+union mntval {
+	char *strval;
+	int ival;
 };
 
 /* User-visible MNT_ flags. */
-#define MOPT_ASYNC		{ "async",	0, MNT_ASYNC }
-#define MOPT_NOACCESSTIME	{ "accesstime",	1, MNT_NOATIME }
-#define MOPT_NOATIME		{ "atime",	1, MNT_NOATIME }
-#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_USERQUOTA		{ "userquota",	0, 0 }
-#define MOPT_GROUPQUOTA		{ "groupquota",	0, 0 }
-#define MOPT_SOFTDEP		{ "softdep",	0, MNT_SOFTDEP }
+#define MOPT_ASYNC	{ "async",	MNT_ASYNC, MFLAG_SET }
+#define MOPT_NOACCESSTIME	{ "accesstime", MNT_NOATIME,		\
+					MFLAG_INVERSE | MFLAG_SET }
+#define MOPT_NOATIME	{ "atime",      MNT_NOATIME, MFLAG_INVERSE | MFLAG_SET }
+#define MOPT_NODEV	{ "dev",	MNT_NODEV, MFLAG_INVERSE | MFLAG_SET }
+#define MOPT_NOEXEC	{ "exec",	MNT_NOEXEC, MFLAG_INVERSE | MFLAG_SET }
+#define MOPT_NOSUID	{ "suid",	MNT_NOSUID, MFLAG_INVERSE | MFLAG_SET }
+#define MOPT_RDONLY	{ "rdonly",	MNT_RDONLY, MFLAG_SET }
+#define MOPT_SYNC	{ "sync",	MNT_SYNCHRONOUS, MFLAG_SET }
+#define MOPT_UNION	{ "union",	MNT_UNION, MFLAG_SET }
+#define MOPT_USERQUOTA	{ "userquota",	0, MFLAG_SET }
+#define MOPT_GROUPQUOTA	{ "groupquota",	0, MFLAG_SET }
+#define MOPT_SOFTDEP	{ "softdep",	MNT_SOFTDEP, MFLAG_SET }
 
 /* Control flags. */
-#define MOPT_FORCE		{ "force",	0, MNT_FORCE }
-#define MOPT_UPDATE		{ "update",	0, MNT_UPDATE }
-#define MOPT_RELOAD		{ "reload",	0, MNT_RELOAD }
+#define MOPT_FORCE	{ "force",	MNT_FORCE, MFLAG_SET }
+#define MOPT_UPDATE	{ "update",	MNT_UPDATE, MFLAG_SET }
+#define MOPT_RELOAD	{ "reload",	MNT_RELOAD, MFLAG_SET }
 
 /* Support for old-style "ro", "rw" flags. */
-#define MOPT_RO			{ "ro",		0, MNT_RDONLY }
-#define MOPT_RW			{ "rw",		1, MNT_RDONLY }
+#define MOPT_RO		{ "ro",		MNT_RDONLY, MFLAG_SET }
+#define MOPT_RW		{ "rw",		MNT_RDONLY, MFLAG_INVERSE | MFLAG_SET }
 
 /* This is parsed by mount(8), but is ignored by specific mount_*(8)s. */
-#define MOPT_AUTO		{ "auto",	0, 0 }
+#define MOPT_AUTO		{ "auto",	0, MFLAG_SET }
 
 #define MOPT_FSTAB_COMPAT						\
 	MOPT_RO,							\
@@ -82,4 +94,5 @@ struct mntopt {
 	MOPT_RDONLY,							\
 	MOPT_UNION
 
-void getmntopts(const char *, const struct mntopt *, int *);
+int getmntopts(const char *, const struct mntopt *, int *);
+int getmntopt(char **, union mntval *, const struct mntopt *, int *);
Index: mount_nfs/Makefile
===================================================================
RCS file: /cvs/src/sbin/mount_nfs/Makefile,v
retrieving revision 1.10
diff -u -p -r1.10 Makefile
--- mount_nfs/Makefile	18 May 2004 11:07:53 -0000	1.10
+++ mount_nfs/Makefile	10 Jun 2004 21:39:30 -0000
@@ -4,11 +4,8 @@ PROG=	mount_nfs
 SRCS=	mount_nfs.c getmntopts.c
 MAN=	mount_nfs.8
 
-# Temporarily removed to use own getmntops.c - fvdl
-#
-#MOUNT=	${.CURDIR}/../mount
-#CFLAGS+= -DNFS -I${MOUNT}
-#.PATH:	${MOUNT}
-CFLAGS+=-DNFS
+MOUNT=	${.CURDIR}/../mount
+CFLAGS+= -DNFS -I${MOUNT}
+.PATH:	${MOUNT}
 
 .include <bsd.prog.mk>
Index: mount_nfs/getmntopts.c
===================================================================
RCS file: mount_nfs/getmntopts.c
diff -N mount_nfs/getmntopts.c
--- mount_nfs/getmntopts.c	18 May 2004 11:07:53 -0000	1.5
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,96 +0,0 @@
-/*	$OpenBSD: getmntopts.c,v 1.5 2004/05/18 11:07:53 otto Exp $	*/
-
-/*-
- * Copyright (c) 1994
- *	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. 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[] = "@(#)getmntopts.c	8.3 (Berkeley) 3/29/95";
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/mount.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fstab.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "mntopts.h"
-
-int getmnt_silent = 0;
-
-void
-getmntopts(const char *options, const struct mntopt *m0, int *flagp,
-    int *altflagp)
-{
-	const struct mntopt *m;
-	int negative;
-	char *opt, *optbuf, *p;
-	int *thisflagp;
-
-	/* Copy option string, since it is about to be torn asunder... */
-	if ((optbuf = strdup(options)) == NULL)
-		err(1, NULL);
-
-	for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
-		/* Check for "no" prefix. */
-		if (opt[0] == 'n' && opt[1] == 'o') {
-			negative = 1;
-			opt += 2;
-		} 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)
-				break;
-
-		/* Save flag, or fail if option is not recognised. */
-		if (m->m_option) {
-			thisflagp = m->m_altloc ? altflagp : flagp;
-			if (negative == m->m_inverse)
-				*thisflagp |= m->m_flag;
-			else
-				*thisflagp &= ~m->m_flag;
-		} else if (!getmnt_silent) {
-			errx(1, "-o %s: option not supported", opt);
-		}
-	}
-
-	free(optbuf);
-}
Index: mount_nfs/mntopts.h
===================================================================
RCS file: mount_nfs/mntopts.h
diff -N mount_nfs/mntopts.h
--- mount_nfs/mntopts.h	18 May 2004 11:07:53 -0000	1.5
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,78 +0,0 @@
-/*	$OpenBSD: mntopts.h,v 1.5 2004/05/18 11:07:53 otto Exp $	*/
-
-/*-
- * Copyright (c) 1994
- *      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. 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.
- *
- *	@(#)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, 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",	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 }
-
-/* 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_AUTO
-
-/* Standard options which all mounts can understand. */
-#define MOPT_STDOPTS							\
-	MOPT_USERQUOTA,							\
-	MOPT_GROUPQUOTA,						\
-	MOPT_FSTAB_COMPAT,						\
-	MOPT_NODEV,							\
-	MOPT_NOEXEC,							\
-	MOPT_NOSUID,							\
-	MOPT_RDONLY,							\
-	MOPT_UNION
-
-void getmntopts(const char *, const struct mntopt *, int *, int *);
-extern int getmnt_silent;
Index: mount_nfs/mount_nfs.c
===================================================================
RCS file: /cvs/src/sbin/mount_nfs/mount_nfs.c,v
retrieving revision 1.38
diff -u -p -r1.38 mount_nfs.c
--- mount_nfs/mount_nfs.c	18 May 2004 11:07:53 -0000	1.38
+++ mount_nfs/mount_nfs.c	10 Jun 2004 21:34:34 -0000
@@ -106,26 +106,26 @@ const struct mntopt mopts[] = {
 	MOPT_STDOPTS,
 	MOPT_FORCE,
 	MOPT_UPDATE,
-	{ "bg", 0, ALTF_BG, 1 },
-	{ "conn", 1, ALTF_NOCONN, 1 },
-	{ "dumbtimer", 0, ALTF_DUMBTIMR, 1 },
-	{ "intr", 0, ALTF_INTR, 1 },
-	{ "nfsv3", 0, ALTF_NFSV3, 1 },
-	{ "rdirplus", 0, ALTF_RDIRPLUS, 1 },
-	{ "mntudp", 0, ALTF_MNTUDP, 1 },
-	{ "resvport", 0, ALTF_RESVPORT, 1 },
+	{ "bg", ALTF_BG, 0 },
+	{ "conn", ALTF_NOCONN, MFLAG_INVERSE },
+	{ "dumbtimer", ALTF_DUMBTIMR, 0 },
+	{ "intr", ALTF_INTR, 0 },
+	{ "nfsv3", ALTF_NFSV3, 0 },
+	{ "rdirplus", ALTF_RDIRPLUS, 0 },
+	{ "mntudp", ALTF_MNTUDP, 0 },
+	{ "resvport", ALTF_RESVPORT, 0 },
 #ifdef ISO
-	{ "seqpacket", 0, ALTF_SEQPACKET, 1 },
+	{ "seqpacket", ALTF_SEQPACKET, 0 },
 #endif
-	{ "soft", 0, ALTF_SOFT, 1 },
-	{ "tcp", 0, ALTF_TCP, 1 },
-	{ "port", 0, ALTF_PORT, 1 },
-	{ "nfsv2", 0, ALTF_NFSV2, 1 },
-	{ "ac", 1, ALTF_NOAC, 1 },
-	{ "acregmin", 0, ALTF_ACREGMIN, 1},
-	{ "acregmax", 0, ALTF_ACREGMAX, 1},
-	{ "acdirmin", 0, ALTF_ACDIRMIN, 1},
-	{ "acdirmax", 0, ALTF_ACDIRMAX, 1},
+	{ "soft", ALTF_SOFT, 0 },
+	{ "tcp", ALTF_TCP, 0 },
+	{ "port", ALTF_PORT, MFLAG_INTVAL },
+	{ "nfsv2", ALTF_NFSV2, 0 },
+	{ "ac", ALTF_NOAC, 0 },
+	{ "acregmin", ALTF_ACREGMIN, MFLAG_INTVAL },
+	{ "acregmax", ALTF_ACREGMAX, MFLAG_INTVAL },
+	{ "acdirmin", ALTF_ACDIRMIN, MFLAG_INTVAL },
+	{ "acdirmax", ALTF_ACDIRMAX, MFLAG_INTVAL },
 	{ NULL }
 };
 
@@ -187,13 +187,13 @@ main(int argc, char *argv[])
 	int c;
 	struct nfs_args *nfsargsp;
 	struct nfs_args nfsargs;
-	int mntflags, altflags, num;
-	char name[MAXPATHLEN], *p, *spec;
+	int mntflags, num;
+	char name[MAXPATHLEN], *options = NULL, *p, *spec;
+	union mntval value;
 
 	retrycnt = DEF_RETRY;
 
 	mntflags = 0;
-	altflags = 0;
 	nfsargs = nfsdefargs;
 	nfsargsp = &nfsargs;
 	while ((c = getopt(argc, argv,
@@ -264,74 +264,7 @@ main(int argc, char *argv[])
 			nfsargsp->flags |= NFSMNT_RDIRPLUS;
 			break;
 		case 'o':
-			getmntopts(optarg, mopts, &mntflags, &altflags);
-			if (altflags & ALTF_BG)
-				opflags |= BGRND;
-			if (altflags & ALTF_NOCONN)
-				nfsargsp->flags |= NFSMNT_NOCONN;
-			if (altflags & ALTF_DUMBTIMR)
-				nfsargsp->flags |= NFSMNT_DUMBTIMR;
-			if (altflags & ALTF_INTR)
-				nfsargsp->flags |= NFSMNT_INT;
-			if (altflags & ALTF_NFSV3) {
-				if (force2)
-					errx(1,"conflicting version options");
-				force3 = 1;
-			}
-			if (altflags & ALTF_NFSV2) {
-				if (force3)
-					errx(1,"conflicting version options");
-				force2 = 1;
-				nfsargsp->flags &= ~NFSMNT_NFSV3;
-			}
-			if (altflags & ALTF_RDIRPLUS)
-				nfsargsp->flags |= NFSMNT_RDIRPLUS;
-			if (altflags & ALTF_MNTUDP)
-				mnttcp_ok = 0;
-			if (altflags & ALTF_RESVPORT)
-				nfsargsp->flags |= NFSMNT_RESVPORT;
-#ifdef ISO
-			if (altflags & ALTF_SEQPACKET)
-				nfsargsp->sotype = SOCK_SEQPACKET;
-#endif
-			if (altflags & ALTF_SOFT)
-				nfsargsp->flags |= NFSMNT_SOFT;
-			if (altflags & ALTF_TCP) {
-				nfsargsp->sotype = SOCK_STREAM;
-				nfsproto = IPPROTO_TCP;
-			}
-			if (altflags & ALTF_PORT)
-				port_no = atoi(strstr(optarg, "port=") + 5);
-			if (altflags & ALTF_NOAC) {
-				nfsargsp->flags
-				    |= (NFSMNT_ACREGMIN | NFSMNT_ACREGMAX |
-					NFSMNT_ACDIRMIN | NFSMNT_ACDIRMAX);
-				nfsargsp->acregmin = 0;
-				nfsargsp->acregmax = 0;
-				nfsargsp->acdirmin = 0;
-				nfsargsp->acdirmax = 0;
-			}
-			if (altflags & ALTF_ACREGMIN) {
-				nfsargsp->flags |= NFSMNT_ACREGMIN;
-				nfsargsp->acregmin =
-				    atoi(strstr(optarg, "acregmin=") + 9);
-			}
-			if (altflags & ALTF_ACREGMAX) {
-				nfsargsp->flags |= NFSMNT_ACREGMAX;
-				nfsargsp->acregmax =
-				    atoi(strstr(optarg, "acregmax=") + 9);
-			}
-			if (altflags & ALTF_ACDIRMIN) {
-				nfsargsp->flags |= NFSMNT_ACDIRMIN;
-				nfsargsp->acdirmin =
-				    atoi(strstr(optarg, "acdirmin=") + 9);
-			}
-			if (altflags & ALTF_ACDIRMAX) {
-				nfsargsp->flags |= NFSMNT_ACDIRMAX;
-				nfsargsp->acdirmax =
-				    atoi(strstr(optarg, "acdirmax=") + 9);
-			}
-			altflags = 0;
+			options = optarg;
 			break;
 		case 'P':
 			nfsargsp->flags |= NFSMNT_RESVPORT;
@@ -394,6 +327,86 @@ main(int argc, char *argv[])
 
 	if (argc != 2)
 		usage();
+
+	/* parse -o options */
+	while (options != NULL) {
+		switch (getmntopt(&options, &value, mopts, &mntflags)) {
+		case ALTF_BG:
+			opflags |= BGRND;
+			break;
+		case ALTF_NOCONN:
+			nfsargsp->flags |= NFSMNT_NOCONN;
+			break;
+		case ALTF_DUMBTIMR:
+			nfsargsp->flags |= NFSMNT_DUMBTIMR;
+			break;
+		case ALTF_INTR:
+			nfsargsp->flags |= NFSMNT_INT;
+			break;
+		case ALTF_NFSV3:
+			if (force2)
+				errx(1,
+				    "conflicting version options");
+			force3 = 1;
+			break;
+		case ALTF_NFSV2:
+			if (force3)
+				errx(1,
+				    "conflicting version options");
+			force2 = 1;
+			nfsargsp->flags &= ~NFSMNT_NFSV3;
+			break;
+		case ALTF_RDIRPLUS:
+			nfsargsp->flags |= NFSMNT_RDIRPLUS;
+			break;
+		case ALTF_MNTUDP:
+			mnttcp_ok = 0;
+			break;
+		case ALTF_RESVPORT:
+			nfsargsp->flags |= NFSMNT_RESVPORT;
+			break;
+#ifdef ISO
+		case ALTF_SEQPACKET:
+			nfsargsp->sotype = SOCK_SEQPACKET;
+			break;
+#endif
+		case ALTF_SOFT:
+			nfsargsp->flags |= NFSMNT_SOFT;
+			break;
+		case ALTF_TCP:
+			nfsargsp->sotype = SOCK_STREAM;
+			nfsproto = IPPROTO_TCP;
+			break;
+		case ALTF_PORT:
+			port_no = value.ival;
+			break;
+		case ALTF_NOAC:
+			nfsargsp->flags |= (NFSMNT_ACREGMIN |
+			    NFSMNT_ACREGMAX | NFSMNT_ACDIRMIN |
+			    NFSMNT_ACDIRMAX);
+			nfsargsp->acregmin = 0;
+			nfsargsp->acregmax = 0;
+			nfsargsp->acdirmin = 0;
+			nfsargsp->acdirmax = 0;
+			break;
+		case ALTF_ACREGMIN:
+			nfsargsp->flags |= NFSMNT_ACREGMIN;
+			nfsargsp->acregmin = value.ival;
+			break;
+		case ALTF_ACREGMAX:
+			nfsargsp->flags |= NFSMNT_ACREGMAX;
+			nfsargsp->acregmax = value.ival;
+			break;
+		case ALTF_ACDIRMIN:
+			nfsargsp->flags |= NFSMNT_ACDIRMIN;
+			nfsargsp->acdirmin = value.ival;
+			break;
+		case ALTF_ACDIRMAX:
+			nfsargsp->flags |= NFSMNT_ACDIRMAX;
+			nfsargsp->acdirmax = value.ival;
+			break;
+		}
+	}
 
 	spec = *argv++;
 	if (realpath(*argv, name) == NULL)
Index: mount_procfs/Makefile
===================================================================
RCS file: /cvs/src/sbin/mount_procfs/Makefile,v
retrieving revision 1.6
diff -u -p -r1.6 Makefile
--- mount_procfs/Makefile	18 May 2004 11:07:54 -0000	1.6
+++ mount_procfs/Makefile	9 Jun 2004 18:35:21 -0000
@@ -4,7 +4,7 @@ PROG=	mount_procfs
 SRCS=	mount_procfs.c getmntopts.c
 MAN=	mount_procfs.8
 
-MOUNT=	${.CURDIR}/../mount_nfs
+MOUNT=	${.CURDIR}/../mount
 CFLAGS+= -I${MOUNT}
 .PATH:	${MOUNT}
 
Index: mount_procfs/mount_procfs.c
===================================================================
RCS file: /cvs/src/sbin/mount_procfs/mount_procfs.c,v
retrieving revision 1.13
diff -u -p -r1.13 mount_procfs.c
--- mount_procfs/mount_procfs.c	18 May 2004 11:07:54 -0000	1.13
+++ mount_procfs/mount_procfs.c	9 Jun 2004 18:35:21 -0000
@@ -64,7 +64,7 @@ static char rcsid[] = "$OpenBSD: mount_p
 
 const struct mntopt mopts[] = {
 	MOPT_STDOPTS,
-	{ "linux", 0, PROCFSMNT_LINUXCOMPAT, 1 },
+	{ "linux", PROCFSMNT_LINUXCOMPAT, 0 },
 	{ NULL }
 };
 
@@ -81,7 +81,7 @@ main(int argc, char *argv[])
 	while ((ch = getopt(argc, argv, "o:")) != -1)
 		switch (ch) {
 		case 'o':
-			getmntopts(optarg, mopts, &mntflags, &altflags);
+			altflags |= getmntopts(optarg, mopts, &mntflags);
 			break;
 		case '?':
 		default:



Visit your host, monkey.org