xref: /haiku/src/add-ons/kernel/file_systems/userlandfs/server/fuse/fuse_config.c (revision b5067cdcbdd7ff92882fb25c7c48194b2b9e42b4)
139f2d9e6SIngo Weinhold /*
239f2d9e6SIngo Weinhold   FUSE: Filesystem in Userspace
339f2d9e6SIngo Weinhold   Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
439f2d9e6SIngo Weinhold 
539f2d9e6SIngo Weinhold   This program can be distributed under the terms of the GNU LGPLv2.
639f2d9e6SIngo Weinhold   See the file COPYING.LIB
739f2d9e6SIngo Weinhold */
839f2d9e6SIngo Weinhold 
939f2d9e6SIngo Weinhold #include "fuse_config.h"
1039f2d9e6SIngo Weinhold 
11*b5067cdcSRene Gollent #include <string.h>
1239f2d9e6SIngo Weinhold 
1339f2d9e6SIngo Weinhold enum {
14861dbb48SIngo Weinhold 	KEY_KERN_FLAG,
15861dbb48SIngo Weinhold 	KEY_KERN_OPT,
16861dbb48SIngo Weinhold 	KEY_FUSERMOUNT_OPT,
17861dbb48SIngo Weinhold 	KEY_SUBTYPE_OPT,
18861dbb48SIngo Weinhold 	KEY_MTAB_OPT,
19861dbb48SIngo Weinhold 	KEY_ALLOW_ROOT,
20861dbb48SIngo Weinhold 	KEY_RO,
2139f2d9e6SIngo Weinhold 	KEY_HELP,
22861dbb48SIngo Weinhold 	KEY_VERSION,
23861dbb48SIngo Weinhold };
24861dbb48SIngo Weinhold 
25861dbb48SIngo Weinhold struct mount_opts {
26861dbb48SIngo Weinhold 	int allow_other;
27861dbb48SIngo Weinhold 	int allow_root;
28861dbb48SIngo Weinhold 	int ishelp;
29861dbb48SIngo Weinhold 	int flags;
30861dbb48SIngo Weinhold 	int nonempty;
31861dbb48SIngo Weinhold 	int blkdev;
32861dbb48SIngo Weinhold 	char *fsname;
33861dbb48SIngo Weinhold 	char *subtype;
34861dbb48SIngo Weinhold 	char *subtype_opt;
35861dbb48SIngo Weinhold 	char *mtab_opts;
36861dbb48SIngo Weinhold 	char *fusermount_opts;
37861dbb48SIngo Weinhold 	char *kernel_opts;
3839f2d9e6SIngo Weinhold };
3939f2d9e6SIngo Weinhold 
4039f2d9e6SIngo Weinhold #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
4139f2d9e6SIngo Weinhold 
4239f2d9e6SIngo Weinhold static const struct fuse_opt fuse_lib_opts[] = {
4339f2d9e6SIngo Weinhold 	FUSE_OPT_KEY("-h",		      KEY_HELP),
4439f2d9e6SIngo Weinhold 	FUSE_OPT_KEY("--help",		      KEY_HELP),
4539f2d9e6SIngo Weinhold 	FUSE_OPT_KEY("debug",		      FUSE_OPT_KEY_KEEP),
4639f2d9e6SIngo Weinhold 	FUSE_OPT_KEY("-d",		      FUSE_OPT_KEY_KEEP),
4739f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("debug",		      debug, 1),
4839f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("-d",		      debug, 1),
4939f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("hard_remove",	      hard_remove, 1),
5039f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("use_ino",		      use_ino, 1),
5139f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("readdir_ino",	      readdir_ino, 1),
5239f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("direct_io",	      direct_io, 1),
5339f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("kernel_cache",	      kernel_cache, 1),
5439f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("auto_cache",	      auto_cache, 1),
5539f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("noauto_cache",	      auto_cache, 0),
5639f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("umask=",		      set_mode, 1),
5739f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("umask=%o",	      umask, 0),
5839f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("uid=",		      set_uid, 1),
5939f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("uid=%d",		      uid, 0),
6039f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("gid=",		      set_gid, 1),
6139f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("gid=%d",		      gid, 0),
6239f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("entry_timeout=%lf",     entry_timeout, 0),
6339f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("attr_timeout=%lf",      attr_timeout, 0),
6439f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("ac_attr_timeout=%lf",   ac_attr_timeout, 0),
6539f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("ac_attr_timeout=",      ac_attr_timeout_set, 1),
6639f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("negative_timeout=%lf",  negative_timeout, 0),
6739f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("intr",		      intr, 1),
6839f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("intr_signal=%d",	      intr_signal, 0),
6939f2d9e6SIngo Weinhold 	FUSE_LIB_OPT("modules=%s",	      modules, 0),
7039f2d9e6SIngo Weinhold 	FUSE_OPT_END
7139f2d9e6SIngo Weinhold };
7239f2d9e6SIngo Weinhold 
73861dbb48SIngo Weinhold #define FUSE_MOUNT_OPT(t, p) { t, offsetof(struct mount_opts, p), 1 }
74861dbb48SIngo Weinhold 
75861dbb48SIngo Weinhold static const struct fuse_opt fuse_mount_opts[] = {
76861dbb48SIngo Weinhold 	FUSE_MOUNT_OPT("allow_other",	    allow_other),
77861dbb48SIngo Weinhold 	FUSE_MOUNT_OPT("allow_root",	    allow_root),
78861dbb48SIngo Weinhold 	FUSE_MOUNT_OPT("nonempty",	    nonempty),
79861dbb48SIngo Weinhold 	FUSE_MOUNT_OPT("blkdev",	    blkdev),
80861dbb48SIngo Weinhold 	FUSE_MOUNT_OPT("fsname=%s",	    fsname),
81861dbb48SIngo Weinhold 	FUSE_MOUNT_OPT("subtype=%s",	    subtype),
82861dbb48SIngo Weinhold 	FUSE_OPT_KEY("allow_other",	    KEY_KERN_OPT),
83861dbb48SIngo Weinhold 	FUSE_OPT_KEY("allow_root",	    KEY_ALLOW_ROOT),
84861dbb48SIngo Weinhold 	FUSE_OPT_KEY("nonempty",	    KEY_FUSERMOUNT_OPT),
85861dbb48SIngo Weinhold 	FUSE_OPT_KEY("blkdev",		    KEY_FUSERMOUNT_OPT),
86861dbb48SIngo Weinhold 	FUSE_OPT_KEY("fsname=",		    KEY_FUSERMOUNT_OPT),
87861dbb48SIngo Weinhold 	FUSE_OPT_KEY("subtype=",	    KEY_SUBTYPE_OPT),
88861dbb48SIngo Weinhold 	FUSE_OPT_KEY("large_read",	    KEY_KERN_OPT),
89861dbb48SIngo Weinhold 	FUSE_OPT_KEY("blksize=",	    KEY_KERN_OPT),
90861dbb48SIngo Weinhold 	FUSE_OPT_KEY("default_permissions", KEY_KERN_OPT),
91861dbb48SIngo Weinhold 	FUSE_OPT_KEY("max_read=",	    KEY_KERN_OPT),
92861dbb48SIngo Weinhold 	FUSE_OPT_KEY("max_read=",	    FUSE_OPT_KEY_KEEP),
93861dbb48SIngo Weinhold 	FUSE_OPT_KEY("user=",		    KEY_MTAB_OPT),
94861dbb48SIngo Weinhold 	FUSE_OPT_KEY("-r",		    KEY_RO),
95861dbb48SIngo Weinhold 	FUSE_OPT_KEY("ro",		    KEY_KERN_FLAG),
96861dbb48SIngo Weinhold 	FUSE_OPT_KEY("rw",		    KEY_KERN_FLAG),
97861dbb48SIngo Weinhold 	FUSE_OPT_KEY("suid",		    KEY_KERN_FLAG),
98861dbb48SIngo Weinhold 	FUSE_OPT_KEY("nosuid",		    KEY_KERN_FLAG),
99861dbb48SIngo Weinhold 	FUSE_OPT_KEY("dev",		    KEY_KERN_FLAG),
100861dbb48SIngo Weinhold 	FUSE_OPT_KEY("nodev",		    KEY_KERN_FLAG),
101861dbb48SIngo Weinhold 	FUSE_OPT_KEY("exec",		    KEY_KERN_FLAG),
102861dbb48SIngo Weinhold 	FUSE_OPT_KEY("noexec",		    KEY_KERN_FLAG),
103861dbb48SIngo Weinhold 	FUSE_OPT_KEY("async",		    KEY_KERN_FLAG),
104861dbb48SIngo Weinhold 	FUSE_OPT_KEY("sync",		    KEY_KERN_FLAG),
105861dbb48SIngo Weinhold 	FUSE_OPT_KEY("dirsync",		    KEY_KERN_FLAG),
106861dbb48SIngo Weinhold 	FUSE_OPT_KEY("atime",		    KEY_KERN_FLAG),
107861dbb48SIngo Weinhold 	FUSE_OPT_KEY("noatime",		    KEY_KERN_FLAG),
108861dbb48SIngo Weinhold 	FUSE_OPT_KEY("-h",		    KEY_HELP),
109861dbb48SIngo Weinhold 	FUSE_OPT_KEY("--help",		    KEY_HELP),
110861dbb48SIngo Weinhold 	FUSE_OPT_KEY("-V",		    KEY_VERSION),
111861dbb48SIngo Weinhold 	FUSE_OPT_KEY("--version",	    KEY_VERSION),
112861dbb48SIngo Weinhold 	FUSE_OPT_END
113861dbb48SIngo Weinhold };
114861dbb48SIngo Weinhold 
11539f2d9e6SIngo Weinhold 
11639f2d9e6SIngo Weinhold static int
fuse_lib_opt_proc(void * data,const char * arg,int key,struct fuse_args * outargs)11739f2d9e6SIngo Weinhold fuse_lib_opt_proc(void *data, const char *arg, int key,
11839f2d9e6SIngo Weinhold 	struct fuse_args *outargs)
11939f2d9e6SIngo Weinhold {
12039f2d9e6SIngo Weinhold 	(void)data;
12139f2d9e6SIngo Weinhold 	(void)arg;
12239f2d9e6SIngo Weinhold 	(void)key;
12339f2d9e6SIngo Weinhold 	(void)outargs;
12439f2d9e6SIngo Weinhold 
12539f2d9e6SIngo Weinhold 	return 1;
12639f2d9e6SIngo Weinhold }
12739f2d9e6SIngo Weinhold 
12839f2d9e6SIngo Weinhold 
12939f2d9e6SIngo Weinhold int
fuse_parse_lib_config_args(struct fuse_args * args,struct fuse_config * config)130861dbb48SIngo Weinhold fuse_parse_lib_config_args(struct fuse_args* args, struct fuse_config* config)
13139f2d9e6SIngo Weinhold {
13239f2d9e6SIngo Weinhold 	return fuse_opt_parse(args, config, fuse_lib_opts, fuse_lib_opt_proc) == 0;
133a7731138SIngo Weinhold }
134a7731138SIngo Weinhold 
135a7731138SIngo Weinhold 
136a7731138SIngo Weinhold int
fuse_is_lib_option(const char * opt)137a7731138SIngo Weinhold fuse_is_lib_option(const char* opt)
138a7731138SIngo Weinhold {
139a7731138SIngo Weinhold 	return /*fuse_lowlevel_is_lib_option(opt) ||*/
140a7731138SIngo Weinhold 		fuse_opt_match(fuse_lib_opts, opt);
14139f2d9e6SIngo Weinhold }
142861dbb48SIngo Weinhold 
143861dbb48SIngo Weinhold 
144861dbb48SIngo Weinhold #if 0
145861dbb48SIngo Weinhold struct mount_flags {
146861dbb48SIngo Weinhold 	const char *opt;
147861dbb48SIngo Weinhold 	unsigned long flag;
148861dbb48SIngo Weinhold 	int on;
149861dbb48SIngo Weinhold };
150861dbb48SIngo Weinhold 
151861dbb48SIngo Weinhold static struct mount_flags mount_flags[] = {
152861dbb48SIngo Weinhold 	{"rw",	    MS_RDONLY,	    0},
153861dbb48SIngo Weinhold 	{"ro",	    MS_RDONLY,	    1},
154861dbb48SIngo Weinhold 	{"suid",    MS_NOSUID,	    0},
155861dbb48SIngo Weinhold 	{"nosuid",  MS_NOSUID,	    1},
156861dbb48SIngo Weinhold 	{"dev",	    MS_NODEV,	    0},
157861dbb48SIngo Weinhold 	{"nodev",   MS_NODEV,	    1},
158861dbb48SIngo Weinhold 	{"exec",    MS_NOEXEC,	    0},
159861dbb48SIngo Weinhold 	{"noexec",  MS_NOEXEC,	    1},
160861dbb48SIngo Weinhold 	{"async",   MS_SYNCHRONOUS, 0},
161861dbb48SIngo Weinhold 	{"sync",    MS_SYNCHRONOUS, 1},
162861dbb48SIngo Weinhold 	{"atime",   MS_NOATIME,	    0},
163861dbb48SIngo Weinhold 	{"noatime", MS_NOATIME,	    1},
164861dbb48SIngo Weinhold 	{"dirsync", MS_DIRSYNC,	    1},
165861dbb48SIngo Weinhold 	{NULL,	    0,		    0}
166861dbb48SIngo Weinhold };
167861dbb48SIngo Weinhold #endif	// 0
168861dbb48SIngo Weinhold 
set_mount_flag(const char * s,int * flags)169861dbb48SIngo Weinhold static void set_mount_flag(const char *s, int *flags)
170861dbb48SIngo Weinhold {
171861dbb48SIngo Weinhold #if 0
172861dbb48SIngo Weinhold 	int i;
173861dbb48SIngo Weinhold 
174861dbb48SIngo Weinhold 	for (i = 0; mount_flags[i].opt != NULL; i++) {
175861dbb48SIngo Weinhold 		const char *opt = mount_flags[i].opt;
176861dbb48SIngo Weinhold 		if (strcmp(opt, s) == 0) {
177861dbb48SIngo Weinhold 			if (mount_flags[i].on)
178861dbb48SIngo Weinhold 				*flags |= mount_flags[i].flag;
179861dbb48SIngo Weinhold 			else
180861dbb48SIngo Weinhold 				*flags &= ~mount_flags[i].flag;
181861dbb48SIngo Weinhold 			return;
182861dbb48SIngo Weinhold 		}
183861dbb48SIngo Weinhold 	}
184861dbb48SIngo Weinhold 	fprintf(stderr, "fuse: internal error, can't find mount flag\n");
185861dbb48SIngo Weinhold 	abort();
186861dbb48SIngo Weinhold #endif
187861dbb48SIngo Weinhold }
188861dbb48SIngo Weinhold 
fuse_mount_opt_proc(void * data,const char * arg,int key,struct fuse_args * outargs)189861dbb48SIngo Weinhold static int fuse_mount_opt_proc(void *data, const char *arg, int key,
190861dbb48SIngo Weinhold 			       struct fuse_args *outargs)
191861dbb48SIngo Weinhold {
192861dbb48SIngo Weinhold 	struct mount_opts *mo = data;
193861dbb48SIngo Weinhold 
194861dbb48SIngo Weinhold 	switch (key) {
195861dbb48SIngo Weinhold 	case KEY_ALLOW_ROOT:
196861dbb48SIngo Weinhold 		if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||
197861dbb48SIngo Weinhold 		    fuse_opt_add_arg(outargs, "-oallow_root") == -1)
198861dbb48SIngo Weinhold 			return -1;
199861dbb48SIngo Weinhold 		return 0;
200861dbb48SIngo Weinhold 
201861dbb48SIngo Weinhold 	case KEY_RO:
202861dbb48SIngo Weinhold 		arg = "ro";
203861dbb48SIngo Weinhold 		/* fall through */
204861dbb48SIngo Weinhold 	case KEY_KERN_FLAG:
205861dbb48SIngo Weinhold 		set_mount_flag(arg, &mo->flags);
206861dbb48SIngo Weinhold 		return 0;
207861dbb48SIngo Weinhold 
208861dbb48SIngo Weinhold 	case KEY_KERN_OPT:
209861dbb48SIngo Weinhold 		return fuse_opt_add_opt(&mo->kernel_opts, arg);
210861dbb48SIngo Weinhold 
211861dbb48SIngo Weinhold 	case KEY_FUSERMOUNT_OPT:
212861dbb48SIngo Weinhold 		return fuse_opt_add_opt(&mo->fusermount_opts, arg);
213861dbb48SIngo Weinhold 
214861dbb48SIngo Weinhold 	case KEY_SUBTYPE_OPT:
215861dbb48SIngo Weinhold 		return fuse_opt_add_opt(&mo->subtype_opt, arg);
216861dbb48SIngo Weinhold 
217861dbb48SIngo Weinhold 	case KEY_MTAB_OPT:
218861dbb48SIngo Weinhold 		return fuse_opt_add_opt(&mo->mtab_opts, arg);
219861dbb48SIngo Weinhold 
220861dbb48SIngo Weinhold 	case KEY_HELP:
221861dbb48SIngo Weinhold //		mount_help();
222861dbb48SIngo Weinhold 		mo->ishelp = 1;
223861dbb48SIngo Weinhold 		break;
224861dbb48SIngo Weinhold 
225861dbb48SIngo Weinhold 	case KEY_VERSION:
226861dbb48SIngo Weinhold //		mount_version();
227861dbb48SIngo Weinhold 		mo->ishelp = 1;
228861dbb48SIngo Weinhold 		break;
229861dbb48SIngo Weinhold 	}
230861dbb48SIngo Weinhold 	return 1;
231861dbb48SIngo Weinhold }
232861dbb48SIngo Weinhold 
233861dbb48SIngo Weinhold 
234861dbb48SIngo Weinhold int
fuse_parse_mount_config_args(struct fuse_args * args)235861dbb48SIngo Weinhold fuse_parse_mount_config_args(struct fuse_args* args)
236861dbb48SIngo Weinhold {
237861dbb48SIngo Weinhold 	struct mount_opts mo;
238861dbb48SIngo Weinhold 	memset(&mo, 0, sizeof(mo));
239861dbb48SIngo Weinhold 
240861dbb48SIngo Weinhold 	return args == 0
241861dbb48SIngo Weinhold 		|| fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == 0;
242861dbb48SIngo Weinhold }
243