rc.d: Improve dhclient script
[dragonfly.git] / sbin / mount_fuse / mount_fusefs.c
blobcce7b090ab15de68c7c1bed14e9fb42386703036
1 /*-
2 * Copyright (c) 2019 Tomohiro Kusumi <tkusumi@netbsd.org>
3 * Copyright (c) 2019 The DragonFly Project
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <vfs/fuse/fuse_mount.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <stdbool.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <getopt.h>
38 #include <mntopts.h>
39 #include <err.h>
41 #define MOPT_FUSE_LINUX_OPTS \
42 { "default_permissions", 0, FUSE_MOUNT_DEFAULT_PERMISSIONS, 1 }, \
43 { "allow_other", 0, FUSE_MOUNT_ALLOW_OTHER, 1 }, \
44 { "max_read=", 0, FUSE_MOUNT_MAX_READ, 1 }, \
45 { "subtype=", 0, FUSE_MOUNT_SUBTYPE, 1 }
47 /* XXX */
48 #define MOPT_FUSE_LINUX_IGNORE_OPTS \
49 { "fsname=", 0, 0, 1 }, \
50 { "fd=", 0, 0, 1 }, \
51 { "rootmode=", 0, 0, 1 }, \
52 { "user_id=", 0, 0, 1 }, \
53 { "group_id=", 0, 0, 1 }, \
55 { "auto_unmount", 0, 0, 1 }, \
56 { "blkdev", 0, 0, 1 }, \
57 { "blksize=", 0, 0, 1 }, \
58 { "context=", 0, 0, 1 }, \
59 { "fscontext=", 0, 0, 1 }, \
60 { "defcontext=", 0, 0, 1 }, \
61 { "rootcontext=", 0, 0, 1 }, \
62 { "user=", 0, 0, 1 }, \
63 { "-r", 0, 0, 1 }, \
64 { "ro", 0, 0, 1 }, \
65 { "rw", 0, 0, 1 }, \
66 { "suid", 0, 0, 1 }, \
67 { "nosuid", 0, 0, 1 }, \
68 { "dev", 0, 0, 1 }, \
69 { "nodev", 0, 0, 1 }, \
70 { "exec", 0, 0, 1 }, \
71 { "noexec", 0, 0, 1 }, \
72 { "async", 0, 0, 1 }, \
73 { "sync", 0, 0, 1 }, \
74 { "dirsync", 0, 0, 1 }, \
75 { "atime", 0, 0, 1 }, \
76 { "noatime", 0, 0, 1 }
78 static struct mntopt mopts[] = {
79 MOPT_FUSE_LINUX_OPTS,
80 MOPT_FUSE_LINUX_IGNORE_OPTS,
81 MOPT_STDOPTS,
82 MOPT_NULL
85 static void
86 usage(void)
88 fprintf(stderr, "usage: mount_fusefs [-o options] fd mountpoint\n");
89 exit(1);
92 static char*
93 get_optval(const char *ptr)
95 char *ret = strdup(ptr);
96 const char *end = strstr(ptr, ",");
98 if (!end)
99 return ret;
101 ret[(int)(end - ptr)] = '\0';
102 return ret;
106 * e.g.
107 * argv[0] = "mount_fusefs"
108 * argv[1] = "-o"
109 * argv[2] = "max_read=...,subtype=hello"
110 * argv[3] = "3"
111 * argv[4] = "/mnt/fuse"
112 * argv[5] = "(null)"
115 main(int argc, char **argv)
117 struct fuse_mount_info args;
118 struct vfsconf vfc;
119 struct stat st;
120 const char *fdstr, *mntpt;
121 char *ep, mntpath[MAXPATHLEN], fusedev[64];
122 int error, c, fd, mntflags;
124 mntflags = 0;
125 memset(&args, 0, sizeof(args));
127 while ((c = getopt_long(argc, argv, "ho:", NULL, NULL)) != -1) {
128 switch(c) {
129 case 'o':
130 getmntopts(optarg, mopts, &mntflags, &args.flags);
131 if (args.flags & FUSE_MOUNT_MAX_READ) {
132 char *p = strstr(optarg, "max_read=");
133 if (p) {
134 p = get_optval(p + 9);
135 args.max_read = strtol(p, NULL, 0);
136 free(p);
139 if (args.flags & FUSE_MOUNT_SUBTYPE) {
140 char *p = strstr(optarg, "subtype=");
141 if (p) {
142 p = get_optval(p + 8);
143 args.subtype = strdup(p);
144 free(p);
147 break;
148 case 'h':
149 default:
150 usage(); /* exit */
153 argc -= optind;
154 argv += optind;
156 if (argc < 2)
157 usage();
159 fdstr = argv[0];
160 mntpt = argv[1];
161 checkpath(mntpt, mntpath);
163 fd = strtol(fdstr, &ep, 10);
164 if (fd <= 0 || *ep != '\0')
165 err(1, "Invalid FUSE fd %s", fdstr);
167 if (fstat(fd, &st) == -1)
168 err(1, "Failed to stat FUSE fd %d", fd);
169 strcpy(fusedev, "/dev/");
170 devname_r(st.st_rdev, S_IFCHR, fusedev + strlen(fusedev),
171 sizeof(fusedev) - strlen(fusedev));
172 if (stat(fusedev, &st) == -1)
173 err(1, "Failed to stat FUSE device %s", fusedev);
174 if (strncmp(fusedev, "/dev/fuse", 9))
175 err(1, "Invalid FUSE device %s", fusedev);
176 args.fd = fd;
177 args.from = strdup(fusedev);
179 error = getvfsbyname("fuse", &vfc);
180 if (error && vfsisloadable("fuse")) {
181 if(vfsload("fuse"))
182 err(1, "vfsload(%s)", "fuse");
183 endvfsent();
184 error = getvfsbyname("fuse", &vfc);
186 if (error)
187 errx(1, "%s filesystem not available", "fuse");
189 if (mount(vfc.vfc_name, mntpath, mntflags, &args) == -1)
190 err(1, "mount");
192 return 0;