diff options
| author | xtraeme <xtraeme@NetBSD.org> | 2007-02-28 16:23:00 +0000 |
|---|---|---|
| committer | xtraeme <xtraeme@NetBSD.org> | 2007-02-28 16:23:00 +0000 |
| commit | c7b91b596f4f768d18c6157fc7b4ad57fa1da39a (patch) | |
| tree | dd569968aead88e63421d315867c62977d6acdc8 /lib/librefuse | |
| parent | aba6b126c7318b25f05ffc5b1ba5cfa9a49001ec (diff) | |
* Move fuse_opt* defs and prototypes into fuse_opt.h.
* Move fuse_opt* funcs from refuse.c into refuse_opt.c.
Implement fuse_opt_parse() and fuse_opt_match(). And make the other
functions just dummy, always returning 0 (I added debugging printfs
to see what the application is trying to do).
For now there are two things that do not work in fuse_opt:
* options accepting arguments, i.e -otimeout=%u or -ofile=%s.
* options without arguments are not enabled, just parsed.
At least now curlftpfs works, even with verbose mode! :-)
Ok'ed by pooka.
Diffstat (limited to 'lib/librefuse')
| -rw-r--r-- | lib/librefuse/Makefile | 11 | ||||
| -rw-r--r-- | lib/librefuse/fuse.h | 24 | ||||
| -rw-r--r-- | lib/librefuse/fuse_opt.h | 61 | ||||
| -rw-r--r-- | lib/librefuse/refuse.c | 44 | ||||
| -rw-r--r-- | lib/librefuse/refuse_opt.c | 287 |
5 files changed, 358 insertions, 69 deletions
diff --git a/lib/librefuse/Makefile b/lib/librefuse/Makefile index 055a2330efb..7b3ead0de59 100644 --- a/lib/librefuse/Makefile +++ b/lib/librefuse/Makefile @@ -1,13 +1,18 @@ -# $NetBSD: Makefile,v 1.2 2007/02/16 15:44:37 pooka Exp $ +# $NetBSD: Makefile,v 1.3 2007/02/28 16:23:00 xtraeme Exp $ LIB= refuse LIBDPLIBS= puffs ${.CURDIR}/../libpuffs -SRCS= refuse.c +.ifdef DEBUG +FUSE_OPT_DEBUG_FLAGS= -g -DFUSE_OPT_DEBUG +.endif + +CFLAGS+= ${FUSE_OPT_DEBUG_FLAGS} +SRCS= refuse.c refuse_opt.c CPPFLAGS+= -I. MAN= refuse.3 WARNS= 4 -INCS= fuse.h +INCS= fuse.h fuse_opt.h INCSDIR= /usr/include .include <bsd.lib.mk> diff --git a/lib/librefuse/fuse.h b/lib/librefuse/fuse.h index d13de8d56b6..7df93da31e9 100644 --- a/lib/librefuse/fuse.h +++ b/lib/librefuse/fuse.h @@ -61,12 +61,6 @@ struct fuse_conn_info { uint32_t reserved[27]; }; -struct fuse_opt { - const char *templ; - uint32_t offset; - int32_t value; -}; - /* equivalent'ish of puffs_cc */ struct fuse_context { struct fuse *fuse; @@ -76,10 +70,6 @@ struct fuse_context { void *private_data; }; -#define FUSE_OPT_KEY(templ, key) { templ, -1U, key } - -#define FUSE_OPT_END { .templ = NULL } - /** * Argument list */ @@ -94,13 +84,6 @@ struct fuse_args { */ #define FUSE_ARGS_INIT(argc, argv) { argc, argv, 0 } -enum { - FUSE_OPT_KEY_OPT = -1, - FUSE_OPT_KEY_NONOPT = -2, - FUSE_OPT_KEY_KEEP = -3, - FUSE_OPT_KEY_DISCARD = -4 -}; - typedef struct puffs_fuse_dirh *fuse_dirh_t; typedef int (*fuse_fill_dir_t)(void *, const char *, const struct stat *, off_t); @@ -160,13 +143,6 @@ struct fuse_operations { }; -typedef int (*fuse_opt_proc_t)(void *, const char *, int, struct fuse_args *); - - -int fuse_opt_add_arg(struct fuse_args *, const char *); -void fuse_opt_free_args(struct fuse_args *); -int fuse_opt_parse(struct fuse_args *, void *, const struct fuse_opt *, fuse_opt_proc_t); - struct fuse_chan *fuse_mount(const char *, struct fuse_args *); struct fuse *fuse_new(struct fuse_chan *, struct fuse_args *, const struct fuse_operations *, size_t, void *); diff --git a/lib/librefuse/fuse_opt.h b/lib/librefuse/fuse_opt.h new file mode 100644 index 00000000000..f16e02d6a35 --- /dev/null +++ b/lib/librefuse/fuse_opt.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2007 Alistair Crooks. 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _FUSE_OPT_H_ +#define _FUSE_OPT_H_ + +#include <fuse.h> + +enum { + FUSE_OPT_KEY_OPT = -1, + FUSE_OPT_KEY_NONOPT = -2, + FUSE_OPT_KEY_KEEP = -3, + FUSE_OPT_KEY_DISCARD = -4 +}; + +struct fuse_opt { + const char *templ; + int32_t offset; + int32_t value; +}; + +#define FUSE_OPT_KEY(templ, key) { templ, -1U, key } +#define FUSE_OPT_END { .templ = NULL } + +typedef int (*fuse_opt_proc_t)(void *, const char *, int, struct fuse_args *); + + +int fuse_opt_add_arg(struct fuse_args *, const char *); +void fuse_opt_free_args(struct fuse_args *); +int fuse_opt_insert_arg(struct fuse_args *, int, const char *); +int fuse_opt_add_opt(char **, const char *); +int fuse_opt_parse(struct fuse_args *, void *, + const struct fuse_opt *, fuse_opt_proc_t); +int fuse_opt_match(const struct fuse_opt *, const char *); + +#endif /* _FUSE_OPT_H_ */ diff --git a/lib/librefuse/refuse.c b/lib/librefuse/refuse.c index 0e2013220c0..67417086777 100644 --- a/lib/librefuse/refuse.c +++ b/lib/librefuse/refuse.c @@ -1,4 +1,4 @@ -/* $NetBSD: refuse.c,v 1.39 2007/02/26 22:28:11 agc Exp $ */ +/* $NetBSD: refuse.c,v 1.40 2007/02/28 16:23:00 xtraeme Exp $ */ /* * Copyright © 2007 Alistair Crooks. All rights reserved. @@ -30,7 +30,7 @@ #include <sys/cdefs.h> #if !defined(lint) -__RCSID("$NetBSD: refuse.c,v 1.39 2007/02/26 22:28:11 agc Exp $"); +__RCSID("$NetBSD: refuse.c,v 1.40 2007/02/28 16:23:00 xtraeme Exp $"); #endif /* !lint */ #include <assert.h> @@ -213,38 +213,6 @@ puffs_fuse_dirfil(fuse_dirh_t h, const char *name, int type, ino_t ino) return fill_dirbuf(h, name, dino, dtype); } -int -fuse_opt_add_arg(struct fuse_args *args, const char *arg) -{ - char **oldargv; - int oldargc; - - if (args->allocated) { - RENEW(char *, args->argv, args->argc + 1, - "fuse_opt_add_arg1", return 0); - } else { - oldargv = args->argv; - oldargc = args->argc; - NEWARRAY(char *, args->argv, oldargc + 1, - "fuse_opt_add_arg2", return 0); - (void) memcpy(args->argv, oldargv, oldargc * sizeof(char *)); - args->allocated = 1; - } - args->argv[args->argc++] = strdup(arg); - return 1; -} - -void -fuse_opt_free_args(struct fuse_args *args) -{ - if (args && args->argv) { - int i; - for (i = 0; i < args->argc; i++) - FREE(args->argv[i]); - FREE(args->argv); - } -} - #define FUSE_ERR_UNLINK(fuse, file) if (fuse->op.unlink) fuse->op.unlink(file) #define FUSE_ERR_RMDIR(fuse, dir) if (fuse->op.rmdir) fuse->op.rmdir(dir) @@ -1159,14 +1127,6 @@ fuse_destroy(struct fuse *fuse) FREE(fuse); } -/* ARGSUSED0 */ -int -fuse_opt_parse(struct fuse_args *args, void *data, - const struct fuse_opt *opts, fuse_opt_proc_t proc) -{ - return 0; -} - /* XXX: threads */ struct fuse_context * fuse_get_context() diff --git a/lib/librefuse/refuse_opt.c b/lib/librefuse/refuse_opt.c new file mode 100644 index 00000000000..da9d0fe302e --- /dev/null +++ b/lib/librefuse/refuse_opt.c @@ -0,0 +1,287 @@ +/* $NetBSD: refuse_opt.c,v 1.1 2007/02/28 16:23:00 xtraeme Exp $ */ + +/*- + * Copyright (c) 2007 Juan Romero Pardines. + * 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. The name of the company nor the name of the author may be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/* + * TODO: + * * -oblah,foo... works, but the options are not enabled. + * * -ofoo=%s (accepts a string) or -ofoo=%u (int) is not + * supported for now. + * * void *data: how is it used? I think it's used to enable + * options or pass values for the matching options. + */ + +#include "defs.h" +#include "fuse.h" +#include "fuse_opt.h" + +#ifdef FUSE_OPT_DEBUG +#define DPRINTF(x) do { printf x; } while (0) +#else +#define DPRINTF(x) +#endif + +enum { + KEY_HELP, + KEY_VERBOSE, + KEY_VERSION +}; + +struct fuse_opt_option { + const struct fuse_opt *fop; + char *option; + int key; + void *data; +}; + +static int fuse_opt_popt(struct fuse_opt_option *, const struct fuse_opt *); + +/* + * Public API. + * + * The following functions always return 0: + * + * int fuse_opt_add_arg(struct fuse_args *, const char *); + * int fuse_opt_add_opt(char **, const char *); + * void fuse_opt_free_args(struct fuse_args *); + * int fuse_opt_insert_arg(struct fuse_args *, const char *); + * + * We implement the next ones: + * + * int fuse_opt_match(const struct fuse_opt *, const char *); + * int fuse_opt_parse(struct fuse_args *, void *, + * const struct fuse_opt *, fuse_opt_proc_t); + * + */ + +/* ARGSUSED */ +int +fuse_opt_add_arg(struct fuse_args *args, const char *arg) +{ + DPRINTF(("%s: arguments passed: [arg:%s]\n", __func__, arg)); + return EXIT_SUCCESS; +} + +/* ARGSUSED */ +void +fuse_opt_free_args(struct fuse_args *args) +{ + /* nada */ +} + +/* ARGSUSED */ +int +fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg) +{ + DPRINTF(("%s: arguments passed: [pos=%d] [arg=%s]\n", + __func__, pos, arg)); + return EXIT_SUCCESS; +} + +/* ARGSUSED */ +int fuse_opt_add_opt(char **opts, const char *opt) +{ + DPRINTF(("%s: arguments passed: [opts=%s] [opt=%s]\n", + __func__, *opts, opt)); + return EXIT_SUCCESS; +} + +/* + * Returns 0 if opt was matched with any option from opts, + * otherwise returns 1. + */ +int +fuse_opt_match(const struct fuse_opt *opts, const char *opt) +{ + while (opts++) { + if (strcmp(opt, opts->templ) == 0) + return EXIT_SUCCESS; + } + + return EXIT_FAILURE; +} + +/* + * Returns 0 if foo->option was matched with any option from opts, + * and sets the following on match: + * + * * foo->key is set to the foo->fop->value if offset == -1. + * * foo->fop points to the matched struct opts. + * + * otherwise returns 1. + */ +static int +fuse_opt_popt(struct fuse_opt_option *foo, const struct fuse_opt *opts) +{ + int i, found = 0; + char *match; + + if (!foo->option) { + (void)fprintf(stderr, "fuse: missing argument after -o\n"); + return EXIT_FAILURE; + } + /* + * iterate over argv and opts to see + * if there's a match with any template. + */ + for (match = strtok(foo->option, ","); + match; match = strtok(NULL, ",")) { + + DPRINTF(("%s: specified option='%s'\n", __func__, match)); + found = 0; + + for (i = 0; opts && opts->templ; opts++, i++) { + + DPRINTF(("%s: opts->templ='%s' opts->offset=%d " + "opts->value=%d\n", __func__, opts->templ, + opts->offset, opts->value)); + + /* option is ok */ + if (strcmp(match, opts->templ) == 0) { + DPRINTF(("%s: option matched='%s'\n", + __func__, match)); + found++; + /* + * our fop pointer now points + * to the matched struct opts. + */ + foo->fop = opts; + /* + * assign default key value, necessary for + * KEY_HELP, KEY_VERSION and KEY_VERBOSE. + */ + if (foo->fop->offset == -1) + foo->key = foo->fop->value; + /* reset counter */ + opts -= i; + break; + } + } + /* invalid option */ + if (!found) { + (void)fprintf(stderr, "fuse: '%s' is not a " + "valid option\n", match); + return EXIT_FAILURE; + } + } + + return EXIT_SUCCESS; +} + +int +fuse_opt_parse(struct fuse_args *args, void *data, + const struct fuse_opt *opts, fuse_opt_proc_t proc) +{ + struct fuse_opt_option foo; + char *buf; + int i, rv = EXIT_SUCCESS; + + if (!args || !args->argv || !args->argc || !proc) + return 0; + + if (args->argc == 1) + return proc(foo.data, *args->argv, FUSE_OPT_KEY_OPT, args); + + /* the real loop to process the arguments */ + for (i = 1; i < args->argc; i++) { + + /* assign current argv string */ + foo.option = buf = args->argv[i]; + + /* argvn != -foo... */ + if (buf[0] != '-') { + + foo.key = FUSE_OPT_KEY_NONOPT; + if ((rv = proc(foo.data, foo.option, foo.key, args))) + break; + + /* -o was specified... */ + } else if (buf[0] == '-' && buf[1] == 'o') { + + /* -oblah,foo... */ + if (buf[2]) { + /* skip -o */ + foo.option = args->argv[i] + 2; + /* -o blah,foo... */ + } else { + /* + * skip current argv and pass to the + * next one to parse the options. + */ + ++i; + foo.option = args->argv[i]; + } + + if ((rv = fuse_opt_popt(&foo, opts))) + break; + + /* help/version/verbose argument */ + } else if (buf[0] == '-' && buf[1] != 'o') { + /* + * check if the argument matches + * with any template in opts. + */ + if ((rv = fuse_opt_popt(&foo, opts))) { + break; + } else { + DPRINTF(("%s: foo.fop->templ='%s' " + "foo.fop->offset: %d " + "foo.fop->value: %d\n", + __func__, foo.fop->templ, + foo.fop->offset, foo.fop->value)); + + /* argument needs to be discarded */ + if (foo.key == FUSE_OPT_KEY_DISCARD) { + rv = EXIT_FAILURE; + break; + } + + /* process help/version argument */ + if (foo.key != KEY_VERBOSE && + foo.key != FUSE_OPT_KEY_KEEP) { + rv = proc(foo.data, foo.option, + foo.key, args); + break; + } else { + /* process verbose argument */ + if ((rv = proc(foo.data, foo.option, + foo.key, args))) + break; + } + } + /* unknown option, how could that happen? */ + } else { + DPRINTF(("%s: unknown option\n", __func__)); + rv = EXIT_FAILURE; + break; + } + } + + return rv; +} |
