mirror of https://github.com/trapexit/mergerfs.git
Browse Source
Convert vendored/libfuse C sources to C++17
Convert vendored/libfuse C sources to C++17
Convert all C source files in vendored/libfuse/ to C++17: - lib/crc32b.c -> crc32b.cpp (const void* cast) - lib/fuse_opt.c -> fuse_opt.cpp (designated init, void* arithmetic) - lib/fuse_signals.c -> fuse_signals.cpp - lib/helper.c -> helper.cpp (void* data cast) - lib/mount.c -> mount.cpp (thin wrapper) - lib/mount_generic.c -> mount_generic.h (static inline, #pragma once) - lib/mount_bsd.c -> mount_bsd.h (static inline, #pragma once) - lib/mount_util.c -> mount_util.h (static inline, #pragma once) - util/fusermount.c -> fusermount.cpp - util/mount.mergerfs.c -> mount.mergerfs.cpp Key changes: - Replace C99 designated initializer in fuse_opt_parse with field-by-field init - Fix void* pointer arithmetic via char* base + offset pattern - All C-style (T*)voidptr casts replaced with static_cast/reinterpret_cast - Remove redundant #define _GNU_SOURCE (already in FUSE_FLAGS) - Wrap __clone2 declaration in extern "C" for ia64 path - Update Makefile: empty SRC_C, build utils with $(CXX) instead of $(CC) - Remove stale .c files now replaced by .cpp/.h counterparts All binaries build cleanly: mergerfs, mergerfs-fusermount, mount.mergerfsfixes
14 changed files with 391 additions and 714 deletions
-
15vendored/libfuse/Makefile
-
4vendored/libfuse/lib/crc32b.cpp
-
29vendored/libfuse/lib/fuse_opt.cpp
-
0vendored/libfuse/lib/fuse_signals.cpp
-
2vendored/libfuse/lib/helper.cpp
-
19vendored/libfuse/lib/mount.cpp
-
8vendored/libfuse/lib/mount.hpp
-
4vendored/libfuse/lib/mount_bsd.h
-
12vendored/libfuse/lib/mount_generic.h
-
331vendored/libfuse/lib/mount_util.c
-
325vendored/libfuse/lib/mount_util.h
-
20vendored/libfuse/util/fusermount.cpp
-
6vendored/libfuse/util/mount.mergerfs.cpp
-
330vendored/libfuse/util/mount_util.c
@ -0,0 +1,19 @@ |
|||
/*
|
|||
ISC License |
|||
|
|||
Copyright (c) 2019, Antonio SJ Musumeci <trapexit@spawn.link> |
|||
|
|||
Permission to use, copy, modify, and/or distribute this software for any |
|||
purpose with or without fee is hereby granted, provided that the above |
|||
copyright notice and this permission notice appear in all copies. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
|||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|||
*/ |
|||
|
|||
#include "mount.hpp"
|
|||
@ -1,331 +0,0 @@ |
|||
/* |
|||
FUSE: Filesystem in Userspace |
|||
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> |
|||
|
|||
This program can be distributed under the terms of the GNU LGPLv2. |
|||
See the file COPYING.LIB. |
|||
*/ |
|||
|
|||
#include "mount_util.h" |
|||
#include <stdio.h> |
|||
#include <unistd.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
#include <signal.h> |
|||
#include <dirent.h> |
|||
#include <errno.h> |
|||
#include <fcntl.h> |
|||
#include <limits.h> |
|||
#include <paths.h> |
|||
#ifndef __NetBSD__ |
|||
#include <mntent.h> |
|||
#endif |
|||
#include <sys/stat.h> |
|||
#include <sys/wait.h> |
|||
#include <sys/mount.h> |
|||
#include <sys/param.h> |
|||
|
|||
#ifdef __NetBSD__ |
|||
#define umount2(mnt, flags) unmount(mnt, (flags == 2) ? MNT_FORCE : 0) |
|||
#define mtab_needs_update(mnt) 0 |
|||
#else |
|||
static int mtab_needs_update(const char *mnt) |
|||
{ |
|||
int res; |
|||
struct stat stbuf; |
|||
|
|||
/* If mtab is within new mount, don't touch it */ |
|||
if (strncmp(mnt, _PATH_MOUNTED, strlen(mnt)) == 0 && |
|||
_PATH_MOUNTED[strlen(mnt)] == '/') |
|||
return 0; |
|||
|
|||
/* |
|||
* Skip mtab update if /etc/mtab: |
|||
* |
|||
* - doesn't exist, |
|||
* - is a symlink, |
|||
* - is on a read-only filesystem. |
|||
*/ |
|||
res = lstat(_PATH_MOUNTED, &stbuf); |
|||
if (res == -1) { |
|||
if (errno == ENOENT) |
|||
return 0; |
|||
} else { |
|||
uid_t ruid; |
|||
int err; |
|||
|
|||
if (S_ISLNK(stbuf.st_mode)) |
|||
return 0; |
|||
|
|||
ruid = getuid(); |
|||
if (ruid != 0) |
|||
setreuid(0, -1); |
|||
|
|||
res = access(_PATH_MOUNTED, W_OK); |
|||
err = (res == -1) ? errno : 0; |
|||
if (ruid != 0) |
|||
setreuid(ruid, -1); |
|||
|
|||
if (err == EROFS) |
|||
return 0; |
|||
} |
|||
|
|||
return 1; |
|||
} |
|||
#endif /* __NetBSD__ */ |
|||
|
|||
static int add_mount(const char *progname, const char *fsname, |
|||
const char *mnt, const char *type, const char *opts) |
|||
{ |
|||
int res; |
|||
int status; |
|||
sigset_t blockmask; |
|||
sigset_t oldmask; |
|||
|
|||
sigemptyset(&blockmask); |
|||
sigaddset(&blockmask, SIGCHLD); |
|||
res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); |
|||
if (res == -1) { |
|||
fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); |
|||
return -1; |
|||
} |
|||
|
|||
res = fork(); |
|||
if (res == -1) { |
|||
fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); |
|||
goto out_restore; |
|||
} |
|||
if (res == 0) { |
|||
char *env = NULL; |
|||
|
|||
sigprocmask(SIG_SETMASK, &oldmask, NULL); |
|||
setuid(geteuid()); |
|||
execle("/bin/mount", "/bin/mount", "--no-canonicalize", "-i", |
|||
"-f", "-t", type, "-o", opts, fsname, mnt, NULL, &env); |
|||
fprintf(stderr, "%s: failed to execute /bin/mount: %s\n", |
|||
progname, strerror(errno)); |
|||
exit(1); |
|||
} |
|||
res = waitpid(res, &status, 0); |
|||
if (res == -1) |
|||
fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); |
|||
|
|||
if (status != 0) |
|||
res = -1; |
|||
|
|||
out_restore: |
|||
sigprocmask(SIG_SETMASK, &oldmask, NULL); |
|||
|
|||
return res; |
|||
} |
|||
|
|||
int fuse_mnt_add_mount(const char *progname, const char *fsname, |
|||
const char *mnt, const char *type, const char *opts) |
|||
{ |
|||
if (!mtab_needs_update(mnt)) |
|||
return 0; |
|||
|
|||
return add_mount(progname, fsname, mnt, type, opts); |
|||
} |
|||
|
|||
static int exec_umount(const char *progname, const char *rel_mnt, int lazy) |
|||
{ |
|||
int res; |
|||
int status; |
|||
sigset_t blockmask; |
|||
sigset_t oldmask; |
|||
|
|||
sigemptyset(&blockmask); |
|||
sigaddset(&blockmask, SIGCHLD); |
|||
res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); |
|||
if (res == -1) { |
|||
fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); |
|||
return -1; |
|||
} |
|||
|
|||
res = fork(); |
|||
if (res == -1) { |
|||
fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); |
|||
goto out_restore; |
|||
} |
|||
if (res == 0) { |
|||
char *env = NULL; |
|||
|
|||
sigprocmask(SIG_SETMASK, &oldmask, NULL); |
|||
setuid(geteuid()); |
|||
if (lazy) { |
|||
execle("/bin/umount", "/bin/umount", "-i", rel_mnt, |
|||
"-l", NULL, &env); |
|||
} else { |
|||
execle("/bin/umount", "/bin/umount", "-i", rel_mnt, |
|||
NULL, &env); |
|||
} |
|||
fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", |
|||
progname, strerror(errno)); |
|||
exit(1); |
|||
} |
|||
res = waitpid(res, &status, 0); |
|||
if (res == -1) |
|||
fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); |
|||
|
|||
if (status != 0) { |
|||
res = -1; |
|||
} |
|||
|
|||
out_restore: |
|||
sigprocmask(SIG_SETMASK, &oldmask, NULL); |
|||
return res; |
|||
|
|||
} |
|||
|
|||
int fuse_mnt_umount(const char *progname, const char *abs_mnt, |
|||
const char *rel_mnt, int lazy) |
|||
{ |
|||
int res; |
|||
|
|||
if (!mtab_needs_update(abs_mnt)) { |
|||
res = umount2(rel_mnt, lazy ? MNT_DETACH : 0); |
|||
if (res == -1) |
|||
fprintf(stderr, "%s: failed to unmount %s: %s\n", |
|||
progname, abs_mnt, strerror(errno)); |
|||
return res; |
|||
} |
|||
|
|||
return exec_umount(progname, rel_mnt, lazy); |
|||
} |
|||
|
|||
static int remove_mount(const char *progname, const char *mnt) |
|||
{ |
|||
int res; |
|||
int status; |
|||
sigset_t blockmask; |
|||
sigset_t oldmask; |
|||
|
|||
sigemptyset(&blockmask); |
|||
sigaddset(&blockmask, SIGCHLD); |
|||
res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); |
|||
if (res == -1) { |
|||
fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); |
|||
return -1; |
|||
} |
|||
|
|||
res = fork(); |
|||
if (res == -1) { |
|||
fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); |
|||
goto out_restore; |
|||
} |
|||
if (res == 0) { |
|||
char *env = NULL; |
|||
|
|||
sigprocmask(SIG_SETMASK, &oldmask, NULL); |
|||
setuid(geteuid()); |
|||
execle("/bin/umount", "/bin/umount", "--no-canonicalize", "-i", |
|||
"--fake", mnt, NULL, &env); |
|||
fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", |
|||
progname, strerror(errno)); |
|||
exit(1); |
|||
} |
|||
res = waitpid(res, &status, 0); |
|||
if (res == -1) |
|||
fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); |
|||
|
|||
if (status != 0) |
|||
res = -1; |
|||
|
|||
out_restore: |
|||
sigprocmask(SIG_SETMASK, &oldmask, NULL); |
|||
return res; |
|||
} |
|||
|
|||
int fuse_mnt_remove_mount(const char *progname, const char *mnt) |
|||
{ |
|||
if (!mtab_needs_update(mnt)) |
|||
return 0; |
|||
|
|||
return remove_mount(progname, mnt); |
|||
} |
|||
|
|||
char *fuse_mnt_resolve_path(const char *progname, const char *orig) |
|||
{ |
|||
char buf[PATH_MAX]; |
|||
char *copy; |
|||
char *dst; |
|||
char *end; |
|||
char *lastcomp; |
|||
const char *toresolv; |
|||
|
|||
if (!orig[0]) { |
|||
fprintf(stderr, "%s: invalid mountpoint '%s'\n", progname, |
|||
orig); |
|||
return NULL; |
|||
} |
|||
|
|||
copy = strdup(orig); |
|||
if (copy == NULL) { |
|||
fprintf(stderr, "%s: failed to allocate memory\n", progname); |
|||
return NULL; |
|||
} |
|||
|
|||
toresolv = copy; |
|||
lastcomp = NULL; |
|||
for (end = copy + strlen(copy) - 1; end > copy && *end == '/'; end --); |
|||
if (end[0] != '/') { |
|||
char *tmp; |
|||
end[1] = '\0'; |
|||
tmp = strrchr(copy, '/'); |
|||
if (tmp == NULL) { |
|||
lastcomp = copy; |
|||
toresolv = "."; |
|||
} else { |
|||
lastcomp = tmp + 1; |
|||
if (tmp == copy) |
|||
toresolv = "/"; |
|||
} |
|||
if (strcmp(lastcomp, ".") == 0 || strcmp(lastcomp, "..") == 0) { |
|||
lastcomp = NULL; |
|||
toresolv = copy; |
|||
} |
|||
else if (tmp) |
|||
tmp[0] = '\0'; |
|||
} |
|||
if (realpath(toresolv, buf) == NULL) { |
|||
fprintf(stderr, "%s: bad mount point %s: %s\n", progname, orig, |
|||
strerror(errno)); |
|||
free(copy); |
|||
return NULL; |
|||
} |
|||
if (lastcomp == NULL) |
|||
dst = strdup(buf); |
|||
else { |
|||
unsigned buflen = strlen(buf); |
|||
size_t dstlen = buflen + 1 + strlen(lastcomp) + 1; |
|||
dst = (char *) malloc(dstlen); |
|||
if (dst) { |
|||
if (buflen && buf[buflen-1] == '/') |
|||
snprintf(dst, dstlen, "%s%s", buf, lastcomp); |
|||
else |
|||
snprintf(dst, dstlen, "%s/%s", buf, lastcomp); |
|||
} |
|||
} |
|||
free(copy); |
|||
if (dst == NULL) |
|||
fprintf(stderr, "%s: failed to allocate memory\n", progname); |
|||
return dst; |
|||
} |
|||
|
|||
int fuse_mnt_check_fuseblk(void) |
|||
{ |
|||
char buf[256]; |
|||
FILE *f = fopen("/proc/filesystems", "r"); |
|||
if (!f) |
|||
return 1; |
|||
|
|||
while (fgets(buf, sizeof(buf), f)) |
|||
if (strstr(buf, "fuseblk\n")) { |
|||
fclose(f); |
|||
return 1; |
|||
} |
|||
|
|||
fclose(f); |
|||
return 0; |
|||
} |
|||
@ -1,330 +0,0 @@ |
|||
/* |
|||
FUSE: Filesystem in Userspace |
|||
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> |
|||
|
|||
This program can be distributed under the terms of the GNU LGPLv2. |
|||
See the file COPYING.LIB. |
|||
*/ |
|||
|
|||
#include "mount_util.h" |
|||
#include <stdio.h> |
|||
#include <unistd.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
#include <signal.h> |
|||
#include <dirent.h> |
|||
#include <errno.h> |
|||
#include <fcntl.h> |
|||
#include <limits.h> |
|||
#include <paths.h> |
|||
#ifndef __NetBSD__ |
|||
#include <mntent.h> |
|||
#endif |
|||
#include <sys/stat.h> |
|||
#include <sys/wait.h> |
|||
#include <sys/mount.h> |
|||
#include <sys/param.h> |
|||
|
|||
#ifdef __NetBSD__ |
|||
#define umount2(mnt, flags) unmount(mnt, (flags == 2) ? MNT_FORCE : 0) |
|||
#define mtab_needs_update(mnt) 0 |
|||
#else |
|||
static int mtab_needs_update(const char *mnt) |
|||
{ |
|||
int res; |
|||
struct stat stbuf; |
|||
|
|||
/* If mtab is within new mount, don't touch it */ |
|||
if (strncmp(mnt, _PATH_MOUNTED, strlen(mnt)) == 0 && |
|||
_PATH_MOUNTED[strlen(mnt)] == '/') |
|||
return 0; |
|||
|
|||
/* |
|||
* Skip mtab update if /etc/mtab: |
|||
* |
|||
* - doesn't exist, |
|||
* - is a symlink, |
|||
* - is on a read-only filesystem. |
|||
*/ |
|||
res = lstat(_PATH_MOUNTED, &stbuf); |
|||
if (res == -1) { |
|||
if (errno == ENOENT) |
|||
return 0; |
|||
} else { |
|||
uid_t ruid; |
|||
int err; |
|||
|
|||
if (S_ISLNK(stbuf.st_mode)) |
|||
return 0; |
|||
|
|||
ruid = getuid(); |
|||
if (ruid != 0) |
|||
setreuid(0, -1); |
|||
|
|||
res = access(_PATH_MOUNTED, W_OK); |
|||
err = (res == -1) ? errno : 0; |
|||
if (ruid != 0) |
|||
setreuid(ruid, -1); |
|||
|
|||
if (err == EROFS) |
|||
return 0; |
|||
} |
|||
|
|||
return 1; |
|||
} |
|||
#endif /* __NetBSD__ */ |
|||
|
|||
static int add_mount(const char *progname, const char *fsname, |
|||
const char *mnt, const char *type, const char *opts) |
|||
{ |
|||
int res; |
|||
int status; |
|||
sigset_t blockmask; |
|||
sigset_t oldmask; |
|||
|
|||
sigemptyset(&blockmask); |
|||
sigaddset(&blockmask, SIGCHLD); |
|||
res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); |
|||
if (res == -1) { |
|||
fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); |
|||
return -1; |
|||
} |
|||
|
|||
res = fork(); |
|||
if (res == -1) { |
|||
fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); |
|||
goto out_restore; |
|||
} |
|||
if (res == 0) { |
|||
char *env = NULL; |
|||
|
|||
sigprocmask(SIG_SETMASK, &oldmask, NULL); |
|||
setuid(geteuid()); |
|||
execle("/bin/mount", "/bin/mount", "--no-canonicalize", "-i", |
|||
"-f", "-t", type, "-o", opts, fsname, mnt, NULL, &env); |
|||
fprintf(stderr, "%s: failed to execute /bin/mount: %s\n", |
|||
progname, strerror(errno)); |
|||
exit(1); |
|||
} |
|||
res = waitpid(res, &status, 0); |
|||
if (res == -1) |
|||
fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); |
|||
|
|||
if (status != 0) |
|||
res = -1; |
|||
|
|||
out_restore: |
|||
sigprocmask(SIG_SETMASK, &oldmask, NULL); |
|||
|
|||
return res; |
|||
} |
|||
|
|||
int fuse_mnt_add_mount(const char *progname, const char *fsname, |
|||
const char *mnt, const char *type, const char *opts) |
|||
{ |
|||
if (!mtab_needs_update(mnt)) |
|||
return 0; |
|||
|
|||
return add_mount(progname, fsname, mnt, type, opts); |
|||
} |
|||
|
|||
static int exec_umount(const char *progname, const char *rel_mnt, int lazy) |
|||
{ |
|||
int res; |
|||
int status; |
|||
sigset_t blockmask; |
|||
sigset_t oldmask; |
|||
|
|||
sigemptyset(&blockmask); |
|||
sigaddset(&blockmask, SIGCHLD); |
|||
res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); |
|||
if (res == -1) { |
|||
fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); |
|||
return -1; |
|||
} |
|||
|
|||
res = fork(); |
|||
if (res == -1) { |
|||
fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); |
|||
goto out_restore; |
|||
} |
|||
if (res == 0) { |
|||
char *env = NULL; |
|||
|
|||
sigprocmask(SIG_SETMASK, &oldmask, NULL); |
|||
setuid(geteuid()); |
|||
if (lazy) { |
|||
execle("/bin/umount", "/bin/umount", "-i", rel_mnt, |
|||
"-l", NULL, &env); |
|||
} else { |
|||
execle("/bin/umount", "/bin/umount", "-i", rel_mnt, |
|||
NULL, &env); |
|||
} |
|||
fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", |
|||
progname, strerror(errno)); |
|||
exit(1); |
|||
} |
|||
res = waitpid(res, &status, 0); |
|||
if (res == -1) |
|||
fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); |
|||
|
|||
if (status != 0) { |
|||
res = -1; |
|||
} |
|||
|
|||
out_restore: |
|||
sigprocmask(SIG_SETMASK, &oldmask, NULL); |
|||
return res; |
|||
|
|||
} |
|||
|
|||
int fuse_mnt_umount(const char *progname, const char *abs_mnt, |
|||
const char *rel_mnt, int lazy) |
|||
{ |
|||
int res; |
|||
|
|||
if (!mtab_needs_update(abs_mnt)) { |
|||
res = umount2(rel_mnt, lazy ? 2 : 0); |
|||
if (res == -1) |
|||
fprintf(stderr, "%s: failed to unmount %s: %s\n", |
|||
progname, abs_mnt, strerror(errno)); |
|||
return res; |
|||
} |
|||
|
|||
return exec_umount(progname, rel_mnt, lazy); |
|||
} |
|||
|
|||
static int remove_mount(const char *progname, const char *mnt) |
|||
{ |
|||
int res; |
|||
int status; |
|||
sigset_t blockmask; |
|||
sigset_t oldmask; |
|||
|
|||
sigemptyset(&blockmask); |
|||
sigaddset(&blockmask, SIGCHLD); |
|||
res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); |
|||
if (res == -1) { |
|||
fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); |
|||
return -1; |
|||
} |
|||
|
|||
res = fork(); |
|||
if (res == -1) { |
|||
fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); |
|||
goto out_restore; |
|||
} |
|||
if (res == 0) { |
|||
char *env = NULL; |
|||
|
|||
sigprocmask(SIG_SETMASK, &oldmask, NULL); |
|||
setuid(geteuid()); |
|||
execle("/bin/umount", "/bin/umount", "--no-canonicalize", "-i", |
|||
"--fake", mnt, NULL, &env); |
|||
fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", |
|||
progname, strerror(errno)); |
|||
exit(1); |
|||
} |
|||
res = waitpid(res, &status, 0); |
|||
if (res == -1) |
|||
fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); |
|||
|
|||
if (status != 0) |
|||
res = -1; |
|||
|
|||
out_restore: |
|||
sigprocmask(SIG_SETMASK, &oldmask, NULL); |
|||
return res; |
|||
} |
|||
|
|||
int fuse_mnt_remove_mount(const char *progname, const char *mnt) |
|||
{ |
|||
if (!mtab_needs_update(mnt)) |
|||
return 0; |
|||
|
|||
return remove_mount(progname, mnt); |
|||
} |
|||
|
|||
char *fuse_mnt_resolve_path(const char *progname, const char *orig) |
|||
{ |
|||
char buf[PATH_MAX]; |
|||
char *copy; |
|||
char *dst; |
|||
char *end; |
|||
char *lastcomp; |
|||
const char *toresolv; |
|||
|
|||
if (!orig[0]) { |
|||
fprintf(stderr, "%s: invalid mountpoint '%s'\n", progname, |
|||
orig); |
|||
return NULL; |
|||
} |
|||
|
|||
copy = strdup(orig); |
|||
if (copy == NULL) { |
|||
fprintf(stderr, "%s: failed to allocate memory\n", progname); |
|||
return NULL; |
|||
} |
|||
|
|||
toresolv = copy; |
|||
lastcomp = NULL; |
|||
for (end = copy + strlen(copy) - 1; end > copy && *end == '/'; end --); |
|||
if (end[0] != '/') { |
|||
char *tmp; |
|||
end[1] = '\0'; |
|||
tmp = strrchr(copy, '/'); |
|||
if (tmp == NULL) { |
|||
lastcomp = copy; |
|||
toresolv = "."; |
|||
} else { |
|||
lastcomp = tmp + 1; |
|||
if (tmp == copy) |
|||
toresolv = "/"; |
|||
} |
|||
if (strcmp(lastcomp, ".") == 0 || strcmp(lastcomp, "..") == 0) { |
|||
lastcomp = NULL; |
|||
toresolv = copy; |
|||
} |
|||
else if (tmp) |
|||
tmp[0] = '\0'; |
|||
} |
|||
if (realpath(toresolv, buf) == NULL) { |
|||
fprintf(stderr, "%s: bad mount point %s: %s\n", progname, orig, |
|||
strerror(errno)); |
|||
free(copy); |
|||
return NULL; |
|||
} |
|||
if (lastcomp == NULL) |
|||
dst = strdup(buf); |
|||
else { |
|||
dst = (char *) malloc(strlen(buf) + 1 + strlen(lastcomp) + 1); |
|||
if (dst) { |
|||
unsigned buflen = strlen(buf); |
|||
if (buflen && buf[buflen-1] == '/') |
|||
sprintf(dst, "%s%s", buf, lastcomp); |
|||
else |
|||
sprintf(dst, "%s/%s", buf, lastcomp); |
|||
} |
|||
} |
|||
free(copy); |
|||
if (dst == NULL) |
|||
fprintf(stderr, "%s: failed to allocate memory\n", progname); |
|||
return dst; |
|||
} |
|||
|
|||
int fuse_mnt_check_fuseblk(void) |
|||
{ |
|||
char buf[256]; |
|||
FILE *f = fopen("/proc/filesystems", "r"); |
|||
if (!f) |
|||
return 1; |
|||
|
|||
while (fgets(buf, sizeof(buf), f)) |
|||
if (strstr(buf, "fuseblk\n")) { |
|||
fclose(f); |
|||
return 1; |
|||
} |
|||
|
|||
fclose(f); |
|||
return 0; |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue