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