blob: bb8243c4c88fa61aebab409c54305d0573643f98 [file] [log] [blame]
Miklos Szeredicc8c9752001-11-21 10:03:39 +00001/*
2 FUSE: Filesystem in Userspace
Miklos Szeredi149f6072005-01-10 12:29:28 +00003 Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
Miklos Szeredicc8c9752001-11-21 10:03:39 +00004
Miklos Szeredi8b39a9f2002-10-25 12:41:16 +00005 This program can be distributed under the terms of the GNU LGPL.
6 See the file COPYING.LIB.
Miklos Szeredicc8c9752001-11-21 10:03:39 +00007*/
8
Miklos Szeredi178451d2005-08-15 13:19:07 +00009#include "fuse_i.h"
Miklos Szeredicc8c9752001-11-21 10:03:39 +000010
11#include <stdio.h>
12#include <stdlib.h>
Miklos Szeredicc8c9752001-11-21 10:03:39 +000013#include <unistd.h>
Miklos Szeredi0f48a262002-12-05 14:23:01 +000014#include <string.h>
Miklos Szeredicc8c9752001-11-21 10:03:39 +000015#include <limits.h>
16#include <signal.h>
Miklos Szeredicc8c9752001-11-21 10:03:39 +000017
Miklos Szeredie175fb72004-10-21 16:33:17 +000018static struct fuse *fuse_instance;
Miklos Szeredicc8c9752001-11-21 10:03:39 +000019
Miklos Szeredi5dc8a802004-10-21 09:35:10 +000020static void usage(const char *progname)
Miklos Szeredicc8c9752001-11-21 10:03:39 +000021{
Miklos Szeredi799993c2004-12-04 21:20:05 +000022 if (progname)
23 fprintf(stderr,
24 "usage: %s mountpoint [FUSE options]\n\n", progname);
25
Miklos Szeredie5183742005-02-02 11:14:04 +000026 fprintf(stderr,
Miklos Szeredi799993c2004-12-04 21:20:05 +000027 "FUSE options:\n"
Miklos Szeredifbb5c742005-02-09 15:47:51 +000028 " -d enable debug output (implies -f)\n"
29 " -f foreground operation\n"
Miklos Szeredib75d4b92005-10-11 10:12:08 +000030 " -s disable multi-threaded operation\n"
Miklos Szeredifbb5c742005-02-09 15:47:51 +000031 " -r mount read only (equivalent to '-o ro')\n"
32 " -o opt,[opt...] mount options\n"
33 " -h print help\n"
Miklos Szeredi307242f2004-01-26 11:28:44 +000034 "\n"
Miklos Szeredibd7661b2004-07-23 17:16:29 +000035 "Mount options:\n"
36 " default_permissions enable permission checking\n"
37 " allow_other allow access to other users\n"
Miklos Szeredi3c7d41b2005-01-09 20:05:27 +000038 " allow_root allow access to root\n"
Miklos Szeredibd7661b2004-07-23 17:16:29 +000039 " kernel_cache cache files in kernel\n"
40 " large_read issue large read requests (2.4 only)\n"
41 " direct_io use direct I/O\n"
42 " max_read=N set maximum size of read requests\n"
43 " hard_remove immediate removal (don't hide files)\n"
44 " debug enable debug output\n"
Miklos Szeredi830ef702005-02-10 19:39:34 +000045 " fsname=NAME set filesystem name in mtab\n"
Miklos Szeredi33be22d2005-05-27 09:12:43 +000046 " use_ino let filesystem set inode numbers\n"
47 " readdir_ino try to fill in d_ino in readdir\n"
Miklos Szeredi340d21f2005-07-06 10:07:52 +000048 " nonempty allow mounts over non-empty file/dir\n"
Miklos Szeredie331c4b2005-07-06 13:34:02 +000049 " umask=M set file permissions (octal)\n"
50 " uid=N set file owner\n"
51 " gid=N set file group\n"
Miklos Szeredi33be22d2005-05-27 09:12:43 +000052 );
Miklos Szeredicc8c9752001-11-21 10:03:39 +000053}
54
Miklos Szeredi5dc8a802004-10-21 09:35:10 +000055static void invalid_option(const char *argv[], int argctr)
Miklos Szeredi307242f2004-01-26 11:28:44 +000056{
Miklos Szeredi5dc8a802004-10-21 09:35:10 +000057 fprintf(stderr, "fuse: invalid option: %s\n\n", argv[argctr]);
Miklos Szeredid59bb9d2004-12-07 10:04:24 +000058 fprintf(stderr, "see `%s -h' for usage\n", argv[0]);
Miklos Szeredi307242f2004-01-26 11:28:44 +000059}
60
Miklos Szeredif6e0ec62005-08-03 09:11:06 +000061static void exit_handler(int sig)
Miklos Szeredicc8c9752001-11-21 10:03:39 +000062{
Miklos Szeredif6e0ec62005-08-03 09:11:06 +000063 (void) sig;
Miklos Szeredie175fb72004-10-21 16:33:17 +000064 if (fuse_instance != NULL)
65 fuse_exit(fuse_instance);
Miklos Szeredicc8c9752001-11-21 10:03:39 +000066}
67
Miklos Szeredif6e0ec62005-08-03 09:11:06 +000068static int set_one_signal_handler(int sig, void (*handler)(int))
Miklos Szeredicc8c9752001-11-21 10:03:39 +000069{
70 struct sigaction sa;
Miklos Szerediacb4d362004-07-02 16:20:45 +000071 struct sigaction old_sa;
Miklos Szeredicc8c9752001-11-21 10:03:39 +000072
Miklos Szeredie7d5d7d2004-07-16 18:27:50 +000073 memset(&sa, 0, sizeof(struct sigaction));
Miklos Szerediacb4d362004-07-02 16:20:45 +000074 sa.sa_handler = handler;
Miklos Szeredicc8c9752001-11-21 10:03:39 +000075 sigemptyset(&(sa.sa_mask));
76 sa.sa_flags = 0;
77
Miklos Szeredif6e0ec62005-08-03 09:11:06 +000078 if (sigaction(sig, NULL, &old_sa) == -1) {
Miklos Szerediacb4d362004-07-02 16:20:45 +000079 perror("FUSE: cannot get old signal handler");
Miklos Szeredi5dc8a802004-10-21 09:35:10 +000080 return -1;
Miklos Szeredicc8c9752001-11-21 10:03:39 +000081 }
Miklos Szeredie5183742005-02-02 11:14:04 +000082
Miklos Szerediacb4d362004-07-02 16:20:45 +000083 if (old_sa.sa_handler == SIG_DFL &&
Miklos Szeredif6e0ec62005-08-03 09:11:06 +000084 sigaction(sig, &sa, NULL) == -1) {
Miklos Szerediacb4d362004-07-02 16:20:45 +000085 perror("Cannot set signal handler");
Miklos Szeredi5dc8a802004-10-21 09:35:10 +000086 return -1;
Miklos Szerediacb4d362004-07-02 16:20:45 +000087 }
Miklos Szeredi5dc8a802004-10-21 09:35:10 +000088 return 0;
Miklos Szerediacb4d362004-07-02 16:20:45 +000089}
Miklos Szeredicc8c9752001-11-21 10:03:39 +000090
Miklos Szeredif6e0ec62005-08-03 09:11:06 +000091static int set_signal_handlers(void)
Miklos Szerediacb4d362004-07-02 16:20:45 +000092{
Miklos Szeredi5dc8a802004-10-21 09:35:10 +000093 if (set_one_signal_handler(SIGHUP, exit_handler) == -1 ||
94 set_one_signal_handler(SIGINT, exit_handler) == -1 ||
95 set_one_signal_handler(SIGTERM, exit_handler) == -1 ||
96 set_one_signal_handler(SIGPIPE, SIG_IGN) == -1)
97 return -1;
Miklos Szerediba1e2dc2004-09-16 08:43:24 +000098
Miklos Szerediff875352004-06-03 13:52:40 +000099 return 0;
100}
101
Miklos Szeredi0f62d722005-01-04 12:45:54 +0000102static int opt_member(const char *opts, const char *opt)
103{
104 const char *e, *s = opts;
105 int optlen = strlen(opt);
106 for (s = opts; s; s = e + 1) {
107 if(!(e = strchr(s, ',')))
108 break;
109 if (e - s == optlen && strncmp(s, opt, optlen) == 0)
110 return 1;
111 }
112 return (s && strcmp(s, opt) == 0);
113}
114
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000115static int add_option_to(const char *opt, char **optp)
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000116{
117 unsigned len = strlen(opt);
118 if (*optp) {
119 unsigned oldlen = strlen(*optp);
Miklos Szeredif6e0ec62005-08-03 09:11:06 +0000120 *optp = (char *) realloc(*optp, oldlen + 1 + len + 1);
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000121 if (*optp == NULL)
122 return -1;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000123 (*optp)[oldlen] = ',';
124 strcpy(*optp + oldlen + 1, opt);
125 } else {
Miklos Szeredif6e0ec62005-08-03 09:11:06 +0000126 *optp = (char *) malloc(len + 1);
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000127 if (*optp == NULL)
128 return -1;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000129 strcpy(*optp, opt);
130 }
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000131 return 0;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000132}
133
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000134static int add_options(char **lib_optp, char **kernel_optp, const char *opts)
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000135{
136 char *xopts = strdup(opts);
137 char *s = xopts;
138 char *opt;
Miklos Szeredic902a852005-07-07 12:35:37 +0000139 int has_allow_other = 0;
140 int has_allow_root = 0;
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000141
142 if (xopts == NULL) {
143 fprintf(stderr, "fuse: memory allocation failed\n");
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000144 return -1;
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000145 }
146
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000147 while((opt = strsep(&s, ",")) != NULL) {
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000148 int res;
Miklos Szeredi0111f9d2005-04-22 12:04:55 +0000149 if (fuse_is_lib_option(opt)) {
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000150 res = add_option_to(opt, lib_optp);
Miklos Szeredi0111f9d2005-04-22 12:04:55 +0000151 /* Compatibility hack */
Miklos Szeredic902a852005-07-07 12:35:37 +0000152 if (strcmp(opt, "allow_root") == 0 && res != -1) {
153 has_allow_root = 1;
Miklos Szeredi0111f9d2005-04-22 12:04:55 +0000154 res = add_option_to("allow_other", kernel_optp);
Miklos Szeredic902a852005-07-07 12:35:37 +0000155 }
Miklos Szeredi0111f9d2005-04-22 12:04:55 +0000156 }
Miklos Szeredic902a852005-07-07 12:35:37 +0000157 else {
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000158 res = add_option_to(opt, kernel_optp);
Miklos Szeredic902a852005-07-07 12:35:37 +0000159 if (strcmp(opt, "allow_other") == 0)
160 has_allow_other = 1;
161 }
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000162 if (res == -1) {
163 fprintf(stderr, "fuse: memory allocation failed\n");
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000164 return -1;
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000165 }
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000166 }
Miklos Szeredic902a852005-07-07 12:35:37 +0000167 if (has_allow_other && has_allow_root) {
168 fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
169 return -1;
170 }
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000171 free(xopts);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000172 return 0;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000173}
174
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000175static int fuse_parse_cmdline(int argc, const char *argv[], char **kernel_opts,
176 char **lib_opts, char **mountpoint,
177 int *multithreaded, int *background)
Miklos Szeredicc8c9752001-11-21 10:03:39 +0000178{
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000179 int res;
Miklos Szeredie970f302004-02-25 08:39:42 +0000180 int argctr;
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000181 const char *basename;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000182 char *fsname_opt;
Miklos Szeredie5183742005-02-02 11:14:04 +0000183
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000184 *kernel_opts = NULL;
185 *lib_opts = NULL;
186 *mountpoint = NULL;
187 *multithreaded = 1;
188 *background = 1;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000189
190 basename = strrchr(argv[0], '/');
191 if (basename == NULL)
192 basename = argv[0];
193 else if (basename[1] != '\0')
194 basename++;
195
Miklos Szeredif6e0ec62005-08-03 09:11:06 +0000196 fsname_opt = (char *) malloc(strlen(basename) + 64);
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000197 if (fsname_opt == NULL) {
198 fprintf(stderr, "fuse: memory allocation failed\n");
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000199 return -1;
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000200 }
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000201 sprintf(fsname_opt, "fsname=%s", basename);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000202 res = add_options(lib_opts, kernel_opts, fsname_opt);
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000203 free(fsname_opt);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000204 if (res == -1)
205 goto err;
Miklos Szeredie5183742005-02-02 11:14:04 +0000206
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000207 for (argctr = 1; argctr < argc; argctr ++) {
Miklos Szerediff875352004-06-03 13:52:40 +0000208 if (argv[argctr][0] == '-') {
209 if (strlen(argv[argctr]) == 2)
210 switch (argv[argctr][1]) {
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000211 case 'o':
212 if (argctr + 1 == argc || argv[argctr+1][0] == '-') {
Miklos Szeredi799993c2004-12-04 21:20:05 +0000213 fprintf(stderr, "missing option after -o\n");
Miklos Szeredid59bb9d2004-12-07 10:04:24 +0000214 fprintf(stderr, "see `%s -h' for usage\n", argv[0]);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000215 goto err;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000216 }
217 argctr ++;
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000218 res = add_options(lib_opts, kernel_opts, argv[argctr]);
219 if (res == -1)
220 goto err;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000221 break;
Miklos Szeredie5183742005-02-02 11:14:04 +0000222
Miklos Szeredie970f302004-02-25 08:39:42 +0000223 case 'd':
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000224 res = add_options(lib_opts, kernel_opts, "debug");
225 if (res == -1)
226 goto err;
Miklos Szeredie970f302004-02-25 08:39:42 +0000227 break;
Miklos Szeredie5183742005-02-02 11:14:04 +0000228
Miklos Szeredi96dfad72004-11-30 00:00:02 +0000229 case 'r':
230 res = add_options(lib_opts, kernel_opts, "ro");
231 if (res == -1)
232 goto err;
233 break;
234
Miklos Szerediff875352004-06-03 13:52:40 +0000235 case 'f':
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000236 *background = 0;
Miklos Szerediff875352004-06-03 13:52:40 +0000237 break;
238
Miklos Szeredie970f302004-02-25 08:39:42 +0000239 case 's':
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000240 *multithreaded = 0;
Miklos Szeredie970f302004-02-25 08:39:42 +0000241 break;
Miklos Szeredie5183742005-02-02 11:14:04 +0000242
Miklos Szeredie970f302004-02-25 08:39:42 +0000243 case 'h':
244 usage(argv[0]);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000245 goto err;
Miklos Szeredie5183742005-02-02 11:14:04 +0000246
Miklos Szeredie970f302004-02-25 08:39:42 +0000247 default:
248 invalid_option(argv, argctr);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000249 goto err;
Miklos Szeredie970f302004-02-25 08:39:42 +0000250 }
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000251 else {
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000252 if (argv[argctr][1] == 'o') {
253 res = add_options(lib_opts, kernel_opts, &argv[argctr][2]);
254 if (res == -1)
255 goto err;
Miklos Szeredi799993c2004-12-04 21:20:05 +0000256 } else if(strcmp(argv[argctr], "-ho") == 0) {
257 usage(NULL);
258 goto err;
259 } else {
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000260 invalid_option(argv, argctr);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000261 goto err;
262 }
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000263 }
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000264 } else if (*mountpoint == NULL) {
265 *mountpoint = strdup(argv[argctr]);
266 if (*mountpoint == NULL) {
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000267 fprintf(stderr, "fuse: memory allocation failed\n");
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000268 goto err;
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000269 }
270 }
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000271 else {
Miklos Szeredi307242f2004-01-26 11:28:44 +0000272 invalid_option(argv, argctr);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000273 goto err;
274 }
Miklos Szeredi307242f2004-01-26 11:28:44 +0000275 }
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000276 return 0;
Miklos Szeredicc8c9752001-11-21 10:03:39 +0000277
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000278 err:
279 free(*kernel_opts);
280 free(*lib_opts);
281 free(*mountpoint);
282 return -1;
283}
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000284
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000285static struct fuse *fuse_setup_common(int argc, char *argv[],
286 const struct fuse_operations *op,
287 size_t op_size,
288 char **mountpoint,
289 int *multithreaded,
290 int *fd,
291 int compat)
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000292{
293 struct fuse *fuse;
294 int background;
295 char *kernel_opts;
296 char *lib_opts;
297 int res;
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000298
Miklos Szeredie175fb72004-10-21 16:33:17 +0000299 if (fuse_instance != NULL) {
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000300 fprintf(stderr, "fuse: fuse_setup() called twice\n");
Miklos Szeredie175fb72004-10-21 16:33:17 +0000301 return NULL;
302 }
303
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000304 res = fuse_parse_cmdline(argc, (const char **) argv, &kernel_opts,
305 &lib_opts, mountpoint, multithreaded,
306 &background);
307 if (res == -1)
308 return NULL;
309
310 *fd = fuse_mount(*mountpoint, kernel_opts);
311 if (*fd == -1)
312 goto err_free;
313
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000314 fuse = fuse_new_common(*fd, lib_opts, op, op_size, compat);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000315 if (fuse == NULL)
316 goto err_unmount;
317
Miklos Szeredi0f62d722005-01-04 12:45:54 +0000318 if (background && !opt_member(lib_opts, "debug")) {
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000319 res = daemon(0, 0);
320 if (res == -1) {
321 perror("fuse: failed to daemonize program\n");
322 goto err_destroy;
323 }
324 }
Miklos Szeredie175fb72004-10-21 16:33:17 +0000325
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000326 res = set_signal_handlers();
327 if (res == -1)
328 goto err_destroy;
329
Miklos Szeredicc82a8c2004-10-21 16:39:09 +0000330 fuse_instance = fuse;
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000331 free(kernel_opts);
332 free(lib_opts);
333 return fuse;
334
335 err_destroy:
336 fuse_destroy(fuse);
337 err_unmount:
338 fuse_unmount(*mountpoint);
339 err_free:
340 free(kernel_opts);
341 free(lib_opts);
342 free(*mountpoint);
343 return NULL;
344}
345
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000346struct fuse *fuse_setup(int argc, char *argv[],
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000347 const struct fuse_operations *op,
348 size_t op_size, char **mountpoint,
349 int *multithreaded, int *fd)
350{
351 return fuse_setup_common(argc, argv, op, op_size, mountpoint,
352 multithreaded, fd, 0);
353}
354
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000355void fuse_teardown(struct fuse *fuse, int fd, char *mountpoint)
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000356{
Miklos Szeredibcc53852005-11-10 09:54:41 +0000357 (void) fd;
358
Miklos Szeredie175fb72004-10-21 16:33:17 +0000359 if (fuse_instance != fuse)
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000360 fprintf(stderr, "fuse: fuse_teardown() with unknown fuse object\n");
Miklos Szeredie175fb72004-10-21 16:33:17 +0000361 else
362 fuse_instance = NULL;
363
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000364 fuse_unmount(mountpoint);
Miklos Szeredib3f99722005-11-16 13:00:24 +0000365 fuse_destroy(fuse);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000366 free(mountpoint);
367}
368
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000369static int fuse_main_common(int argc, char *argv[],
370 const struct fuse_operations *op, size_t op_size,
371 int compat)
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000372{
Miklos Szeredie175fb72004-10-21 16:33:17 +0000373 struct fuse *fuse;
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000374 char *mountpoint;
375 int multithreaded;
376 int res;
377 int fd;
378
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000379 fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint,
380 &multithreaded, &fd, compat);
Miklos Szeredie175fb72004-10-21 16:33:17 +0000381 if (fuse == NULL)
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000382 return 1;
Miklos Szeredie5183742005-02-02 11:14:04 +0000383
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000384 if (multithreaded)
Miklos Szeredie175fb72004-10-21 16:33:17 +0000385 res = fuse_loop_mt(fuse);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000386 else
Miklos Szeredie175fb72004-10-21 16:33:17 +0000387 res = fuse_loop(fuse);
Miklos Szeredie5183742005-02-02 11:14:04 +0000388
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000389 fuse_teardown(fuse, fd, mountpoint);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000390 if (res == -1)
391 return 1;
Miklos Szeredie5183742005-02-02 11:14:04 +0000392
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000393 return 0;
Miklos Szeredicc8c9752001-11-21 10:03:39 +0000394}
395
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000396int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
397 size_t op_size)
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000398{
399 return fuse_main_common(argc, argv, op, op_size, 0);
400}
401
Miklos Szeredi9c2ccb42005-11-17 17:11:48 +0000402#undef fuse_main
403int fuse_main(void)
404{
405 fprintf(stderr, "fuse_main(): This function does not exist\n");
406 return -1;
407}
408
409#ifndef __FreeBSD__
410
411#include "fuse_compat.h"
412
413struct fuse *fuse_setup_compat22(int argc, char *argv[],
414 const struct fuse_operations_compat22 *op,
415 size_t op_size, char **mountpoint,
416 int *multithreaded, int *fd)
417{
418 return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
419 op_size, mountpoint, multithreaded, fd, 22);
420}
421
422struct fuse *fuse_setup_compat2(int argc, char *argv[],
423 const struct fuse_operations_compat2 *op,
424 char **mountpoint, int *multithreaded,
425 int *fd)
426{
427 return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
428 sizeof(struct fuse_operations_compat2),
429 mountpoint, multithreaded, fd, 21);
430}
431
Miklos Szeredi3a770472005-11-11 21:32:42 +0000432int fuse_main_real_compat22(int argc, char *argv[],
433 const struct fuse_operations_compat22 *op,
434 size_t op_size)
435{
436 return fuse_main_common(argc, argv, (struct fuse_operations *) op,
437 op_size, 22);
438}
439
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000440void fuse_main_compat1(int argc, char *argv[],
441 const struct fuse_operations_compat1 *op)
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000442{
Miklos Szeredie5183742005-02-02 11:14:04 +0000443 fuse_main_common(argc, argv, (struct fuse_operations *) op,
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000444 sizeof(struct fuse_operations_compat1), 11);
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000445}
446
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000447int fuse_main_compat2(int argc, char *argv[],
448 const struct fuse_operations_compat2 *op)
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000449{
450 return fuse_main_common(argc, argv, (struct fuse_operations *) op,
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000451 sizeof(struct fuse_operations_compat2), 21);
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000452}
453
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000454__asm__(".symver fuse_setup_compat2,__fuse_setup@");
Miklos Szeredi3a770472005-11-11 21:32:42 +0000455__asm__(".symver fuse_setup_compat22,fuse_setup@FUSE_2.2");
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000456__asm__(".symver fuse_teardown,__fuse_teardown@");
457__asm__(".symver fuse_main_compat2,fuse_main@");
Miklos Szeredi3a770472005-11-11 21:32:42 +0000458__asm__(".symver fuse_main_real_compat22,fuse_main_real@FUSE_2.2");
Miklos Szeredi9c2ccb42005-11-17 17:11:48 +0000459
460#endif /* __FreeBSD__ */