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