diff --git a/vendored/libfuse/lib/helper.cpp b/vendored/libfuse/lib/helper.cpp index 1c162700..9dad6abb 100644 --- a/vendored/libfuse/lib/helper.cpp +++ b/vendored/libfuse/lib/helper.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -86,24 +87,14 @@ fuse_helper_opt_proc(void *data, static int add_default_subtype(const char *progname, struct fuse_args *args) { - int res; - char *subtype_opt; const char *basename = strrchr(progname, '/'); if (basename == NULL) basename = progname; else if (basename[1] != '\0') basename++; - size_t optlen = strlen(basename) + 64; - subtype_opt = (char *) malloc(optlen); - if (subtype_opt == NULL) { - fprintf(stderr, "fuse: memory allocation failed\n"); - return -1; - } - snprintf(subtype_opt, optlen, "-osubtype=%s", basename); - res = fuse_opt_add_arg(args, subtype_opt); - free(subtype_opt); - return res; + std::string subtype_opt = "-osubtype=" + std::string(basename); + return fuse_opt_add_arg(args, subtype_opt.c_str()); } int diff --git a/vendored/libfuse/lib/mount_generic.h b/vendored/libfuse/lib/mount_generic.h index a1849ddc..357f39e9 100644 --- a/vendored/libfuse/lib/mount_generic.h +++ b/vendored/libfuse/lib/mount_generic.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -407,8 +408,8 @@ fuse_mount_sys(const char *mnt, { char tmp[128]; const char *devname = "/dev/fuse"; - char *source = NULL; - char *type = NULL; + std::string source; + std::string type; struct stat stbuf; int fd; int res; @@ -478,36 +479,23 @@ fuse_mount_sys(const char *mnt, if (res == -1) goto out_close; - source = static_cast(malloc((mo->fsname ? strlen(mo->fsname) : 0) + - (mo->subtype ? strlen(mo->subtype) : 0) + - strlen(devname) + 32)); + type = mo->blkdev ? "fuseblk" : "fuse"; + if (mo->subtype) + type += "." + std::string(mo->subtype); - type = static_cast(malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32)); - if (!type || !source) { - fprintf(stderr, "mergerfs: failed to allocate memory\n"); - goto out_close; - } - - strcpy(type, mo->blkdev ? "fuseblk" : "fuse"); - if (mo->subtype) { - strcat(type, "."); - strcat(type, mo->subtype); - } - strcpy(source, - mo->fsname ? mo->fsname : (mo->subtype ? mo->subtype : devname)); + source = mo->fsname ? mo->fsname : (mo->subtype ? mo->subtype : devname); - res = mount(source, mnt, type, mo->flags, mo->kernel_opts); + res = mount(source.c_str(), mnt, type.c_str(), mo->flags, mo->kernel_opts); if (res == -1 && errno == ENODEV && mo->subtype) { /* Probably missing subtype support */ - strcpy(type, mo->blkdev ? "fuseblk" : "fuse"); + type = mo->blkdev ? "fuseblk" : "fuse"; if (mo->fsname) { if (!mo->blkdev) - sprintf(source, "%s#%s", mo->subtype, - mo->fsname); + source = std::string(mo->subtype) + "#" + mo->fsname; } else { - strcpy(source, type); + source = type; } - res = mount(source, mnt, type, mo->flags, mo->kernel_opts); + res = mount(source.c_str(), mnt, type.c_str(), mo->flags, mo->kernel_opts); } if (res == -1) { /* @@ -543,7 +531,7 @@ fuse_mount_sys(const char *mnt, if (!newmnt) goto out_umount; - res = fuse_mnt_add_mount("fuse", source, newmnt, type, + res = fuse_mnt_add_mount("fuse", source.c_str(), newmnt, type.c_str(), mnt_opts); free(newmnt); if (res == -1) @@ -551,16 +539,12 @@ fuse_mount_sys(const char *mnt, } #endif /* IGNORE_MTAB */ #endif /* __NetBSD__ */ - free(type); - free(source); return fd; out_umount: umount2(mnt, 2); /* lazy umount */ out_close: - free(type); - free(source); close(fd); return res; } diff --git a/vendored/libfuse/lib/mount_util.h b/vendored/libfuse/lib/mount_util.h index ecd6d9f9..63104b73 100644 --- a/vendored/libfuse/lib/mount_util.h +++ b/vendored/libfuse/lib/mount_util.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -249,11 +250,6 @@ int fuse_mnt_remove_mount(const char *progname, const char *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, @@ -261,57 +257,44 @@ char *fuse_mnt_resolve_path(const char *progname, const char *orig) return NULL; } - copy = strdup(orig); - if (copy == NULL) { - fprintf(stderr, "%s: failed to allocate memory\n", progname); - return NULL; - } + std::string copy = orig; + std::string lastcomp; + std::string toresolv; - 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; + while (!copy.empty() && copy.back() == '/') + copy.pop_back(); + + if (!copy.empty() && copy.find('/') != std::string::npos) { + size_t last_slash = copy.find_last_of('/'); + lastcomp = copy.substr(last_slash + 1); + toresolv = copy.substr(0, last_slash); + + if (lastcomp == "." || lastcomp == "..") { + lastcomp.clear(); toresolv = copy; } - else if (tmp) - tmp[0] = '\0'; + } else if (!copy.empty()) { + lastcomp = copy; + toresolv = "."; + } else { + toresolv = "/"; } - if (realpath(toresolv, buf) == NULL) { + + if (realpath(toresolv.c_str(), 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 = static_cast(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; + + std::string dst; + if (lastcomp.empty()) + dst = buf; + else if (buf[strlen(buf) - 1] == '/') + dst = std::string(buf) + lastcomp; + else + dst = std::string(buf) + "/" + lastcomp; + + return strdup(dst.c_str()); } int fuse_mnt_check_fuseblk(void) diff --git a/vendored/libfuse/util/mount.mergerfs.cpp b/vendored/libfuse/util/mount.mergerfs.cpp index 34589aad..49752311 100644 --- a/vendored/libfuse/util/mount.mergerfs.cpp +++ b/vendored/libfuse/util/mount.mergerfs.cpp @@ -11,111 +11,73 @@ #include #include #include +#include -static char *progname; +static const char *progname; -static char *xstrdup(const char *s) +static std::string shell_quote(const std::string &s) { - char *t = strdup(s); - if (!t) { - fprintf(stderr, "%s: failed to allocate memory\n", progname); - exit(1); - } - return t; -} + std::string r = "'"; -static void *xrealloc(void *oldptr, size_t size) -{ - void *ptr = realloc(oldptr, size); - if (!ptr) { - fprintf(stderr, "%s: failed to allocate memory\n", progname); - exit(1); + for (char c : s) { + if (c == '\'') + r += "'\\''"; + else + r += c; } - return ptr; -} + r += "'"; -static void add_arg(char **cmdp, const char *opt) -{ - size_t optlen = strlen(opt); - size_t cmdlen = *cmdp ? strlen(*cmdp) : 0; - char *cmd = static_cast(xrealloc(*cmdp, cmdlen + optlen * 4 + 4)); - char *s; - s = cmd + cmdlen; - if (*cmdp) - *s++ = ' '; - - *s++ = '\''; - for (; *opt; opt++) { - if (*opt == '\'') { - *s++ = '\''; - *s++ = '\\'; - *s++ = '\''; - *s++ = '\''; - } else - *s++ = *opt; - } - *s++ = '\''; - *s = '\0'; - *cmdp = cmd; + return r; } -static char *add_option(const char *opt, char *options) +static std::string add_option(const std::string &opt, + const std::string &options) { - int oldlen = options ? strlen(options) : 0; - - options = static_cast(xrealloc(options, oldlen + 1 + strlen(opt) + 1)); - if (!oldlen) - strcpy(options, opt); - else { - strcat(options, ","); - strcat(options, opt); - } - return options; + if (options.empty()) + return opt; + + return options + "," + opt; } int main(int argc, char *argv[]) { - char *type = NULL; - char *source; - const char *mountpoint; - char *basename; - char *options = NULL; - char *command = NULL; - char *setuid = NULL; - int i; + std::string type; + std::string source; + std::string mountpoint; + std::string basename; + std::string options; + std::string command; + std::string setuid; int dev = 1; int suid = 1; progname = argv[0]; - basename = strrchr(argv[0], '/'); - if (basename) - basename++; - else - basename = argv[0]; + { + const char *slash = strrchr(argv[0], '/'); + basename = slash ? (slash + 1) : argv[0]; + } - type = const_cast("mergerfs"); - if (strncmp(basename, "mount.fuse.", 11) == 0) - type = basename + 11; - if (strncmp(basename, "mount.fuseblk.", 14) == 0) - type = basename + 14; + type = "mergerfs"; + if (strncmp(basename.c_str(), "mount.fuse.", 11) == 0) + type = basename.substr(11); + if (strncmp(basename.c_str(), "mount.fuseblk.", 14) == 0) + type = basename.substr(14); - if (type && !type[0]) - type = NULL; + if (type.empty()) + type = ""; if (argc < 3) { fprintf(stderr, "usage: %s %s destination [-t type] [-o opt[,opts...]]\n", - progname, type ? "source" : "type#[source]"); + progname, type.empty() ? "type#[source]" : "source"); exit(1); } source = argv[1]; - if (!source[0]) - source = NULL; mountpoint = argv[2]; - for (i = 3; i < argc; i++) { + for (int i = 3; i < argc; i++) { if (strcmp(argv[i], "-v") == 0) { continue; } else if (strcmp(argv[i], "-t") == 0) { @@ -128,25 +90,25 @@ int main(int argc, char *argv[]) exit(1); } type = argv[i]; - if (strncmp(type, "fuse.", 5) == 0) - type += 5; - else if (strncmp(type, "fuseblk.", 8) == 0) - type += 8; + if (strncmp(type.c_str(), "fuse.", 5) == 0) + type = type.substr(5); + else if (strncmp(type.c_str(), "fuseblk.", 8) == 0) + type = type.substr(8); - if (!type[0]) { + if (type.empty()) { fprintf(stderr, "%s: empty type given as argument to option '-t'\n", progname); exit(1); } - } else if (strcmp(argv[i], "-o") == 0) { + } else if (strcmp(argv[i], "-o") == 0) { char *opts; char *opt; i++; if (i == argc) break; - opts = xstrdup(argv[i]); + opts = strdup(argv[i]); opt = strtok(opts, ","); while (opt) { @@ -165,7 +127,7 @@ int main(int argc, char *argv[]) NULL }; if (strncmp(opt, "setuid=", 7) == 0) { - setuid = xstrdup(opt + 7); + setuid = opt + 7; ignore = 1; } for (j = 0; ignore_opts[j]; j++) @@ -182,6 +144,7 @@ int main(int argc, char *argv[]) } opt = strtok(NULL, ","); } + free(opts); } } @@ -190,13 +153,17 @@ int main(int argc, char *argv[]) if (suid) options = add_option("suid", options); - if (!type) { - if (source) { - type = xstrdup(source); - source = strchr(type, '#'); - if (source) - *source++ = '\0'; - if (!type[0]) { + if (type.empty()) { + if (!source.empty()) { + size_t hash_pos = source.find('#'); + if (hash_pos != std::string::npos) { + type = source.substr(0, hash_pos); + source = source.substr(hash_pos + 1); + } else { + type = source; + source.clear(); + } + if (type.empty()) { fprintf(stderr, "%s: empty filesystem type\n", progname); exit(1); @@ -207,29 +174,27 @@ int main(int argc, char *argv[]) } } - add_arg(&command, type); - if (source) - add_arg(&command, source); - add_arg(&command, mountpoint); - if (options) { - add_arg(&command, "-o"); - add_arg(&command, options); + command += shell_quote(type); + if (!source.empty()) + command += " " + shell_quote(source); + command += " " + shell_quote(mountpoint); + if (!options.empty()) { + command += " " + shell_quote("-o"); + command += " " + shell_quote(options); } - if (setuid && setuid[0]) { - char *sucommand = command; - command = NULL; - add_arg(&command, "su"); - add_arg(&command, "-"); - add_arg(&command, setuid); - add_arg(&command, "-c"); - add_arg(&command, sucommand); + if (!setuid.empty()) { + std::string sucommand = command; + command = "su"; + command += " -"; + command += " " + shell_quote(setuid); + command += " -c"; + command += " " + shell_quote(sucommand); } else if (!getenv("HOME")) { - /* Hack to make filesystems work in the boot environment */ setenv("HOME", "/root", 0); } - execl("/bin/sh", "/bin/sh", "-c", command, NULL); + execl("/bin/sh", "/bin/sh", "-c", command.c_str(), NULL); fprintf(stderr, "%s: failed to execute /bin/sh: %s\n", progname, strerror(errno)); return 1;