add functions to retrieve option values.

This commit is contained in:
christos 2003-04-11 17:36:57 +00:00
parent 350a2ec006
commit 8099c8302c
4 changed files with 162 additions and 29 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: mntopts.h,v 1.1 2003/03/22 12:44:03 jdolecek Exp $ */
/* $NetBSD: mntopts.h,v 1.2 2003/04/11 17:36:57 christos Exp $ */
/*-
* Copyright (c) 1994
@ -34,6 +34,8 @@
*
* @(#)mntopts.h 8.7 (Berkeley) 3/29/95
*/
#ifndef _MNTOPTS_H_
#define _MNTOPTS_H_
struct mntopt {
const char *m_option; /* option name */
@ -91,5 +93,15 @@ struct mntopt {
MOPT_IGNORE, \
MOPT_SYMPERM
void getmntopts __P((const char *, const struct mntopt *, int *, int *));
__BEGIN_DECLS
typedef struct mntoptparse *mntoptparse_t;
mntoptparse_t getmntopts __P((const char *, const struct mntopt *, int *,
int *));
const char *getmntoptstr __P((mntoptparse_t, const char *));
long getmntoptnum __P((mntoptparse_t, const char *));
void freemntopts __P((mntoptparse_t));
extern int getmnt_silent;
__END_DECLS
#endif /* _MNTOPTS_H_ */

View File

@ -1,4 +1,4 @@
.\" $NetBSD: getmntopts.3,v 1.2 2003/03/22 15:46:47 wiz Exp $
.\" $NetBSD: getmntopts.3,v 1.3 2003/04/11 17:37:28 christos Exp $
.\"
.\" Copyright (c) 1994
.\" The Regents of the University of California. All rights reserved.
@ -33,7 +33,7 @@
.\"
.\" @(#)getmntopts.3 8.3 (Berkeley) 3/30/95
.\"
.Dd March 22, 2003
.Dd April 11, 2003
.Dt GETMNTOPTS 3
.Os
.Sh NAME
@ -43,8 +43,14 @@
.Lb libutil
.Sh SYNOPSIS
.Fd #include \*[Lt]mntopts.h\*[Gt]
.Ft void
.Ft mntoptparse_t
.Fn getmntopts "const char *options" "const struct mntopt *mopts" "int *flagp" "int *altflagp"
.Ft const char *
.Fn getmntoptstr "mntoptparse_t mp" "const char *opt"
.Ft long
.Fn getmntoptnum "mntoptparse_t mp" "const char *opt"
.Ft void
.Fn freemntopts "mntoptparse_t mp"
.Sh DESCRIPTION
The
.Fn getmntopts
@ -138,6 +144,23 @@ flags to be set.
Finally, the table must be terminated by an entry with a
.Dv NULL
first element.
.Pp
The
.Fn getmntoptstr
function returns the string value of the named option, if such a value
was set it the option string.
.Pp
The
.Fn getmntoptnum
returns the long value of the named option, if such a value was set it the
option string. It prints an error message and exits if the value was not
set, or could not be converted from a string to a long.
.Pp
r
The
.Fn freemntopts
frees the storage used by
.Fn getmntopts .
.Sh EXAMPLES
Most commands will use the standard option set.
Local filesystems which support the
@ -155,12 +178,24 @@ static const struct mntopt mopts[] = {
{ NULL }
};
...
mntflags = mntaltflags = 0;
...
getmntopts(options, mopts, \*[Am]mntflags, \*[Am]mntaltflags);
...
...
long val;
mntflags = mntaltflags = 0;
mntoptparse_t mp;
...
if ((mp = getmntopts(options, mopts, \*[Am]mntflags, \*[Am]mntaltflags)) == NULL)
err(1, NULL);
...
val = getmntoptnum(mp, "rsize");
freemntopts(mp);
.Ed
.Sh RETURN VALUE
.Fn getmntopts
returns NULL if an error occured.
.Fn getmntoptstr
returns NULL if the option does not have an argument, or the option string.
.Fn getmntoptnum
returns -1 if an error occured and the getmnt_silent is set.
.Sh DIAGNOSTICS
If the external integer variable
.Dv getmnt_silent
@ -179,5 +214,6 @@ The
.Fn getmntopts
function appeared in
.Bx 4.4 .
It was moved to the utilities library in
It was moved to the utilities library and enhanced to retrieve option
values in
.Nx 2.0 .

View File

@ -1,4 +1,4 @@
/* $NetBSD: getmntopts.c,v 1.1 2003/03/22 12:44:04 jdolecek Exp $ */
/* $NetBSD: getmntopts.c,v 1.2 2003/04/11 17:37:28 christos Exp $ */
/*-
* Copyright (c) 1994
@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)getmntopts.c 8.3 (Berkeley) 3/29/95";
#else
__RCSID("$NetBSD: getmntopts.c,v 1.1 2003/03/22 12:44:04 jdolecek Exp $");
__RCSID("$NetBSD: getmntopts.c,v 1.2 2003/04/11 17:37:28 christos Exp $");
#endif
#endif /* not lint */
@ -55,23 +55,107 @@ __RCSID("$NetBSD: getmntopts.c,v 1.1 2003/03/22 12:44:04 jdolecek Exp $");
int getmnt_silent = 0;
void
getmntopts(options, m0, flagp, altflagp)
static const char errmsg[] = "-o %s: option not supported";
struct mntoptparse {
const char *options;
const struct mntopt *m0;
int *flagp;
int *altflagp;
const struct mntopt *mopts;
char *optbuf;
char **optarg;
};
const char *
getmntoptstr(mntoptparse_t mp, const char *opt)
{
const struct mntopt *m;
for (m = mp->mopts; m->m_option != NULL; m++)
if (strcasecmp(opt, m->m_option) == 0)
break;
if (m->m_option == NULL) {
if (getmnt_silent == 0)
errx(1, errmsg, opt);
else
return NULL;
}
return mp->optarg[m - mp->mopts];
}
long
getmntoptnum(mntoptparse_t mp, const char *opt)
{
char *ep;
long rv;
void (*fun)(int, const char *, ...) = NULL;
const char *val = getmntoptstr(mp, opt);
if (val == NULL) {
if (getmnt_silent == 0)
errx(1, "Missing %s argument", opt);
else
return -1;
}
errno = 0;
rv = strtol(val, &ep, 0);
if (*ep)
fun = errx;
if (errno == ERANGE && (rv == LONG_MAX || rv == LONG_MIN))
fun = err;
if (fun) {
if (getmnt_silent != 0)
return -1;
(*fun)(1, "Invalid %s argument `%s'", opt, val);
}
return rv;
}
void
freemntopts(mntoptparse_t mp)
{
free(mp->optbuf);
free(mp->optarg);
free(mp);
}
mntoptparse_t
getmntopts(const char *options, const struct mntopt *m0, int *flagp,
int *altflagp)
{
const struct mntopt *m;
int negative;
char *opt, *optbuf, *p;
char *opt, *p;
int *thisflagp;
size_t nopts;
mntoptparse_t mp;
for (nopts = 0, m = m0; m->m_option != NULL; ++m, nopts++)
continue;
if ((mp = malloc(sizeof(struct mntoptparse))) == NULL)
return NULL;
/* Copy option string, since it is about to be torn asunder... */
if ((optbuf = strdup(options)) == NULL)
err(1, NULL);
if ((mp->optbuf = strdup(options)) == NULL) {
free(mp);
return NULL;
}
for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
if ((mp->optarg = calloc(nopts, sizeof(char *))) == NULL) {
free(mp->optbuf);
free(mp);
return NULL;
}
mp->mopts = m0;
mp->options = options;
for (opt = mp->optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
/* Check for "no" prefix. */
if (opt[0] == 'n' && opt[1] == 'o') {
negative = 1;
@ -84,8 +168,9 @@ getmntopts(options, m0, flagp, altflagp)
* ignore the assignment as it's handled elsewhere
*/
p = strchr(opt, '=');
if (p)
*p = '\0';
if (p) {
*p++ = '\0';
}
/* Scan option table. */
for (m = m0; m->m_option != NULL; ++m)
@ -94,15 +179,15 @@ getmntopts(options, m0, flagp, altflagp)
/* Save flag, or fail if option is not recognised. */
if (m->m_option) {
mp->optarg[m - m0] = p;
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);
errx(1, errmsg, opt);
}
}
free(optbuf);
return mp;
}

View File

@ -1,5 +1,5 @@
# $NetBSD: shlib_version,v 1.32 2003/03/22 12:44:04 jdolecek Exp $
# $NetBSD: shlib_version,v 1.33 2003/04/11 17:37:28 christos Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
#
major=7
minor=2
minor=3