1*9e564957SAndroid Build Coastguard Worker /*
2*9e564957SAndroid Build Coastguard Worker FUSE: Filesystem in Userspace
3*9e564957SAndroid Build Coastguard Worker Copyright (C) 2001-2007 Miklos Szeredi <[email protected]>
4*9e564957SAndroid Build Coastguard Worker
5*9e564957SAndroid Build Coastguard Worker Architecture-independent mounting code.
6*9e564957SAndroid Build Coastguard Worker
7*9e564957SAndroid Build Coastguard Worker This program can be distributed under the terms of the GNU LGPLv2.
8*9e564957SAndroid Build Coastguard Worker See the file COPYING.LIB.
9*9e564957SAndroid Build Coastguard Worker */
10*9e564957SAndroid Build Coastguard Worker
11*9e564957SAndroid Build Coastguard Worker #include "fuse_config.h"
12*9e564957SAndroid Build Coastguard Worker #include "mount_util.h"
13*9e564957SAndroid Build Coastguard Worker
14*9e564957SAndroid Build Coastguard Worker #include <stdio.h>
15*9e564957SAndroid Build Coastguard Worker #include <unistd.h>
16*9e564957SAndroid Build Coastguard Worker #include <stdlib.h>
17*9e564957SAndroid Build Coastguard Worker #include <string.h>
18*9e564957SAndroid Build Coastguard Worker #include <signal.h>
19*9e564957SAndroid Build Coastguard Worker #include <dirent.h>
20*9e564957SAndroid Build Coastguard Worker #include <errno.h>
21*9e564957SAndroid Build Coastguard Worker #include <fcntl.h>
22*9e564957SAndroid Build Coastguard Worker #include <limits.h>
23*9e564957SAndroid Build Coastguard Worker #include <paths.h>
24*9e564957SAndroid Build Coastguard Worker #if !defined( __NetBSD__) && !defined(__FreeBSD__) && !defined(__DragonFly__) && !defined(__ANDROID__)
25*9e564957SAndroid Build Coastguard Worker #include <mntent.h>
26*9e564957SAndroid Build Coastguard Worker #else
27*9e564957SAndroid Build Coastguard Worker #define IGNORE_MTAB
28*9e564957SAndroid Build Coastguard Worker #endif
29*9e564957SAndroid Build Coastguard Worker #include <sys/stat.h>
30*9e564957SAndroid Build Coastguard Worker #include <sys/wait.h>
31*9e564957SAndroid Build Coastguard Worker
32*9e564957SAndroid Build Coastguard Worker #include "fuse_mount_compat.h"
33*9e564957SAndroid Build Coastguard Worker
34*9e564957SAndroid Build Coastguard Worker #include <sys/param.h>
35*9e564957SAndroid Build Coastguard Worker
36*9e564957SAndroid Build Coastguard Worker #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
37*9e564957SAndroid Build Coastguard Worker #define umount2(mnt, flags) unmount(mnt, ((flags) == 2) ? MNT_FORCE : 0)
38*9e564957SAndroid Build Coastguard Worker #endif
39*9e564957SAndroid Build Coastguard Worker
40*9e564957SAndroid Build Coastguard Worker #ifdef IGNORE_MTAB
41*9e564957SAndroid Build Coastguard Worker #define mtab_needs_update(mnt) 0
42*9e564957SAndroid Build Coastguard Worker #else
mtab_needs_update(const char * mnt)43*9e564957SAndroid Build Coastguard Worker static int mtab_needs_update(const char *mnt)
44*9e564957SAndroid Build Coastguard Worker {
45*9e564957SAndroid Build Coastguard Worker int res;
46*9e564957SAndroid Build Coastguard Worker struct stat stbuf;
47*9e564957SAndroid Build Coastguard Worker
48*9e564957SAndroid Build Coastguard Worker /* If mtab is within new mount, don't touch it */
49*9e564957SAndroid Build Coastguard Worker if (strncmp(mnt, _PATH_MOUNTED, strlen(mnt)) == 0 &&
50*9e564957SAndroid Build Coastguard Worker _PATH_MOUNTED[strlen(mnt)] == '/')
51*9e564957SAndroid Build Coastguard Worker return 0;
52*9e564957SAndroid Build Coastguard Worker
53*9e564957SAndroid Build Coastguard Worker /*
54*9e564957SAndroid Build Coastguard Worker * Skip mtab update if /etc/mtab:
55*9e564957SAndroid Build Coastguard Worker *
56*9e564957SAndroid Build Coastguard Worker * - doesn't exist,
57*9e564957SAndroid Build Coastguard Worker * - is on a read-only filesystem.
58*9e564957SAndroid Build Coastguard Worker */
59*9e564957SAndroid Build Coastguard Worker res = lstat(_PATH_MOUNTED, &stbuf);
60*9e564957SAndroid Build Coastguard Worker if (res == -1) {
61*9e564957SAndroid Build Coastguard Worker if (errno == ENOENT)
62*9e564957SAndroid Build Coastguard Worker return 0;
63*9e564957SAndroid Build Coastguard Worker } else {
64*9e564957SAndroid Build Coastguard Worker uid_t ruid;
65*9e564957SAndroid Build Coastguard Worker int err;
66*9e564957SAndroid Build Coastguard Worker
67*9e564957SAndroid Build Coastguard Worker ruid = getuid();
68*9e564957SAndroid Build Coastguard Worker if (ruid != 0)
69*9e564957SAndroid Build Coastguard Worker setreuid(0, -1);
70*9e564957SAndroid Build Coastguard Worker
71*9e564957SAndroid Build Coastguard Worker res = access(_PATH_MOUNTED, W_OK);
72*9e564957SAndroid Build Coastguard Worker err = (res == -1) ? errno : 0;
73*9e564957SAndroid Build Coastguard Worker if (ruid != 0)
74*9e564957SAndroid Build Coastguard Worker setreuid(ruid, -1);
75*9e564957SAndroid Build Coastguard Worker
76*9e564957SAndroid Build Coastguard Worker if (err == EROFS)
77*9e564957SAndroid Build Coastguard Worker return 0;
78*9e564957SAndroid Build Coastguard Worker }
79*9e564957SAndroid Build Coastguard Worker
80*9e564957SAndroid Build Coastguard Worker return 1;
81*9e564957SAndroid Build Coastguard Worker }
82*9e564957SAndroid Build Coastguard Worker #endif /* IGNORE_MTAB */
83*9e564957SAndroid Build Coastguard Worker
add_mount(const char * progname,const char * fsname,const char * mnt,const char * type,const char * opts)84*9e564957SAndroid Build Coastguard Worker static int add_mount(const char *progname, const char *fsname,
85*9e564957SAndroid Build Coastguard Worker const char *mnt, const char *type, const char *opts)
86*9e564957SAndroid Build Coastguard Worker {
87*9e564957SAndroid Build Coastguard Worker int res;
88*9e564957SAndroid Build Coastguard Worker int status;
89*9e564957SAndroid Build Coastguard Worker sigset_t blockmask;
90*9e564957SAndroid Build Coastguard Worker sigset_t oldmask;
91*9e564957SAndroid Build Coastguard Worker
92*9e564957SAndroid Build Coastguard Worker sigemptyset(&blockmask);
93*9e564957SAndroid Build Coastguard Worker sigaddset(&blockmask, SIGCHLD);
94*9e564957SAndroid Build Coastguard Worker res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
95*9e564957SAndroid Build Coastguard Worker if (res == -1) {
96*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno));
97*9e564957SAndroid Build Coastguard Worker return -1;
98*9e564957SAndroid Build Coastguard Worker }
99*9e564957SAndroid Build Coastguard Worker
100*9e564957SAndroid Build Coastguard Worker res = fork();
101*9e564957SAndroid Build Coastguard Worker if (res == -1) {
102*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
103*9e564957SAndroid Build Coastguard Worker goto out_restore;
104*9e564957SAndroid Build Coastguard Worker }
105*9e564957SAndroid Build Coastguard Worker if (res == 0) {
106*9e564957SAndroid Build Coastguard Worker char *env = NULL;
107*9e564957SAndroid Build Coastguard Worker
108*9e564957SAndroid Build Coastguard Worker sigprocmask(SIG_SETMASK, &oldmask, NULL);
109*9e564957SAndroid Build Coastguard Worker
110*9e564957SAndroid Build Coastguard Worker if(setuid(geteuid()) == -1) {
111*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: setuid: %s\n", progname, strerror(errno));
112*9e564957SAndroid Build Coastguard Worker res = -1;
113*9e564957SAndroid Build Coastguard Worker goto out_restore;
114*9e564957SAndroid Build Coastguard Worker }
115*9e564957SAndroid Build Coastguard Worker
116*9e564957SAndroid Build Coastguard Worker execle("/bin/mount", "/bin/mount", "--no-canonicalize", "-i",
117*9e564957SAndroid Build Coastguard Worker "-f", "-t", type, "-o", opts, fsname, mnt, NULL, &env);
118*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: failed to execute /bin/mount: %s\n",
119*9e564957SAndroid Build Coastguard Worker progname, strerror(errno));
120*9e564957SAndroid Build Coastguard Worker exit(1);
121*9e564957SAndroid Build Coastguard Worker }
122*9e564957SAndroid Build Coastguard Worker res = waitpid(res, &status, 0);
123*9e564957SAndroid Build Coastguard Worker if (res == -1)
124*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
125*9e564957SAndroid Build Coastguard Worker
126*9e564957SAndroid Build Coastguard Worker if (status != 0)
127*9e564957SAndroid Build Coastguard Worker res = -1;
128*9e564957SAndroid Build Coastguard Worker
129*9e564957SAndroid Build Coastguard Worker out_restore:
130*9e564957SAndroid Build Coastguard Worker sigprocmask(SIG_SETMASK, &oldmask, NULL);
131*9e564957SAndroid Build Coastguard Worker
132*9e564957SAndroid Build Coastguard Worker return res;
133*9e564957SAndroid Build Coastguard Worker }
134*9e564957SAndroid Build Coastguard Worker
fuse_mnt_add_mount(const char * progname,const char * fsname,const char * mnt,const char * type,const char * opts)135*9e564957SAndroid Build Coastguard Worker int fuse_mnt_add_mount(const char *progname, const char *fsname,
136*9e564957SAndroid Build Coastguard Worker const char *mnt, const char *type, const char *opts)
137*9e564957SAndroid Build Coastguard Worker {
138*9e564957SAndroid Build Coastguard Worker if (!mtab_needs_update(mnt))
139*9e564957SAndroid Build Coastguard Worker return 0;
140*9e564957SAndroid Build Coastguard Worker
141*9e564957SAndroid Build Coastguard Worker return add_mount(progname, fsname, mnt, type, opts);
142*9e564957SAndroid Build Coastguard Worker }
143*9e564957SAndroid Build Coastguard Worker
exec_umount(const char * progname,const char * rel_mnt,int lazy)144*9e564957SAndroid Build Coastguard Worker static int exec_umount(const char *progname, const char *rel_mnt, int lazy)
145*9e564957SAndroid Build Coastguard Worker {
146*9e564957SAndroid Build Coastguard Worker int res;
147*9e564957SAndroid Build Coastguard Worker int status;
148*9e564957SAndroid Build Coastguard Worker sigset_t blockmask;
149*9e564957SAndroid Build Coastguard Worker sigset_t oldmask;
150*9e564957SAndroid Build Coastguard Worker
151*9e564957SAndroid Build Coastguard Worker sigemptyset(&blockmask);
152*9e564957SAndroid Build Coastguard Worker sigaddset(&blockmask, SIGCHLD);
153*9e564957SAndroid Build Coastguard Worker res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
154*9e564957SAndroid Build Coastguard Worker if (res == -1) {
155*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno));
156*9e564957SAndroid Build Coastguard Worker return -1;
157*9e564957SAndroid Build Coastguard Worker }
158*9e564957SAndroid Build Coastguard Worker
159*9e564957SAndroid Build Coastguard Worker res = fork();
160*9e564957SAndroid Build Coastguard Worker if (res == -1) {
161*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
162*9e564957SAndroid Build Coastguard Worker goto out_restore;
163*9e564957SAndroid Build Coastguard Worker }
164*9e564957SAndroid Build Coastguard Worker if (res == 0) {
165*9e564957SAndroid Build Coastguard Worker char *env = NULL;
166*9e564957SAndroid Build Coastguard Worker
167*9e564957SAndroid Build Coastguard Worker sigprocmask(SIG_SETMASK, &oldmask, NULL);
168*9e564957SAndroid Build Coastguard Worker
169*9e564957SAndroid Build Coastguard Worker if(setuid(geteuid()) == -1) {
170*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: setuid: %s\n", progname, strerror(errno));
171*9e564957SAndroid Build Coastguard Worker res = -1;
172*9e564957SAndroid Build Coastguard Worker goto out_restore;
173*9e564957SAndroid Build Coastguard Worker }
174*9e564957SAndroid Build Coastguard Worker
175*9e564957SAndroid Build Coastguard Worker if (lazy) {
176*9e564957SAndroid Build Coastguard Worker execle("/bin/umount", "/bin/umount", "-i", rel_mnt,
177*9e564957SAndroid Build Coastguard Worker "-l", NULL, &env);
178*9e564957SAndroid Build Coastguard Worker } else {
179*9e564957SAndroid Build Coastguard Worker execle("/bin/umount", "/bin/umount", "-i", rel_mnt,
180*9e564957SAndroid Build Coastguard Worker NULL, &env);
181*9e564957SAndroid Build Coastguard Worker }
182*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: failed to execute /bin/umount: %s\n",
183*9e564957SAndroid Build Coastguard Worker progname, strerror(errno));
184*9e564957SAndroid Build Coastguard Worker exit(1);
185*9e564957SAndroid Build Coastguard Worker }
186*9e564957SAndroid Build Coastguard Worker res = waitpid(res, &status, 0);
187*9e564957SAndroid Build Coastguard Worker if (res == -1)
188*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
189*9e564957SAndroid Build Coastguard Worker
190*9e564957SAndroid Build Coastguard Worker if (status != 0) {
191*9e564957SAndroid Build Coastguard Worker res = -1;
192*9e564957SAndroid Build Coastguard Worker }
193*9e564957SAndroid Build Coastguard Worker
194*9e564957SAndroid Build Coastguard Worker out_restore:
195*9e564957SAndroid Build Coastguard Worker sigprocmask(SIG_SETMASK, &oldmask, NULL);
196*9e564957SAndroid Build Coastguard Worker return res;
197*9e564957SAndroid Build Coastguard Worker
198*9e564957SAndroid Build Coastguard Worker }
199*9e564957SAndroid Build Coastguard Worker
fuse_mnt_umount(const char * progname,const char * abs_mnt,const char * rel_mnt,int lazy)200*9e564957SAndroid Build Coastguard Worker int fuse_mnt_umount(const char *progname, const char *abs_mnt,
201*9e564957SAndroid Build Coastguard Worker const char *rel_mnt, int lazy)
202*9e564957SAndroid Build Coastguard Worker {
203*9e564957SAndroid Build Coastguard Worker int res;
204*9e564957SAndroid Build Coastguard Worker
205*9e564957SAndroid Build Coastguard Worker if (!mtab_needs_update(abs_mnt)) {
206*9e564957SAndroid Build Coastguard Worker res = umount2(rel_mnt, lazy ? 2 : 0);
207*9e564957SAndroid Build Coastguard Worker if (res == -1)
208*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: failed to unmount %s: %s\n",
209*9e564957SAndroid Build Coastguard Worker progname, abs_mnt, strerror(errno));
210*9e564957SAndroid Build Coastguard Worker return res;
211*9e564957SAndroid Build Coastguard Worker }
212*9e564957SAndroid Build Coastguard Worker
213*9e564957SAndroid Build Coastguard Worker return exec_umount(progname, rel_mnt, lazy);
214*9e564957SAndroid Build Coastguard Worker }
215*9e564957SAndroid Build Coastguard Worker
remove_mount(const char * progname,const char * mnt)216*9e564957SAndroid Build Coastguard Worker static int remove_mount(const char *progname, const char *mnt)
217*9e564957SAndroid Build Coastguard Worker {
218*9e564957SAndroid Build Coastguard Worker int res;
219*9e564957SAndroid Build Coastguard Worker int status;
220*9e564957SAndroid Build Coastguard Worker sigset_t blockmask;
221*9e564957SAndroid Build Coastguard Worker sigset_t oldmask;
222*9e564957SAndroid Build Coastguard Worker
223*9e564957SAndroid Build Coastguard Worker sigemptyset(&blockmask);
224*9e564957SAndroid Build Coastguard Worker sigaddset(&blockmask, SIGCHLD);
225*9e564957SAndroid Build Coastguard Worker res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
226*9e564957SAndroid Build Coastguard Worker if (res == -1) {
227*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno));
228*9e564957SAndroid Build Coastguard Worker return -1;
229*9e564957SAndroid Build Coastguard Worker }
230*9e564957SAndroid Build Coastguard Worker
231*9e564957SAndroid Build Coastguard Worker res = fork();
232*9e564957SAndroid Build Coastguard Worker if (res == -1) {
233*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
234*9e564957SAndroid Build Coastguard Worker goto out_restore;
235*9e564957SAndroid Build Coastguard Worker }
236*9e564957SAndroid Build Coastguard Worker if (res == 0) {
237*9e564957SAndroid Build Coastguard Worker char *env = NULL;
238*9e564957SAndroid Build Coastguard Worker
239*9e564957SAndroid Build Coastguard Worker sigprocmask(SIG_SETMASK, &oldmask, NULL);
240*9e564957SAndroid Build Coastguard Worker
241*9e564957SAndroid Build Coastguard Worker if(setuid(geteuid()) == -1) {
242*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: setuid: %s\n", progname, strerror(errno));
243*9e564957SAndroid Build Coastguard Worker res = -1;
244*9e564957SAndroid Build Coastguard Worker goto out_restore;
245*9e564957SAndroid Build Coastguard Worker }
246*9e564957SAndroid Build Coastguard Worker
247*9e564957SAndroid Build Coastguard Worker execle("/bin/umount", "/bin/umount", "--no-canonicalize", "-i",
248*9e564957SAndroid Build Coastguard Worker "--fake", mnt, NULL, &env);
249*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: failed to execute /bin/umount: %s\n",
250*9e564957SAndroid Build Coastguard Worker progname, strerror(errno));
251*9e564957SAndroid Build Coastguard Worker exit(1);
252*9e564957SAndroid Build Coastguard Worker }
253*9e564957SAndroid Build Coastguard Worker res = waitpid(res, &status, 0);
254*9e564957SAndroid Build Coastguard Worker if (res == -1)
255*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
256*9e564957SAndroid Build Coastguard Worker
257*9e564957SAndroid Build Coastguard Worker if (status != 0)
258*9e564957SAndroid Build Coastguard Worker res = -1;
259*9e564957SAndroid Build Coastguard Worker
260*9e564957SAndroid Build Coastguard Worker out_restore:
261*9e564957SAndroid Build Coastguard Worker sigprocmask(SIG_SETMASK, &oldmask, NULL);
262*9e564957SAndroid Build Coastguard Worker return res;
263*9e564957SAndroid Build Coastguard Worker }
264*9e564957SAndroid Build Coastguard Worker
fuse_mnt_remove_mount(const char * progname,const char * mnt)265*9e564957SAndroid Build Coastguard Worker int fuse_mnt_remove_mount(const char *progname, const char *mnt)
266*9e564957SAndroid Build Coastguard Worker {
267*9e564957SAndroid Build Coastguard Worker if (!mtab_needs_update(mnt))
268*9e564957SAndroid Build Coastguard Worker return 0;
269*9e564957SAndroid Build Coastguard Worker
270*9e564957SAndroid Build Coastguard Worker return remove_mount(progname, mnt);
271*9e564957SAndroid Build Coastguard Worker }
272*9e564957SAndroid Build Coastguard Worker
fuse_mnt_resolve_path(const char * progname,const char * orig)273*9e564957SAndroid Build Coastguard Worker char *fuse_mnt_resolve_path(const char *progname, const char *orig)
274*9e564957SAndroid Build Coastguard Worker {
275*9e564957SAndroid Build Coastguard Worker char buf[PATH_MAX];
276*9e564957SAndroid Build Coastguard Worker char *copy;
277*9e564957SAndroid Build Coastguard Worker char *dst;
278*9e564957SAndroid Build Coastguard Worker char *end;
279*9e564957SAndroid Build Coastguard Worker char *lastcomp;
280*9e564957SAndroid Build Coastguard Worker const char *toresolv;
281*9e564957SAndroid Build Coastguard Worker
282*9e564957SAndroid Build Coastguard Worker if (!orig[0]) {
283*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: invalid mountpoint '%s'\n", progname,
284*9e564957SAndroid Build Coastguard Worker orig);
285*9e564957SAndroid Build Coastguard Worker return NULL;
286*9e564957SAndroid Build Coastguard Worker }
287*9e564957SAndroid Build Coastguard Worker
288*9e564957SAndroid Build Coastguard Worker copy = strdup(orig);
289*9e564957SAndroid Build Coastguard Worker if (copy == NULL) {
290*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: failed to allocate memory\n", progname);
291*9e564957SAndroid Build Coastguard Worker return NULL;
292*9e564957SAndroid Build Coastguard Worker }
293*9e564957SAndroid Build Coastguard Worker
294*9e564957SAndroid Build Coastguard Worker toresolv = copy;
295*9e564957SAndroid Build Coastguard Worker lastcomp = NULL;
296*9e564957SAndroid Build Coastguard Worker for (end = copy + strlen(copy) - 1; end > copy && *end == '/'; end --);
297*9e564957SAndroid Build Coastguard Worker if (end[0] != '/') {
298*9e564957SAndroid Build Coastguard Worker char *tmp;
299*9e564957SAndroid Build Coastguard Worker end[1] = '\0';
300*9e564957SAndroid Build Coastguard Worker tmp = strrchr(copy, '/');
301*9e564957SAndroid Build Coastguard Worker if (tmp == NULL) {
302*9e564957SAndroid Build Coastguard Worker lastcomp = copy;
303*9e564957SAndroid Build Coastguard Worker toresolv = ".";
304*9e564957SAndroid Build Coastguard Worker } else {
305*9e564957SAndroid Build Coastguard Worker lastcomp = tmp + 1;
306*9e564957SAndroid Build Coastguard Worker if (tmp == copy)
307*9e564957SAndroid Build Coastguard Worker toresolv = "/";
308*9e564957SAndroid Build Coastguard Worker }
309*9e564957SAndroid Build Coastguard Worker if (strcmp(lastcomp, ".") == 0 || strcmp(lastcomp, "..") == 0) {
310*9e564957SAndroid Build Coastguard Worker lastcomp = NULL;
311*9e564957SAndroid Build Coastguard Worker toresolv = copy;
312*9e564957SAndroid Build Coastguard Worker }
313*9e564957SAndroid Build Coastguard Worker else if (tmp)
314*9e564957SAndroid Build Coastguard Worker tmp[0] = '\0';
315*9e564957SAndroid Build Coastguard Worker }
316*9e564957SAndroid Build Coastguard Worker if (realpath(toresolv, buf) == NULL) {
317*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: bad mount point %s: %s\n", progname, orig,
318*9e564957SAndroid Build Coastguard Worker strerror(errno));
319*9e564957SAndroid Build Coastguard Worker free(copy);
320*9e564957SAndroid Build Coastguard Worker return NULL;
321*9e564957SAndroid Build Coastguard Worker }
322*9e564957SAndroid Build Coastguard Worker if (lastcomp == NULL)
323*9e564957SAndroid Build Coastguard Worker dst = strdup(buf);
324*9e564957SAndroid Build Coastguard Worker else {
325*9e564957SAndroid Build Coastguard Worker dst = (char *) malloc(strlen(buf) + 1 + strlen(lastcomp) + 1);
326*9e564957SAndroid Build Coastguard Worker if (dst) {
327*9e564957SAndroid Build Coastguard Worker unsigned buflen = strlen(buf);
328*9e564957SAndroid Build Coastguard Worker if (buflen && buf[buflen-1] == '/')
329*9e564957SAndroid Build Coastguard Worker sprintf(dst, "%s%s", buf, lastcomp);
330*9e564957SAndroid Build Coastguard Worker else
331*9e564957SAndroid Build Coastguard Worker sprintf(dst, "%s/%s", buf, lastcomp);
332*9e564957SAndroid Build Coastguard Worker }
333*9e564957SAndroid Build Coastguard Worker }
334*9e564957SAndroid Build Coastguard Worker free(copy);
335*9e564957SAndroid Build Coastguard Worker if (dst == NULL)
336*9e564957SAndroid Build Coastguard Worker fprintf(stderr, "%s: failed to allocate memory\n", progname);
337*9e564957SAndroid Build Coastguard Worker return dst;
338*9e564957SAndroid Build Coastguard Worker }
339*9e564957SAndroid Build Coastguard Worker
fuse_mnt_check_fuseblk(void)340*9e564957SAndroid Build Coastguard Worker int fuse_mnt_check_fuseblk(void)
341*9e564957SAndroid Build Coastguard Worker {
342*9e564957SAndroid Build Coastguard Worker char buf[256];
343*9e564957SAndroid Build Coastguard Worker FILE *f = fopen("/proc/filesystems", "r");
344*9e564957SAndroid Build Coastguard Worker if (!f)
345*9e564957SAndroid Build Coastguard Worker return 1;
346*9e564957SAndroid Build Coastguard Worker
347*9e564957SAndroid Build Coastguard Worker while (fgets(buf, sizeof(buf), f))
348*9e564957SAndroid Build Coastguard Worker if (strstr(buf, "fuseblk\n")) {
349*9e564957SAndroid Build Coastguard Worker fclose(f);
350*9e564957SAndroid Build Coastguard Worker return 1;
351*9e564957SAndroid Build Coastguard Worker }
352*9e564957SAndroid Build Coastguard Worker
353*9e564957SAndroid Build Coastguard Worker fclose(f);
354*9e564957SAndroid Build Coastguard Worker return 0;
355*9e564957SAndroid Build Coastguard Worker }
356*9e564957SAndroid Build Coastguard Worker
fuse_mnt_parse_fuse_fd(const char * mountpoint)357*9e564957SAndroid Build Coastguard Worker int fuse_mnt_parse_fuse_fd(const char *mountpoint)
358*9e564957SAndroid Build Coastguard Worker {
359*9e564957SAndroid Build Coastguard Worker int fd = -1;
360*9e564957SAndroid Build Coastguard Worker int len = 0;
361*9e564957SAndroid Build Coastguard Worker
362*9e564957SAndroid Build Coastguard Worker if (sscanf(mountpoint, "/dev/fd/%u%n", &fd, &len) == 1 &&
363*9e564957SAndroid Build Coastguard Worker len == strlen(mountpoint)) {
364*9e564957SAndroid Build Coastguard Worker return fd;
365*9e564957SAndroid Build Coastguard Worker }
366*9e564957SAndroid Build Coastguard Worker
367*9e564957SAndroid Build Coastguard Worker return -1;
368*9e564957SAndroid Build Coastguard Worker }
369