summaryrefslogtreecommitdiff
path: root/lib/librefuse
diff options
context:
space:
mode:
authorxtraeme <xtraeme@NetBSD.org>2007-02-28 16:23:00 +0000
committerxtraeme <xtraeme@NetBSD.org>2007-02-28 16:23:00 +0000
commitc7b91b596f4f768d18c6157fc7b4ad57fa1da39a (patch)
treedd569968aead88e63421d315867c62977d6acdc8 /lib/librefuse
parentaba6b126c7318b25f05ffc5b1ba5cfa9a49001ec (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/Makefile11
-rw-r--r--lib/librefuse/fuse.h24
-rw-r--r--lib/librefuse/fuse_opt.h61
-rw-r--r--lib/librefuse/refuse.c44
-rw-r--r--lib/librefuse/refuse_opt.c287
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;
+}