+2016-04-08 Christos Zoulas <christos@zoulas.com>
+
+ * Make hasmntval() return an 0 on error, 1 on success and
+ place the value in an argument. Update all users and
+ check properly for errors. Get rid of hasmntvalerr().
+ * Add hasmntvaldelim() which takes a string delimiter. This
+ is now used to chop vers=4.1 to 4, so that we can parse the
+ version correctly (we don't care about the .1 part yet)
+
2016-03-31 Christos Zoulas <christos@zoulas.com>
* Fix SEGV on amq time printing.
if (amu_hasmntopt(&mnt, "nounmount") || amu_hasmntopt(&mnt, "noumount"))
notimeout = 1;
/* utimeout=N option: user wants to unmount this option AND set timeout */
- if ((mp->am_timeo = hasmntval(&mnt, "utimeout")) == 0)
+ if (!hasmntval(&mnt, "utimeout", &mp->am_timeo))
mp->am_timeo = gopt.am_timeo; /* otherwise use default timeout */
else
notimeout = 0;
mnt.mnt_type = HIDE_MOUNT_TYPE;
}
- retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);
- if (retry <= 0)
+ if (!hasmntval(&mnt, MNTTAB_OPT_RETRY, &retry) || retry <= 0)
retry = 2; /* XXX: default to 2 retries */
/*
nfs_args_t nfs_args;
am_nfs_handle_t *fhp, anh;
#ifndef HAVE_TRANSPORT_TYPE_TLI
- u_short port;
+ int port;
struct sockaddr_in sin;
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
/* as per POSIX, sin_len need not be set (used internally by kernel) */
sin.sin_family = AF_INET;
sin.sin_addr = myipaddr;
- port = hasmntval(&mnt, MNTTAB_OPT_PORT);
- if (port) {
+ if (hasmntval(&mnt, MNTTAB_OPT_PORT, &port) && port > 0 && port < 65536) {
sin.sin_port = htons(port);
} else {
plog(XLOG_ERROR, "no port number specified for %s", dir);
#endif /* HAVE_CDFS_ARGS_T_ISO_FLAGS */
#ifdef HAVE_CDFS_ARGS_T_ISO_PGTHRESH
- cdfs_args.iso_pgthresh = hasmntval(&mnt, MNTTAB_OPT_PGTHRESH);
+ {
+ int thresh;
+ if (!hasmntval(&mnt, MNTTAB_OPT_PGTHRESH, &thresh) || thresh < 0)
+ thresh = 0;
+ cdfs_args.iso_pgthresh = thresh;
+ }
#endif /* HAVE_CDFS_ARGS_T_ISO_PGTHRESH */
#ifdef HAVE_CDFS_ARGS_T_NORRIP
plog(XLOG_INFO, "mount_nfs_fh: NFS version %d", (int) nfs_version);
plog(XLOG_INFO, "mount_nfs_fh: using NFS transport %s", nfs_proto);
- retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);
- if (retry <= 0)
+ if (!hasmntval(&mnt, MNTTAB_OPT_RETRY, &retry) || retry <= 0)
retry = 1; /* XXX */
genflags = compute_mount_flags(&mnt);
#endif /* HAVE_PCFS_ARGS_T_FSPEC */
#ifdef HAVE_PCFS_ARGS_T_MASK
- pcfs_args.mask = 0777; /* this may be the msdos file modes */
- if ((mask = hasmntval(&mnt, MNTTAB_OPT_MASK)) > 0)
+ if (hasmntval(&mnt, MNTTAB_OPT_MASK, &mask) && mask > 0)
pcfs_args.mask = mask;
+ else
+ pcfs_args.mask = 0777; /* this may be the msdos file modes */
if (amuDebug(D_TRACE))
plog(XLOG_DEBUG, "mount_pcfs: mask=%o (octal)", (u_int) pcfs_args.mask);
#endif /* HAVE_PCFS_ARGS_T_MASK */
#ifdef HAVE_PCFS_ARGS_T_DIRMASK
- pcfs_args.dirmask = 0777; /* this may be the msdos dir modes */
- if ((mask = hasmntval(&mnt, MNTTAB_OPT_DIRMASK)) > 0)
+ if (hasmntval(&mnt, MNTTAB_OPT_DIRMASK, &mask) && mask > 0)
pcfs_args.dirmask = mask;
+ else
+ pcfs_args.dirmask = 0777; /* this may be the msdos dir modes */
if (amuDebug(D_TRACE))
plog(XLOG_DEBUG, "mount_pcfs: dirmask=%o (octal)", (u_int) pcfs_args.dirmask);
#endif /* HAVE_PCFS_ARGS_T_DIRMASK */
#endif /* HAVE_UFS_ARGS_T_FSPEC */
#ifdef HAVE_UFS_ARGS_T_UFS_PGTHRESH
- ufs_args.ufs_pgthresh = hasmntval(&mnt, MNTTAB_OPT_PGTHRESH);
+ {
+ int thresh;
+ if (!hasmntval(&mnt, MNTTAB_OPT_PGTHRESH, &thresh) || thresh < 0)
+ thresh = 0;
+ ufs_args.ufs_pgthresh = thresh;
#endif /* HAVE_UFS_ARGS_T_UFS_PGTHRESH */
/*
struct hostent *hp = NULL;
struct sockaddr_in *ip = NULL;
u_long nfs_version = 0; /* default is no version specified */
+ int val;
u_long best_nfs_version = 0;
char *nfs_proto = NULL; /* no IP protocol either */
- int nfs_port = 0;
- int nfs_port_opt = 0;
+ int nfs_port;
int fserver_is_down = 0;
if (mf->mf_fo == NULL) {
* are required or not. < 0 = no pings.
*/
mnt.mnt_opts = mf->mf_mopts;
- pingval = hasmntval(&mnt, "ping");
+ if (!hasmntval(&mnt, "ping", &pingval) || pingval < 0)
+ pingval = 0;
if (mf->mf_flags & MFF_NFS_SCALEDOWN) {
/*
* to decide the highest NFS version to try.
*/
#ifdef MNTTAB_OPT_VERS
- nfs_version = hasmntval(&mnt, MNTTAB_OPT_VERS);
+ if (!hasmntvaldelim(&mnt, MNTTAB_OPT_VERS, ",.", &val) || val < 0)
+ nfs_version = 0;
+ else
+ nfs_version = val;
#endif /* MNTTAB_OPT_VERS */
#ifdef MNTTAB_OPT_PROTO
* If the port has been determined from the portmapper, use that.
* Default to NFS_PORT otherwise (cf. RFC 2054, 3).
*/
- nfs_port_opt = hasmntval(&mnt, MNTTAB_OPT_PORT);
- if (nfs_port_opt > 0)
- nfs_port = htons(nfs_port_opt);
- if (!nfs_port)
+ if (!hasmntval(&mnt, MNTTAB_OPT_PORT, &nfs_port)
+ || nfs_port > 65535 || nfs_port <= 0)
nfs_port = htons(NFS_PORT);
+ else
+ nfs_port = htons(nfs_port);
dlog("%s: using port %d for nfs on %s", __func__,
(int) ntohs(nfs_port), host);
fs->fs_flags |= FSF_PING_UNINIT; /* pinger hasn't been initialized */
np = ALLOC(struct nfs_private);
memset((voidp) np, 0, sizeof(*np));
- np->np_mountd = htons(hasmntval(&mnt, "mountport"));
+ if (!hasmntval(&mnt, "mountport", &val) || val < 0)
+ val = 0;
+ np->np_mountd = htons(val);
if (np->np_mountd == 0) {
np->np_mountd_inval = 'Y';
np->np_xid = XID_ALLOC();
genflags = compute_mount_flags(&mnt);
- retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);
- if (retry <= 0)
+ if (!hasmntval(&mnt, MNTTAB_OPT_RETRY, &retry) || retry <= 0)
retry = 1; /* XXX */
memmove(&anh.v2, root_fhp, sizeof(*root_fhp));
extern void discard_nfs_args(void *, u_long);
extern u_long get_amd_program_number(void);
extern int getcreds(struct svc_req *, uid_t *, gid_t *, SVCXPRT *);
-extern int hasmntval(mntent_t *, char *);
-extern unsigned int hasmntvalerr(mntent_t *, char *, int *);
+extern int hasmntval(mntent_t *, char *, int *);
+extern int hasmntvaldelim(mntent_t *, char *, const char *, int *);
extern char *hasmntstr(mntent_t *, char *);
extern char *hasmnteq(mntent_t *, char *);
extern char *haseq(char *);
addvers(char *zopts, size_t l, mntent_t *mnt, u_long have_vers,
u_long want_vers)
{
- if (have_vers == want_vers &&
- hasmntval(mnt, MNTTAB_OPT_VERS) != want_vers) {
+ int val;
+ if (have_vers == want_vers
+ && hasmntvaldelim(mnt, MNTTAB_OPT_VERS, ".,", &val)
+ && (u_long)val != want_vers) {
char optsbuf[48];
xsnprintf(optsbuf, sizeof(optsbuf),
"%s=%d", MNTTAB_OPT_VERS, want_vers);
* on the values of the attribute caches.
*/
#ifdef MNTTAB_OPT_ACTIMEO
- err_acval = hasmntvalerr(mntp, MNTTAB_OPT_ACTIMEO, &acval); /* attr cache timeout (sec) */
+ err_acval = !hasmntval(mntp, MNTTAB_OPT_ACTIMEO, &acval); /* attr cache timeout (sec) */
#endif /* MNTTAB_OPT_ACTIMEO */
/*** acregmin ***/
} else {
# ifdef MNTTAB_OPT_ACREGMIN
int tmp;
- err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMIN, &tmp);
+ err_acrdmm = !hasmntval(mntp, MNTTAB_OPT_ACREGMIN, &tmp);
nap->acregmin = tmp;
# else /* not MNTTAB_OPT_ACREGMIN */
nap->acregmin = 0;
} else {
# ifdef MNTTAB_OPT_ACREGMAX
int tmp;
- err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMAX, &tmp);
+ err_acrdmm = !hasmntval(mntp, MNTTAB_OPT_ACREGMAX, &tmp);
nap->acregmax = tmp;
# else /* not MNTTAB_OPT_ACREGMAX */
nap->acregmax = 0;
} else {
# ifdef MNTTAB_OPT_ACDIRMIN
int tmp;
- err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMIN, &tmp);
+ err_acrdmm = !hasmntval(mntp, MNTTAB_OPT_ACDIRMIN, &tmp);
nap->acdirmin = tmp;
# else /* not MNTTAB_OPT_ACDIRMIN */
nap->acdirmin = 0;
} else {
# ifdef MNTTAB_OPT_ACDIRMAX
int tmp;
- err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMAX, &tmp);
+ err_acrdmm = !hasmntval(mntp, MNTTAB_OPT_ACDIRMAX, &tmp);
nap->acdirmax = tmp;
# else /* not MNTTAB_OPT_ACDIRMAX */
nap->acdirmax = 0;
compute_nfs_common_args(struct nfs_common_args *nap, mntent_t *mntp,
const char *nfs_proto, u_long nfs_version)
{
+ int val;
#ifdef MNT2_NFS_OPT_TCP
if (nfs_proto && STREQ(nfs_proto, "tcp"))
nap->flags |= MNT2_NFS_OPT_TCP;
# endif /* not MNTTAB_OPT_RESVPORT */
#endif /* MNT2_NFS_OPT_RESVPORT */
- nap->rsize = hasmntval(mntp, MNTTAB_OPT_RSIZE);
+ if (!hasmntval(mntp, MNTTAB_OPT_RSIZE, &val) || val <= 0)
+ nap->rsize = 0;
+ else
+ nap->rsize = val;
#ifdef MNT2_NFS_OPT_RSIZE
if (nap->rsize)
nap->flags |= MNT2_NFS_OPT_RSIZE;
if (nfs_version == NFS_VERSION && nap->rsize > 8192)
nap->rsize = 8192;
- nap->wsize = hasmntval(mntp, MNTTAB_OPT_WSIZE);
+ if (!hasmntval(mntp, MNTTAB_OPT_WSIZE, &val) || val <= 0)
+ nap->wsize = 0;
+ else
+ nap->wsize = val;
#ifdef MNT2_NFS_OPT_WSIZE
if (nap->wsize)
nap->flags |= MNT2_NFS_OPT_WSIZE;
if (nfs_version == NFS_VERSION && nap->wsize > 8192)
nap->wsize = 8192;
- nap->timeo = hasmntval(mntp, MNTTAB_OPT_TIMEO);
+ if (!hasmntval(mntp, MNTTAB_OPT_TIMEO, &val) || val <= 0)
+ nap->timeo = 0;
+ else
+ nap->timeo = val;
#ifdef MNT2_NFS_OPT_TIMEO
if (nap->timeo)
nap->flags |= MNT2_NFS_OPT_TIMEO;
#endif /* MNT2_NFS_OPT_TIMEO */
- nap->retrans = hasmntval(mntp, MNTTAB_OPT_RETRANS);
+ if (!hasmntval(mntp, MNTTAB_OPT_RETRANS, &val) || val <= 0)
+ nap->retrans = 0;
+ else
+ nap->retrans = val;
#ifdef MNT2_NFS_OPT_RETRANS
if (nap->retrans)
nap->flags |= MNT2_NFS_OPT_RETRANS;
char *host_name,
char *fs_name)
{
+ int val;
struct nfs_common_args a;
/* initialize just in case */
memset((voidp) nap, 0, sizeof(nfs_args_t));
/************************************************************************/
#ifdef MNT2_NFS_OPT_BIODS
- if ((nap->biods = hasmntval(mntp, MNTTAB_OPT_BIODS)))
+ if (!hasmntval(mntp, MNTTAB_OPT_BIODS, &val) || val <= 0)
+ nap->biods = 0;
+ else {
+ nap->biods = val;
nap->flags |= MNT2_NFS_OPT_BIODS;
+ }
#endif /* MNT2_NFS_OPT_BIODS */
#ifdef MNTTAB_OPT_SYMTTL /* symlink cache time-to-live */
- if ((nap->symttl = hasmntval(mntp, MNTTAB_OPT_SYMTTL)))
+ if (!hasmntval(mntp, MNTTAB_OPT_SYMTTL, &val) || val <= 0)
+ nap->symttl = 0;
+ else {
+ nap->symttl = val;
nap->flags |= MNT2_NFS_OPT_SYMTTL;
+ }
#endif /* MNTTAB_OPT_SYMTTL */
#ifdef MNT2_NFS_OPT_PGTHRESH /* paging threshold */
- if ((nap->pg_thresh = hasmntval(mntp, MNTTAB_OPT_PGTHRESH)))
+ if (!hasmntval(mntp, MNTTAB_OPT_PGTHRESH, &val) || val <= 0)
+ nap->pg_thresh = 0;
+ else {
+ nap->pg_thresh = val;
nap->flags |= MNT2_NFS_OPT_PGTHRESH;
+ }
#endif /* MNT2_NFS_OPT_PGTHRESH */
#if defined(MNT2_NFS_OPT_POSIX) && defined(MNTTAB_OPT_POSIX)
#ifdef HAVE_TRANSPORT_TYPE_TLI
/* set up syncaddr field */
- nap->syncaddr = (struct netbuf *) NULL;
+ nap->syncaddr = NULL;
/* set up knconf field */
if (get_knetconfig(&nap->knconf, nfsncp, nfs_proto) < 0) {
#endif /* HAVE_NFS_ARGS_T_OPTSTR */
#if defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS)
- nap->maxgrouplist = hasmntval(mntp, MNTTAB_OPT_MAXGROUPS);
- if (nap->maxgrouplist != 0)
+ if (!hasmntval(mntp, MNTTAB_OPT_MAXGROUPS, &val) || val <= 0)
+ nap->maxgrouplist = 0;
+ else {
+ nap->maxgrouplist = val;
nap->flags |= MNT2_NFS_OPT_MAXGRPS;
+ }
#endif /* defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) */
/************************************************************************/
{
char *s;
struct nfs_common_args a;
+ int val;
uint16_t nfs_port;
/* initialize just in case */
nap->host_addr = xmalloc(nap->host_addrlen);
memcpy(nap->host_addr, ip_addr, nap->host_addrlen);
- nfs_port = hasmntval(mntp, MNTTAB_OPT_PORT);
- if (nfs_port == 0)
+ if (!hasmntval(mntp, MNTTAB_OPT_PORT, &val) || val <= 0 || val > 65536)
nfs_port = htons(NFS_PORT);
else
- nfs_port = htons(nfs_port);
+ nfs_port = htons(val);
((struct sockaddr_in *)nap->host_addr)->sin_port = nfs_port;
#endif /* MNT2_NFS_OPT_POSIX && MNTTAB_OPT_POSIX */
#if defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS)
- nap->maxgrouplist = hasmntval(mntp, MNTTAB_OPT_MAXGROUPS);
- if (nap->maxgrouplist != 0)
+ nap->maxgrouplist =
+ if (!hasmntval(mntp, MNTTAB_OPT_MAXGROUPS, &val) || val <= 0)
+ nap->maxgrouplist = 0;
+ else {
+ nap->maxgrouplist = val;
nap->flags |= MNT2_NFS_OPT_MAXGRPS;
+ }
#endif /* defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) */
#ifdef HAVE_NFS_ARGS_T_OPTSTR
/*
- * Wrapper around hasmntvalerr(), which retains backwards compatibiliy with
- * older use of hasmntval().
- *
- * XXX: eventually, all use of hasmntval() should be replaced with
- * hasmntvalerr().
+ * Wrapper around hasmntvaldelim(), which uses the standard "," delim
*/
int
-hasmntval(mntent_t *mnt, char *opt)
+hasmntval(mntent_t *mnt, char *opt, int *valp)
{
- int err, val = 0;
-
- err = hasmntvalerr(mnt, opt, &val);
- if (err) /* if there was an error (hasmntvalerr returned 1) */
- return 0; /* redundant: val==0 above, but leave here for clarity */
- /* otherwise there was no error */
- return val;
+ return hasmntvaldelim(mnt, opt, ",", valp);
}
* valp (argument won't be touched if no value is set, for example due to an
* error).
*
- * Returns non-zero (1) on error; returns 0 on success.
- *
- * XXX: eventually, all use of hasmntval() should be replaced with
- * hasmntvalerr().
+ * Returns 0 on error; returns 1 on success.
*/
-unsigned int
-hasmntvalerr(mntent_t *mnt, char *opt, int *valp)
+int
+hasmntvaldelim(mntent_t *mnt, char *opt, const char *delim, int *valp)
{
char *str = amu_hasmntopt(mnt, opt);
- int err = 1; /* 1 means no good value was set (an error) */
char *eq, *endptr;
long int i;
/* exit if no option specificed */
- if (!str) {
- goto out;
- }
+ if (!str)
+ return 0;
eq = hasmnteq(mnt, opt);
if (!eq) { /* no argument to option ('=' sign was missing) */
plog(XLOG_MAP, "numeric option to \"%s\" missing", opt);
- goto out;
+ return 0;
}
/* if got here, then we had an '=' after option name */
endptr = NULL;
i = strtol(eq, &endptr, 0); /* hex and octal allowed ;-) */
if (!endptr ||
- (endptr != eq && (*endptr == ',' || *endptr == '\0'))) {
+ (endptr != eq && (*endptr == '\0' || strchr(delim, *endptr)))) {
/*
* endptr set means strtol saw a non-digit. If the non-digit is a
* comma, it's probably the start of the next option. If the comma is
* string.
*/
*valp = (int) i; /* set good value */
- err = 0; /* no error */
+ return 1;
} else {
/* whatever was after the '=' sign wasn't a number */
plog(XLOG_MAP, "invalid numeric option in \"%s\": \"%s\"", opt, str);
/* fall through to error/exit processing */
+ return 0;
}
-
- out:
- return err;
}