From c32970f0421deced9a45c9bf8e23dd7db754d8b0 Mon Sep 17 00:00:00 2001 From: helg Date: Mon, 11 Dec 2017 12:38:54 +0000 Subject: [PATCH] sscanf(3) is now used to parse templates that contain format specifiers (e.g. %u, %o) other than %s. This aligns libfuse with the Linux reference implementation. ok mpi@ --- lib/libfuse/fuse_opt.c | 16 +- regress/lib/libfuse/fuse-opt-parse.c | 215 +++++++++++++-------------- 2 files changed, 112 insertions(+), 119 deletions(-) diff --git a/lib/libfuse/fuse_opt.c b/lib/libfuse/fuse_opt.c index aa5436b4b4e..e7ec4168604 100644 --- a/lib/libfuse/fuse_opt.c +++ b/lib/libfuse/fuse_opt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fuse_opt.c,v 1.21 2017/12/11 12:31:00 helg Exp $ */ +/* $OpenBSD: fuse_opt.c,v 1.22 2017/12/11 12:38:54 helg Exp $ */ /* * Copyright (c) 2013 Sylvestre Gallon * Copyright (c) 2013 Stefan Sperling @@ -233,18 +233,16 @@ parse_opt(const struct fuse_opt *o, const char *opt, void *data, } 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 */ + /* All other templates, let sscanf deal with them. */ + if (sscanf(opt, o->templ, data + o->off) != 1) { + fprintf(stderr, "fuse: Invalid value %s for " + "option %s\n", val, o->templ); + return (-1); + } ret = IFUSE_OPT_DISCARD; } } diff --git a/regress/lib/libfuse/fuse-opt-parse.c b/regress/lib/libfuse/fuse-opt-parse.c index 0b626180e4d..339dfc1ad82 100644 --- a/regress/lib/libfuse/fuse-opt-parse.c +++ b/regress/lib/libfuse/fuse-opt-parse.c @@ -14,6 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include @@ -25,26 +26,41 @@ struct data { char *x; char *optstring; int debug; + int foreground; int noatime; int ssh_ver; int count; int cache; + int set_gid; + int gid; +}; + +enum { + KEY_DEBUG, + KEY_NOATIME, + KEY_PORT }; #define DATA_OPT(o,m,v) {o, offsetof(struct data, m), v} struct fuse_opt opts[] = { - FUSE_OPT_KEY("-p ", 1), - FUSE_OPT_KEY("debug", 3), - FUSE_OPT_KEY("noatime", 4), + FUSE_OPT_KEY("noatime", KEY_NOATIME ), DATA_OPT("optstring=%s", optstring, 0), DATA_OPT("-f=%s", fsname, 0), DATA_OPT("-x %s", x, 0), DATA_OPT("--count=%u", count, 0), DATA_OPT("-1", ssh_ver, 5), - /*DATA_OPT("cache=yes", cache, 1),*/ + DATA_OPT("cache=yes", cache, 1), DATA_OPT("cache=no", cache, 0), + DATA_OPT("debug", debug, 1), + DATA_OPT("debug", foreground, 1), + FUSE_OPT_KEY("debug", KEY_DEBUG ), + FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP), + DATA_OPT("-p", port, 25), + FUSE_OPT_KEY("-p ", KEY_PORT ), + DATA_OPT("gid=", set_gid, 1), + DATA_OPT("gid=%o", gid, 1), FUSE_OPT_END }; @@ -52,20 +68,20 @@ struct fuse_opt opts[] = { int proc(void *data, const char *arg, int key, struct fuse_args *args) { - struct data *conf = (struct data *)data; + struct data *conf = data; if (conf == NULL) return (1); switch (key) { - case 1: + case KEY_PORT: conf->port = atoi(&arg[2]); return (0); - case 3: - conf->debug = 1; - return (1); - case 4: + case KEY_DEBUG: + conf->debug = 2; + return (0); + case KEY_NOATIME: conf->noatime = 1; return (1); } @@ -73,9 +89,6 @@ proc(void *data, const char *arg, int key, struct fuse_args *args) return (1); } -#define TEST_DATA_INT(m, v) if (data.m != v) exit(__LINE__) -#define TEST_DATA_STR(m, v) if (data.m == NULL || strcmp(data.m, v) != 0) exit(__LINE__) - /* * A NULL 'args' is equivalent to an empty argument vector. */ @@ -86,17 +99,17 @@ test_null_args(void) { bzero(&data, sizeof(data)); - if (fuse_opt_parse(NULL, &data, opts, proc) != 0) - exit(__LINE__); - - TEST_DATA_INT(port, 0); - TEST_DATA_INT(fsname, 0); - TEST_DATA_INT(x, 0); - TEST_DATA_INT(optstring, 0); - TEST_DATA_INT(debug, 0); - TEST_DATA_INT(noatime, 0); - TEST_DATA_INT(ssh_ver, 0); - TEST_DATA_INT(count, 0); + assert(fuse_opt_parse(NULL, &data, opts, proc) == 0); + + assert(data.port == 0); + assert(data.fsname == NULL); + assert(data.x == NULL); + assert(data.optstring == NULL); + assert(data.debug == 0); + assert(data.noatime == 0); + assert(data.ssh_ver == 0); + assert(data.count == 0); + assert(data.cache == 0); } /* @@ -120,26 +133,24 @@ test_null_opts(void) bzero(&data, sizeof(data)); - if (fuse_opt_parse(&args, &data, NULL, proc) != 0) - exit(__LINE__); - - TEST_DATA_INT(port, 0); - TEST_DATA_INT(fsname, 0); - TEST_DATA_INT(x, 0); - TEST_DATA_INT(optstring, 0); - TEST_DATA_INT(debug, 0); - TEST_DATA_INT(noatime, 0); - TEST_DATA_INT(ssh_ver, 0); - TEST_DATA_INT(count, 0); - - if (args.argc != 2) - exit(__LINE__); - if (strcmp(args.argv[0], "progname") != 0) - exit(__LINE__); - if (strcmp(args.argv[1], "/mnt") != 0) - exit(__LINE__); - if (args.allocated == 0) - exit(__LINE__); + assert(fuse_opt_parse(&args, &data, NULL, proc) == 0); + + assert(data.port == 0); + assert(data.fsname == NULL); + assert(data.x == NULL); + assert(data.optstring == NULL); + assert(data.debug == 0); + assert(data.noatime == 0); + assert(data.ssh_ver == 0); + assert(data.count == 0); + assert(data.cache == 0); + assert(data.set_gid == 0); + assert(data.gid == 0); + + assert(args.argc == 2); + assert(strcmp(args.argv[0], "progname") == 0); + assert(strcmp(args.argv[1], "/mnt") == 0); + assert(args.allocated); fuse_opt_free_args(&args); } @@ -155,7 +166,7 @@ test_null_proc(void) char *argv_null_proc[] = { "progname", - "-odebug,noatime", + "-odebug,noatime,gid=077", "-d", "-p", "22", "/mnt", @@ -165,7 +176,7 @@ test_null_proc(void) "-o", "optstring=", "-o", "optstring=optstring", "--count=10" - }; + }; args.argc = sizeof(argv_null_proc) / sizeof(argv_null_proc[0]); args.argv = argv_null_proc; @@ -173,38 +184,30 @@ test_null_proc(void) bzero(&data, sizeof(data)); - if (fuse_opt_parse(&args, &data, opts, NULL) != 0) - exit(__LINE__); - - TEST_DATA_INT(port, 0); - TEST_DATA_STR(fsname, "filename"); - TEST_DATA_STR(x, "xanadu"); - TEST_DATA_STR(optstring, "optstring"); - TEST_DATA_INT(debug, 0); - TEST_DATA_INT(noatime, 0); - TEST_DATA_INT(ssh_ver, 5); - TEST_DATA_INT(count, 10); - - if (args.argc != 8) - exit(__LINE__); - if (strcmp(args.argv[0], "progname") != 0) - exit(__LINE__); - if (strcmp(args.argv[1], "-o") != 0) - exit(__LINE__); - if (strcmp(args.argv[2], "debug") != 0) - exit(__LINE__); - if (strcmp(args.argv[3], "-o") != 0) - exit(__LINE__); - if (strcmp(args.argv[4], "noatime") != 0) - exit(__LINE__); - if (strcmp(args.argv[5], "-d") != 0) - exit(__LINE__); - if (strcmp(args.argv[6], "-p22") != 0) - exit(__LINE__); - if (strcmp(args.argv[7], "/mnt") != 0) - exit(__LINE__); - if (args.allocated == 0) - exit(__LINE__); + assert(fuse_opt_parse(&args, &data, opts, NULL) == 0); + + assert(data.port == 25); + assert(strcmp(data.fsname, "filename") == 0); + assert(strcmp(data.x, "xanadu") == 0); + assert(strcmp(data.optstring, "optstring") == 0); + assert(data.debug == 1); + assert(data.noatime == 0); + assert(data.ssh_ver == 5); + assert(data.count == 10); + assert(data.cache == 0); + assert(data.set_gid == 1); + assert(data.gid == 077); + + assert(args.argc == 8); + assert(strcmp(args.argv[0], "progname") == 0); + assert(strcmp(args.argv[1], "-o") == 0); + assert(strcmp(args.argv[2], "debug") == 0); + assert(strcmp(args.argv[3], "-o") == 0); + assert(strcmp(args.argv[4], "noatime") == 0); + assert(strcmp(args.argv[5], "-d") == 0); + assert(strcmp(args.argv[6], "-p22") == 0); + assert(strcmp(args.argv[7], "/mnt") == 0); + assert(args.allocated); fuse_opt_free_args(&args); } @@ -220,7 +223,7 @@ test_all_args(void) char *argv[] = { "progname", - "-odebug,noatime", + "-odebug,noatime,gid=077", "-d", "-p", "22", "/mnt", @@ -237,37 +240,29 @@ test_all_args(void) bzero(&data, sizeof(data)); - if (fuse_opt_parse(&args, &data, opts, proc) != 0) - exit(__LINE__); - - TEST_DATA_INT(port, 22); - TEST_DATA_STR(fsname, "filename"); - TEST_DATA_STR(x, "xanadu"); - TEST_DATA_STR(optstring, "optstring"); - TEST_DATA_INT(debug, 1); - TEST_DATA_INT(noatime, 1); - TEST_DATA_INT(ssh_ver, 5); - TEST_DATA_INT(count, 10); - TEST_DATA_INT(cache, 0); - - if (args.argc != 7) - exit(__LINE__); - if (strcmp(args.argv[0], "progname") != 0) - exit(__LINE__); - if (strcmp(args.argv[1], "-o") != 0) - exit(__LINE__); - if (strcmp(args.argv[2], "debug") != 0) - exit(__LINE__); - if (strcmp(args.argv[3], "-o") != 0) - exit(__LINE__); - if (strcmp(args.argv[4], "noatime") != 0) - exit(__LINE__); - if (strcmp(args.argv[5], "-d") != 0) - exit(__LINE__); - if (strcmp(args.argv[6], "/mnt") != 0) - exit(__LINE__); - if (args.allocated == 0) - exit(__LINE__); + assert(fuse_opt_parse(&args, &data, opts, proc) == 0); + + assert(data.port == 22); + assert(strcmp(data.fsname, "filename") == 0); + assert(strcmp(data.x, "xanadu") == 0); + assert(strcmp(data.optstring, "optstring") == 0); + assert(data.debug == 2); + assert(data.noatime == 1); + assert(data.ssh_ver == 5); + assert(data.count == 10); + assert(data.cache == 0); + assert(data.set_gid == 1); + assert(data.gid == 077); + + assert(args.argc == 7); + assert(strcmp(args.argv[0], "progname") == 0); + assert(strcmp(args.argv[1], "-o") == 0); + assert(strcmp(args.argv[2], "debug") == 0); + assert(strcmp(args.argv[3], "-o") == 0); + assert(strcmp(args.argv[4], "noatime") == 0); + assert(strcmp(args.argv[5], "-d") == 0); + assert(strcmp(args.argv[6], "/mnt") == 0); + assert(args.allocated); fuse_opt_free_args(&args); } -- 2.20.1