xref: /haiku/src/add-ons/kernel/file_systems/userlandfs/server/fuse/fuse_config.c (revision 21258e2674226d6aa732321b6f8494841895af5f)
1 /*
2   FUSE: Filesystem in Userspace
3   Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
4 
5   This program can be distributed under the terms of the GNU LGPLv2.
6   See the file COPYING.LIB
7 */
8 
9 #include "fuse_config.h"
10 
11 #include <string.h>
12 
13 enum {
14 	KEY_KERN_FLAG,
15 	KEY_KERN_OPT,
16 	KEY_FUSERMOUNT_OPT,
17 	KEY_SUBTYPE_OPT,
18 	KEY_MTAB_OPT,
19 	KEY_ALLOW_ROOT,
20 	KEY_RO,
21 	KEY_HELP,
22 	KEY_VERSION,
23 };
24 
25 struct mount_opts {
26 	int allow_other;
27 	int allow_root;
28 	int ishelp;
29 	int flags;
30 	int nonempty;
31 	int blkdev;
32 	char *fsname;
33 	char *subtype;
34 	char *subtype_opt;
35 	char *mtab_opts;
36 	char *fusermount_opts;
37 	char *kernel_opts;
38 };
39 
40 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
41 
42 static const struct fuse_opt fuse_lib_opts[] = {
43 	FUSE_OPT_KEY("-h",		      KEY_HELP),
44 	FUSE_OPT_KEY("--help",		      KEY_HELP),
45 	FUSE_OPT_KEY("debug",		      FUSE_OPT_KEY_KEEP),
46 	FUSE_OPT_KEY("-d",		      FUSE_OPT_KEY_KEEP),
47 	FUSE_LIB_OPT("debug",		      debug, 1),
48 	FUSE_LIB_OPT("-d",		      debug, 1),
49 	FUSE_LIB_OPT("hard_remove",	      hard_remove, 1),
50 	FUSE_LIB_OPT("use_ino",		      use_ino, 1),
51 	FUSE_LIB_OPT("readdir_ino",	      readdir_ino, 1),
52 	FUSE_LIB_OPT("direct_io",	      direct_io, 1),
53 	FUSE_LIB_OPT("kernel_cache",	      kernel_cache, 1),
54 	FUSE_LIB_OPT("auto_cache",	      auto_cache, 1),
55 	FUSE_LIB_OPT("noauto_cache",	      auto_cache, 0),
56 	FUSE_LIB_OPT("umask=",		      set_mode, 1),
57 	FUSE_LIB_OPT("umask=%o",	      umask, 0),
58 	FUSE_LIB_OPT("uid=",		      set_uid, 1),
59 	FUSE_LIB_OPT("uid=%d",		      uid, 0),
60 	FUSE_LIB_OPT("gid=",		      set_gid, 1),
61 	FUSE_LIB_OPT("gid=%d",		      gid, 0),
62 	FUSE_LIB_OPT("entry_timeout=%lf",     entry_timeout, 0),
63 	FUSE_LIB_OPT("attr_timeout=%lf",      attr_timeout, 0),
64 	FUSE_LIB_OPT("ac_attr_timeout=%lf",   ac_attr_timeout, 0),
65 	FUSE_LIB_OPT("ac_attr_timeout=",      ac_attr_timeout_set, 1),
66 	FUSE_LIB_OPT("negative_timeout=%lf",  negative_timeout, 0),
67 	FUSE_LIB_OPT("intr",		      intr, 1),
68 	FUSE_LIB_OPT("intr_signal=%d",	      intr_signal, 0),
69 	FUSE_LIB_OPT("modules=%s",	      modules, 0),
70 	FUSE_OPT_END
71 };
72 
73 #define FUSE_MOUNT_OPT(t, p) { t, offsetof(struct mount_opts, p), 1 }
74 
75 static const struct fuse_opt fuse_mount_opts[] = {
76 	FUSE_MOUNT_OPT("allow_other",	    allow_other),
77 	FUSE_MOUNT_OPT("allow_root",	    allow_root),
78 	FUSE_MOUNT_OPT("nonempty",	    nonempty),
79 	FUSE_MOUNT_OPT("blkdev",	    blkdev),
80 	FUSE_MOUNT_OPT("fsname=%s",	    fsname),
81 	FUSE_MOUNT_OPT("subtype=%s",	    subtype),
82 	FUSE_OPT_KEY("allow_other",	    KEY_KERN_OPT),
83 	FUSE_OPT_KEY("allow_root",	    KEY_ALLOW_ROOT),
84 	FUSE_OPT_KEY("nonempty",	    KEY_FUSERMOUNT_OPT),
85 	FUSE_OPT_KEY("blkdev",		    KEY_FUSERMOUNT_OPT),
86 	FUSE_OPT_KEY("fsname=",		    KEY_FUSERMOUNT_OPT),
87 	FUSE_OPT_KEY("subtype=",	    KEY_SUBTYPE_OPT),
88 	FUSE_OPT_KEY("large_read",	    KEY_KERN_OPT),
89 	FUSE_OPT_KEY("blksize=",	    KEY_KERN_OPT),
90 	FUSE_OPT_KEY("default_permissions", KEY_KERN_OPT),
91 	FUSE_OPT_KEY("max_read=",	    KEY_KERN_OPT),
92 	FUSE_OPT_KEY("max_read=",	    FUSE_OPT_KEY_KEEP),
93 	FUSE_OPT_KEY("user=",		    KEY_MTAB_OPT),
94 	FUSE_OPT_KEY("-r",		    KEY_RO),
95 	FUSE_OPT_KEY("ro",		    KEY_KERN_FLAG),
96 	FUSE_OPT_KEY("rw",		    KEY_KERN_FLAG),
97 	FUSE_OPT_KEY("suid",		    KEY_KERN_FLAG),
98 	FUSE_OPT_KEY("nosuid",		    KEY_KERN_FLAG),
99 	FUSE_OPT_KEY("dev",		    KEY_KERN_FLAG),
100 	FUSE_OPT_KEY("nodev",		    KEY_KERN_FLAG),
101 	FUSE_OPT_KEY("exec",		    KEY_KERN_FLAG),
102 	FUSE_OPT_KEY("noexec",		    KEY_KERN_FLAG),
103 	FUSE_OPT_KEY("async",		    KEY_KERN_FLAG),
104 	FUSE_OPT_KEY("sync",		    KEY_KERN_FLAG),
105 	FUSE_OPT_KEY("dirsync",		    KEY_KERN_FLAG),
106 	FUSE_OPT_KEY("atime",		    KEY_KERN_FLAG),
107 	FUSE_OPT_KEY("noatime",		    KEY_KERN_FLAG),
108 	FUSE_OPT_KEY("-h",		    KEY_HELP),
109 	FUSE_OPT_KEY("--help",		    KEY_HELP),
110 	FUSE_OPT_KEY("-V",		    KEY_VERSION),
111 	FUSE_OPT_KEY("--version",	    KEY_VERSION),
112 	FUSE_OPT_END
113 };
114 
115 
116 static int
117 fuse_lib_opt_proc(void *data, const char *arg, int key,
118 	struct fuse_args *outargs)
119 {
120 	(void)data;
121 	(void)arg;
122 	(void)key;
123 	(void)outargs;
124 
125 	return 1;
126 }
127 
128 
129 int
130 fuse_parse_lib_config_args(struct fuse_args* args, struct fuse_config* config)
131 {
132 	return fuse_opt_parse(args, config, fuse_lib_opts, fuse_lib_opt_proc) == 0;
133 }
134 
135 
136 int
137 fuse_is_lib_option(const char* opt)
138 {
139 	return /*fuse_lowlevel_is_lib_option(opt) ||*/
140 		fuse_opt_match(fuse_lib_opts, opt);
141 }
142 
143 
144 #if 0
145 struct mount_flags {
146 	const char *opt;
147 	unsigned long flag;
148 	int on;
149 };
150 
151 static struct mount_flags mount_flags[] = {
152 	{"rw",	    MS_RDONLY,	    0},
153 	{"ro",	    MS_RDONLY,	    1},
154 	{"suid",    MS_NOSUID,	    0},
155 	{"nosuid",  MS_NOSUID,	    1},
156 	{"dev",	    MS_NODEV,	    0},
157 	{"nodev",   MS_NODEV,	    1},
158 	{"exec",    MS_NOEXEC,	    0},
159 	{"noexec",  MS_NOEXEC,	    1},
160 	{"async",   MS_SYNCHRONOUS, 0},
161 	{"sync",    MS_SYNCHRONOUS, 1},
162 	{"atime",   MS_NOATIME,	    0},
163 	{"noatime", MS_NOATIME,	    1},
164 	{"dirsync", MS_DIRSYNC,	    1},
165 	{NULL,	    0,		    0}
166 };
167 #endif	// 0
168 
169 static void set_mount_flag(const char *s, int *flags)
170 {
171 #if 0
172 	int i;
173 
174 	for (i = 0; mount_flags[i].opt != NULL; i++) {
175 		const char *opt = mount_flags[i].opt;
176 		if (strcmp(opt, s) == 0) {
177 			if (mount_flags[i].on)
178 				*flags |= mount_flags[i].flag;
179 			else
180 				*flags &= ~mount_flags[i].flag;
181 			return;
182 		}
183 	}
184 	fprintf(stderr, "fuse: internal error, can't find mount flag\n");
185 	abort();
186 #endif
187 }
188 
189 static int fuse_mount_opt_proc(void *data, const char *arg, int key,
190 			       struct fuse_args *outargs)
191 {
192 	struct mount_opts *mo = data;
193 
194 	switch (key) {
195 	case KEY_ALLOW_ROOT:
196 		if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||
197 		    fuse_opt_add_arg(outargs, "-oallow_root") == -1)
198 			return -1;
199 		return 0;
200 
201 	case KEY_RO:
202 		arg = "ro";
203 		/* fall through */
204 	case KEY_KERN_FLAG:
205 		set_mount_flag(arg, &mo->flags);
206 		return 0;
207 
208 	case KEY_KERN_OPT:
209 		return fuse_opt_add_opt(&mo->kernel_opts, arg);
210 
211 	case KEY_FUSERMOUNT_OPT:
212 		return fuse_opt_add_opt(&mo->fusermount_opts, arg);
213 
214 	case KEY_SUBTYPE_OPT:
215 		return fuse_opt_add_opt(&mo->subtype_opt, arg);
216 
217 	case KEY_MTAB_OPT:
218 		return fuse_opt_add_opt(&mo->mtab_opts, arg);
219 
220 	case KEY_HELP:
221 //		mount_help();
222 		mo->ishelp = 1;
223 		break;
224 
225 	case KEY_VERSION:
226 //		mount_version();
227 		mo->ishelp = 1;
228 		break;
229 	}
230 	return 1;
231 }
232 
233 
234 int
235 fuse_parse_mount_config_args(struct fuse_args* args)
236 {
237 	struct mount_opts mo;
238 	memset(&mo, 0, sizeof(mo));
239 
240 	return args == 0
241 		|| fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == 0;
242 }
243