From ec9508f9e1aec89cba84959920958759743150ef Mon Sep 17 00:00:00 2001 From: helg Date: Mon, 11 Dec 2017 12:31:00 +0000 Subject: [PATCH] Update to fuse_opt_parse(3) so that all option templates are now matched for the supplied option. This allows the following templates to be supplied to set multiple members of a struct at the same time. e.g. #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v } static const struct fuse_opt fuse_lib_opts[] = { FUSE_LIB_OPT("gid=", set_gid, 1), FUSE_LIB_OPT("gid=%u", gid, 0), FUSE_OPT_END }; If "-ogid=1000" is passed to fuse_opt_parse(3) it will set both: fuse_config.set_gid=1 fuse_config.gid=1000 ok mpi@ --- lib/libfuse/fuse_opt.c | 100 ++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 46 deletions(-) diff --git a/lib/libfuse/fuse_opt.c b/lib/libfuse/fuse_opt.c index 0b026cc6038..aa5436b4b4e 100644 --- a/lib/libfuse/fuse_opt.c +++ b/lib/libfuse/fuse_opt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fuse_opt.c,v 1.20 2017/12/11 12:01:55 helg Exp $ */ +/* $OpenBSD: fuse_opt.c,v 1.21 2017/12/11 12:31:00 helg Exp $ */ /* * Copyright (c) 2013 Sylvestre Gallon * Copyright (c) 2013 Stefan Sperling @@ -95,7 +95,6 @@ match_opt(const char *templ, const char *opt) return (0); } - static int add_opt(char **opts, const char *opt) { @@ -185,67 +184,76 @@ fuse_opt_add_arg(struct fuse_args *args, const char *name) } static int -parse_opt(const struct fuse_opt *o, const char *val, void *data, +parse_opt(const struct fuse_opt *o, const char *opt, void *data, fuse_opt_proc_t f, struct fuse_args *arg) { - int keyval; - size_t idx; + const char *val; + int keyval, ret, found; + size_t sep; if (o == NULL) - return IFUSE_OPT_KEEP; + return (IFUSE_OPT_KEEP); keyval = 0; + found = 0; for(; o->templ; o++) { + sep = match_opt(o->templ, opt); + if (sep == 0) + continue; + + found = 1; + val = opt; + /* check key=value or -p n */ - idx = strcspn(o->templ, "= "); - - if (strncmp(val, o->templ, idx) == 0) { - if (o->templ[idx] == '=') { - keyval = 1; - val = &val[idx + 1]; - } else if (o->templ[idx] == ' ') { - keyval = 1; - if (idx == strlen(val)) { - /* ask for next arg to be included */ - return IFUSE_OPT_NEED_ANOTHER_ARG; - } else if (strchr(o->templ, '%') != NULL) { - val = &val[idx]; - } + if (o->templ[sep] == '=') { + keyval = 1; + val = &opt[sep + 1]; + } else if (o->templ[sep] == ' ') { + keyval = 1; + if (sep == strlen(opt)) { + /* ask for next arg to be included */ + return (IFUSE_OPT_NEED_ANOTHER_ARG); + } else if (strchr(o->templ, '%') != NULL) { + val = &opt[sep]; } + } - if (o->val == FUSE_OPT_KEY_DISCARD) - return (IFUSE_OPT_DISCARD); - - if (o->val == FUSE_OPT_KEY_KEEP) + if (o->val == FUSE_OPT_KEY_DISCARD) + ret = IFUSE_OPT_DISCARD; + else if (o->val == FUSE_OPT_KEY_KEEP) + ret = IFUSE_OPT_KEEP; + else if (FUSE_OPT_IS_OPT_KEY(o)) { + if (f == NULL) return (IFUSE_OPT_KEEP); - if (FUSE_OPT_IS_OPT_KEY(o)) { - if (f == NULL) - return IFUSE_OPT_KEEP; - - return f(data, val, o->val, arg); - } else if (data == NULL) { - return (-1); - } else if (strchr(o->templ, '%') == NULL) { - *((int *)(data + o->off)) = o->val; - } else if (strstr(o->templ, "%u") != NULL) { - *((unsigned int*)(data + o->off)) = atoi(val); - } else if (strstr(o->templ, "%lu") != NULL) { - *((unsigned long*)(data + o->off)) = - strtoul(val, NULL, 0); - } else if (strstr(o->templ, "%s") != NULL) { - *((char **)(data + o->off)) = strdup(val); - } else { - /* TODO other parameterised templates */ - } - - return (IFUSE_OPT_DISCARD); + ret = f(data, val, o->val, arg); + } else if (data == NULL) { + return (-1); + } else if (strchr(o->templ, '%') == NULL) { + *((int *)(data + o->off)) = o->val; + ret = IFUSE_OPT_DISCARD; + } else if (strstr(o->templ, "%u") != NULL) { + *((unsigned int*)(data + o->off)) = atoi(val); + ret = IFUSE_OPT_DISCARD; + } else if (strstr(o->templ, "%lu") != NULL) { + *((unsigned long*)(data + o->off)) = + strtoul(val, NULL, 0); + ret = IFUSE_OPT_DISCARD; + } else if (strstr(o->templ, "%s") != NULL) { + *((char **)(data + o->off)) = strdup(val); + ret = IFUSE_OPT_DISCARD; + } else { + /* TODO other parameterised templates */ + ret = IFUSE_OPT_DISCARD; } } + if (found) + return (ret); + if (f != NULL) - return f(data, val, FUSE_OPT_KEY_OPT, arg); + return f(data, opt, FUSE_OPT_KEY_OPT, arg); return (IFUSE_OPT_KEEP); } -- 2.20.1