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
fuse_lib_opt_proc(void * data,const char * arg,int key,struct fuse_args * outargs)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
fuse_parse_lib_config_args(struct fuse_args * args,struct fuse_config * config)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
fuse_is_lib_option(const char * opt)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
set_mount_flag(const char * s,int * flags)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
fuse_mount_opt_proc(void * data,const char * arg,int key,struct fuse_args * outargs)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
fuse_parse_mount_config_args(struct fuse_args * args)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