예제 #1
0
int
main(int argc, char **argv)
{
    int       result    = -1;
    int       mntflags  = 0;
    int       fd        = -1;
    int32_t   dindex    = -1;
    char     *fdnam     = NULL;
    uint64_t  altflags  = 0ULL;
    char     *mntpath   = NULL;

    int i, ch = '\0', done = 0;
    struct mntopt *mo;
    struct mntval *mv;
    struct statfs statfsb;
    fuse_mount_args args;

    if (!getenv("MOUNT_FUSEFS_CALL_BY_LIB")) {
        showhelp();
        /* NOTREACHED */
    }

    /* Kludge to make "<fsdaemon> --version" happy. */
    if ((argc == 2) &&
        ((!strncmp(argv[1], "--version", strlen("--version"))) ||
         (!strncmp(argv[1], "-v", strlen("-v"))))) {
        showversion(1);
    }

    /* Kludge to make "<fsdaemon> --help" happy. */
    if ((argc == 2) &&
        ((!strncmp(argv[1], "--help", strlen("--help"))) ||
         (!strncmp(argv[1], "-h", strlen("-h"))))) {
        showhelp();
    }

    memset((void *)&args, 0, sizeof(args));

    do {
        for (i = 0; i < 3; i++) {
            if (optind < argc && argv[optind][0] != '-') {
                if (mntpath) {
                    done = 1;
                    break;
                }
                if (fdnam)
                    mntpath = argv[optind];
                else
                    fdnam = argv[optind];
                optind++;
            }
        }

        switch(ch) {
        case 'o':
            getmntopts(optarg, mopts, &mntflags, &altflags);
            for (mv = mvals; mv->mv_mntflag; ++mv) {
                if (!(altflags & mv->mv_mntflag)) {
                    continue;
                }
                for (mo = mopts; mo->m_option; ++mo) {
                    char *p, *q;
                    if (mo->m_flag != mv->mv_mntflag) {
                        continue;
                    }
                    p = strstr(optarg, mo->m_option);
                    if (p) {
                        p += strlen(mo->m_option);
                        q = p;
                        while (*q != '\0' && *q != ',') {
                            q++;
                        }
                        mv->mv_len = q - p + 1;
                        mv->mv_value = malloc(mv->mv_len);
                        memcpy(mv->mv_value, p, mv->mv_len - 1);
                        ((char *)mv->mv_value)[mv->mv_len - 1] = '\0';
                        break;
                    }
                }
            }
            break;

        case '\0':
            break;

        case 'v':
            showversion(1);
            break;

        case '?':
        case 'h':
        default:
            showhelp();
            break;
        }

        if (done) {
            break;
        }

    } while ((ch = getopt(argc, argv, "ho:v")) != -1);

    argc -= optind;
    argv += optind;

    if ((!fdnam) && argc > 0) {
        fdnam = *argv++;
        argc--;
    }

    if (!fdnam) {
        errx(EX_USAGE, "missing " OSXFUSE_DISPLAY_NAME
             " device file descriptor");
    }

    errno = 0;
    fd = (int)strtol(fdnam, NULL, 10);
    if ((errno == EINVAL) || (errno == ERANGE)) {
        errx(EX_USAGE, "invalid name (%s) for " OSXFUSE_DISPLAY_NAME
             " device file descriptor", fdnam);
    }

    signal_fd = fd;

    {
        char  ndev[MAXPATHLEN];
        char *ndevbas;
        struct stat sb;

        if (fstat(fd, &sb) == -1) {
            err(EX_OSERR, "fstat failed for " OSXFUSE_DISPLAY_NAME
                " device file descriptor");
        }
        args.rdev = sb.st_rdev;
        (void)strlcpy(ndev, _PATH_DEV, sizeof(ndev));
        ndevbas = ndev + strlen(_PATH_DEV);
        devname_r(sb.st_rdev, S_IFCHR, ndevbas,
                  (int)(sizeof(ndev) - strlen(_PATH_DEV)));

        if (strncmp(ndevbas, OSXFUSE_DEVICE_BASENAME,
                    strlen(OSXFUSE_DEVICE_BASENAME))) {
            errx(EX_USAGE, "mounting inappropriate device");
        }

        errno = 0;
        dindex = (int)strtol(ndevbas + strlen(OSXFUSE_DEVICE_BASENAME),
                             NULL, 10);
        if ((errno == EINVAL) || (errno == ERANGE) ||
            (dindex < 0) || (dindex > OSXFUSE_NDEVICES)) {
            errx(EX_USAGE, "invalid " OSXFUSE_DISPLAY_NAME
                 " device unit (#%d)\n", dindex);
        }
    }

    signal_idx = dindex;

    atexit(signal_idx_atexit_handler);

    result = check_kext_status();

    switch (result) {

    case 0:
        break;

    case ESRCH:
        errx(EX_UNAVAILABLE, "the " OSXFUSE_DISPLAY_NAME
             " kernel extension is not loaded");
        break;

    case EINVAL:
        errx(EX_UNAVAILABLE, "the loaded " OSXFUSE_DISPLAY_NAME
             " kernel extension has a mismatched version");
        break;

    default:
        errx(EX_UNAVAILABLE, "failed to query the loaded " OSXFUSE_DISPLAY_NAME
             " kernel extension (%d)", result);
        break;
    }

    if ((!mntpath) && argc > 0) {
        mntpath = *argv++;
        argc--;
    }

    if (!mntpath) {
        errx(EX_USAGE, "missing mount point");
    }

    (void)checkpath(mntpath, args.mntpath);

    mntpath = args.mntpath;

    fuse_process_mvals();

    if (statfs(mntpath, &statfsb)) {
        errx(EX_OSFILE, "cannot stat the mount point %s", mntpath);
    }

    if (((strlen(statfsb.f_fstypename) == strlen(OSXFUSE_NAME)) &&
         (strcmp(statfsb.f_fstypename, OSXFUSE_NAME) == 0)) ||
        ((strlen(OSXFUSE_TYPE_NAME_PREFIX) > 0) &&
         (strncmp(statfsb.f_fstypename, OSXFUSE_TYPE_NAME_PREFIX,
                  strlen(OSXFUSE_TYPE_NAME_PREFIX)) == 0))) {
        if (!(altflags & FUSE_MOPT_ALLOW_RECURSION)) {
            errx(EX_USAGE, "mount point %s is itself on a "
                 OSXFUSE_DISPLAY_NAME " volume", mntpath);
        }
    }

    /* allow_root and allow_other checks are done in the kernel. */

    if (altflags & FUSE_MOPT_NO_LOCALCACHES) {
        altflags |= FUSE_MOPT_NO_ATTRCACHE;
        altflags |= FUSE_MOPT_NO_READAHEAD;
        altflags |= FUSE_MOPT_NO_UBC;
        altflags |= FUSE_MOPT_NO_VNCACHE;
    }

    if ((altflags & FUSE_MOPT_NEGATIVE_VNCACHE) &&
        (altflags & FUSE_MOPT_NO_VNCACHE)) {
        errx(EX_USAGE, "'negative_vncache' can't be used with 'novncache'");
    }

    /*
     * 'nosyncwrites' must not appear with either 'noubc' or 'noreadahead'.
     */
    if ((altflags & FUSE_MOPT_NO_SYNCWRITES) &&
        (altflags & (FUSE_MOPT_NO_UBC | FUSE_MOPT_NO_READAHEAD))) {
        errx(EX_USAGE,
             "disabling local caching can't be used with 'nosyncwrites'");
    }

    /*
     * 'nosynconclose' only allowed if 'nosyncwrites' is also there.
     */
    if ((altflags & FUSE_MOPT_NO_SYNCONCLOSE) &&
        !(altflags & FUSE_MOPT_NO_SYNCWRITES)) {
        errx(EX_USAGE, "the 'nosynconclose' option requires 'nosyncwrites'");
    }

    if ((altflags & FUSE_MOPT_DEFAULT_PERMISSIONS) &&
        (altflags & FUSE_MOPT_DEFER_PERMISSIONS)) {
        errx(EX_USAGE,
             "'default_permissions' can't be used with 'defer_permissions'");
    }

    if ((altflags & FUSE_MOPT_AUTO_XATTR) &&
        (altflags & FUSE_MOPT_NATIVE_XATTR)) {
        errx(EX_USAGE,
             "'auto_xattr' can't be used with 'native_xattr'");
    }

    if (daemon_timeout < FUSE_MIN_DAEMON_TIMEOUT) {
        daemon_timeout = FUSE_MIN_DAEMON_TIMEOUT;
    }

    if (daemon_timeout > FUSE_MAX_DAEMON_TIMEOUT) {
        daemon_timeout = FUSE_MAX_DAEMON_TIMEOUT;
    }

    result = ioctl(fd, FUSEDEVIOCGETRANDOM, &drandom);
    if (result) {
        errx(EX_UNAVAILABLE, "failed to negotiate with /dev/"
             OSXFUSE_DEVICE_BASENAME "%d", dindex);
    }

    args.altflags       = altflags;
    args.blocksize      = (uint32_t) blocksize;
    args.daemon_timeout = (uint32_t) daemon_timeout;
    args.fsid           = (uint32_t) fsid;
    args.fssubtype      = (uint32_t) fssubtype;
    args.iosize         = (uint32_t) iosize;
    args.random         = drandom;

    char *daemon_name = NULL;
    char *daemon_path = getenv("MOUNT_OSXFUSE_DAEMON_PATH");
    if (daemon_path) {
        daemon_name = basename(daemon_path);
    }

    if (!fsname) {
        if (daemon_name) {
            snprintf(args.fsname, MAXPATHLEN, "%s@" OSXFUSE_DEVICE_BASENAME
                     "%d", daemon_name, dindex);
        } else {
            snprintf(args.fsname, MAXPATHLEN, "instance@"
                     OSXFUSE_DEVICE_BASENAME "%d", dindex);
        }
    } else {
        snprintf(args.fsname, MAXPATHLEN, "%s", fsname);
    }

    if (fstypename) {
        if (strlen(fstypename) > FUSE_TYPE_NAME_MAXLEN) {
            errx(EX_USAGE, "fstypename can be at most %lu characters",
                 (long unsigned int) FUSE_TYPE_NAME_MAXLEN);
        } else {
            snprintf(args.fstypename, MFSTYPENAMELEN, "%s", fstypename);
        }
    }

    if (!volname) {
        #if __clang__
            #pragma clang diagnostic push
            #pragma clang diagnostic ignored "-Wformat-extra-args"
        #endif

        if (daemon_name) {
            snprintf(args.volname, MAXPATHLEN, OSXFUSE_VOLNAME_DAEMON_FORMAT,
                     dindex, daemon_name);
        } else {
            snprintf(args.volname, MAXPATHLEN, OSXFUSE_VOLNAME_FORMAT, dindex);
        }

        #if __clang__
            #pragma clang diagnostic pop
        #endif
    } else {
        snprintf(args.volname, MAXPATHLEN, "%s", volname);
    }

    /* Finally! */
    result = mount(OSXFUSE_NAME, mntpath, mntflags, (void *)&args);

    if (result < 0) {
        err(EX_OSERR, "failed to mount %s@/dev/" OSXFUSE_DEVICE_BASENAME "%d",
            mntpath, dindex);
    } else {
        const char *dict[][2] = { { kFUSEMountPathKey, mntpath } };
        post_notification(NOTIFICATION_MOUNT, dict, 1);
    }

    signal_idx = -1;

    exit(0);
}
예제 #2
0
int
main(int argc, char **argv)
{
    int       result    = -1;
    int       mntflags  = 0;
    int       cfd       = -1;
    char     *fdnam     = NULL;
    char     *dev       = NULL;
    int       r         = 0;
    char      devpath[MAXPATHLEN];
    int       fd        = -1;
    int32_t   dindex    = -1;
    uint64_t  altflags  = 0ULL;
    char     *mntpath   = NULL;

    struct mntopt *mo;
    struct mntval *mv;
    struct statfs statfsb;
    fuse_mount_args args;

    // Drop to real uid and gid
    seteuid(getuid());
    setegid(getgid());

    if (!getenv("MOUNT_OSXFUSE_CALL_BY_LIB")) {
        showhelp();
    }

    memset((void *)&args, 0, sizeof(args));

    while (true) {
        static struct option long_options[] = {
            { "help",    no_argument, NULL, 'h' },
            { "version", no_argument, NULL, 'v' },
            { NULL, 0, NULL, 0 }
        };

        int c = getopt_long(argc, argv, "ho:qv", long_options, NULL);
        if (c == -1) {
            break;
        }

        switch (c) {
            case 'o':
                getmntopts(optarg, mopts, &mntflags, &altflags);
                for (mv = mvals; mv->mv_mntflag; ++mv) {
                    if (!(altflags & mv->mv_mntflag)) {
                        continue;
                    }
                    for (mo = mopts; mo->m_option; ++mo) {
                        char *p, *q;
                        if (!mo->m_altloc || mo->m_flag != mv->mv_mntflag) {
                            continue;
                        }
                        p = strstr(optarg, mo->m_option);
                        if (p) {
                            p += strlen(mo->m_option);
                            q = p;
                            while (*q != '\0' && *q != ',') {
                                q++;
                            }
                            mv->mv_len = q - p + 1;
                            mv->mv_value = malloc(mv->mv_len);
                            memcpy(mv->mv_value, p, mv->mv_len - 1);
                            ((char *)mv->mv_value)[mv->mv_len - 1] = '\0';
                            break;
                        }
                    }
                }
                break;

            case 'q':
                quiet_mode = true;
                break;

            case 'v':
                showversion(true);
                break;

            case 'h':
            case '?':
            default:
                showhelp();
                break;
        }
    }

    argc -= optind;
    argv += optind;

    if (argc >= 1) {
        mntpath = argv[0];
        argc--;
        argv++;
    }

    if (!mntpath) {
        errx(EX_USAGE, "missing mount point");
    }

    {
        char *commfd;

        commfd = getenv("_FUSE_COMMFD");
        if (commfd == NULL) {
            errx(EX_USAGE, "mew style mounting requires commfd");
        }

        errno = 0;
        cfd = (int)strtol(commfd, NULL, 10);
        if (errno == EINVAL || errno == ERANGE || cfd < 0) {
            errx(EX_USAGE, "invalid commfd");
        }
    }

    result = load_kext();
    if (result) {
        if (result == EINVAL) {
            if (!quiet_mode) {
                CFUserNotificationDisplayNotice(
                    (CFTimeInterval)0,
                    kCFUserNotificationCautionAlertLevel,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    CFSTR("Installed version of macOS unsupported"),
                    CFSTR("The installed version of FUSE is too new for the operating system. Please downgrade your FUSE installation to one that is compatible with the currently running version of macOS."),
                    CFSTR("OK"));
            }
            post_notification(NOTIFICATION_OS_IS_TOO_OLD, NULL, 0);
        }
        if (result == ENOENT) {
            if (!quiet_mode) {
                CFUserNotificationDisplayNotice(
                    (CFTimeInterval)0,
                    kCFUserNotificationCautionAlertLevel,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    CFSTR("Installed version of macOS unsupported"),
                    CFSTR("The installed version of FUSE is too old for the operating system. Please upgrade your FUSE installation to one that is compatible with the currently running version of macOS."),
                    CFSTR("OK"));
            }
            post_notification(NOTIFICATION_OS_IS_TOO_NEW, NULL, 0);
        } else if (result == EBUSY) {
            if (!quiet_mode) {
                CFUserNotificationDisplayNotice(
                    (CFTimeInterval)0,
                    kCFUserNotificationCautionAlertLevel,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    CFSTR("FUSE version mismatch"),
                    CFSTR("FUSE has been updated but an incompatible or old version of the FUSE kernel extension is already loaded. It failed to unload, possibly because a FUSE volume is currently mounted.\n\nPlease eject all FUSE volumes and try again, or simply restart the system for changes to take effect."),
                    CFSTR("OK"));
            }
            post_notification(NOTIFICATION_VERSION_MISMATCH, NULL, 0);
        }
        errx(EX_UNAVAILABLE, "the " OSXFUSE_DISPLAY_NAME " file system is not available (%d)", result);
    }

    result = check_kext_status();
    switch (result) {
        case 0:
            break;

        case ESRCH:
            errx(EX_UNAVAILABLE, "the " OSXFUSE_DISPLAY_NAME
                 " kernel extension is not loaded");
            break;

        case EINVAL:
            errx(EX_UNAVAILABLE, "the loaded " OSXFUSE_DISPLAY_NAME
                 " kernel extension has a mismatched version");
            break;

        default:
            errx(EX_UNAVAILABLE, "failed to query the loaded " OSXFUSE_DISPLAY_NAME
                 " kernel extension (%d)", result);
            break;
    }

    fdnam = getenv("FUSE_DEV_FD");
    if (fdnam) {
        errno = 0;
        fd = (int)strtol(fdnam, NULL, 10);
        if (errno == EINVAL || errno == ERANGE || fd < 0) {
            errx(EX_USAGE, "invalid value given in FUSE_DEV_FD");
        }

        goto mount;
    }

    dev = getenv("FUSE_DEV_NAME");
    if (dev) {
        fd = open(dev, O_RDWR);
        if (fd < 0) {
            errx(EX_USAGE, "failed to open device");
        }

        goto mount;
    }

    for (r = 0; r < OSXFUSE_NDEVICES; r++) {
        snprintf(devpath, MAXPATHLEN - 1,
                 _PATH_DEV OSXFUSE_DEVICE_BASENAME "%d", r);
        fd = open(devpath, O_RDWR);
        if (fd >= 0) {
            dindex = r;
            break;
        }
    }
    if (dindex == -1) {
        errx(EX_OSERR, "failed to open device");
    }

mount:
    signal_fd = fd;
    atexit(&signal_idx_atexit_handler);

    {
        struct stat sb;
        if (fstat(fd, &sb) == -1) {
            err(EX_OSERR, "fstat failed for " OSXFUSE_DISPLAY_NAME " device file descriptor");
        }
        args.rdev = sb.st_rdev;
    }

    if (dindex < 0) {
        char  ndev[MAXPATHLEN];
        char *ndevbas;

        (void)strlcpy(ndev, _PATH_DEV, sizeof(ndev));
        ndevbas = ndev + strlen(_PATH_DEV);
        devname_r(args.rdev, S_IFCHR, ndevbas, (int)(sizeof(ndev) - strlen(_PATH_DEV)));

        if (strncmp(ndevbas, OSXFUSE_DEVICE_BASENAME, strlen(OSXFUSE_DEVICE_BASENAME))) {
            errx(EX_USAGE, "mounting inappropriate device");
        }

        errno = 0;
        dindex = (int)strtol(ndevbas + strlen(OSXFUSE_DEVICE_BASENAME), NULL, 10);
        if (errno == EINVAL || errno == ERANGE || dindex < 0 || dindex > OSXFUSE_NDEVICES) {
            errx(EX_USAGE, "invalid " OSXFUSE_DISPLAY_NAME " device unit (#%d)\n", dindex);
        }
    }

    while (true) {
        struct stat sb;

        if (realpath(mntpath, args.mntpath) != NULL &&
            stat(args.mntpath, &sb) == 0) {

            if (S_ISDIR(sb.st_mode)) {
                break;
            } else {
                errx(EX_USAGE, "%s: not a directory", args.mntpath);
            }

        } else if (errno == ENOENT) {
            bool volumes = strncmp(args.mntpath, "/Volumes/", 9) == 0 &&
                           strchr(args.mntpath + 9, '/') == NULL;

            if (volumes) {
                (void)seteuid(0);
                (void)setegid(0);
            }

            if (mkdir(args.mntpath, 0755)) {
                errx(EX_USAGE, "%s: %s", args.mntpath, strerror(errno));
            }

            if (volumes) {
                uid_t uid = getuid();
                gid_t gid = getgid();

                (void)chown(args.mntpath, uid, gid);
                (void)seteuid(uid);
                (void)setegid(gid);
            }

        } else {
            errx(EX_USAGE, "%s: %s", args.mntpath, strerror(errno));
        }
    }

    mntpath = args.mntpath;

    fuse_process_mvals();

    if (statfs(mntpath, &statfsb)) {
        errx(EX_OSFILE, "cannot stat the mount point %s", mntpath);
    }

    if (((strlen(statfsb.f_fstypename) == strlen(OSXFUSE_NAME)) &&
         (strcmp(statfsb.f_fstypename, OSXFUSE_NAME) == 0)) ||
        ((strlen(OSXFUSE_TYPE_NAME_PREFIX) > 0) &&
         (strncmp(statfsb.f_fstypename, OSXFUSE_TYPE_NAME_PREFIX,
                  strlen(OSXFUSE_TYPE_NAME_PREFIX)) == 0))) {
        if (!(altflags & FUSE_MOPT_ALLOW_RECURSION)) {
            errx(EX_USAGE, "mount point %s is itself on a "
                 OSXFUSE_DISPLAY_NAME " volume", mntpath);
        }
    }

    /* allow_root and allow_other checks are done in the kernel. */

    if (altflags & FUSE_MOPT_NO_LOCALCACHES) {
        altflags |= FUSE_MOPT_NO_ATTRCACHE;
        altflags |= FUSE_MOPT_NO_READAHEAD;
        altflags |= FUSE_MOPT_NO_UBC;
        altflags |= FUSE_MOPT_NO_VNCACHE;
    }

    if ((altflags & FUSE_MOPT_NEGATIVE_VNCACHE) &&
        (altflags & FUSE_MOPT_NO_VNCACHE)) {
        errx(EX_USAGE, "'negative_vncache' can't be used with 'novncache'");
    }

    /*
     * 'nosyncwrites' must not appear with either 'noubc' or 'noreadahead'.
     */
    if ((altflags & FUSE_MOPT_NO_SYNCWRITES) &&
        (altflags & (FUSE_MOPT_NO_UBC | FUSE_MOPT_NO_READAHEAD))) {
        errx(EX_USAGE,
             "disabling local caching can't be used with 'nosyncwrites'");
    }

    /*
     * 'nosynconclose' only allowed if 'nosyncwrites' is also there.
     */
    if ((altflags & FUSE_MOPT_NO_SYNCONCLOSE) &&
        !(altflags & FUSE_MOPT_NO_SYNCWRITES)) {
        errx(EX_USAGE, "the 'nosynconclose' option requires 'nosyncwrites'");
    }

    if ((altflags & FUSE_MOPT_DEFAULT_PERMISSIONS) &&
        (altflags & FUSE_MOPT_DEFER_PERMISSIONS)) {
        errx(EX_USAGE,
             "'default_permissions' can't be used with 'defer_permissions'");
    }

    if ((altflags & FUSE_MOPT_AUTO_XATTR) &&
        (altflags & FUSE_MOPT_NATIVE_XATTR)) {
        errx(EX_USAGE,
             "'auto_xattr' can't be used with 'native_xattr'");
    }

    if (daemon_timeout < FUSE_MIN_DAEMON_TIMEOUT) {
        daemon_timeout = FUSE_MIN_DAEMON_TIMEOUT;
    }

    if (daemon_timeout > FUSE_MAX_DAEMON_TIMEOUT) {
        daemon_timeout = FUSE_MAX_DAEMON_TIMEOUT;
    }

    result = ioctl(fd, FUSEDEVIOCGETRANDOM, &drandom);
    if (result) {
        errx(EX_UNAVAILABLE, "failed to negotiate with /dev/"
             OSXFUSE_DEVICE_BASENAME "%d", dindex);
    }

    args.altflags       = altflags;
    args.blocksize      = (uint32_t)blocksize;
    args.daemon_timeout = (uint32_t)daemon_timeout;
    args.fsid           = (uint32_t)fsid;
    args.fssubtype      = (uint32_t)fssubtype;
    args.iosize         = (uint32_t)iosize;
    args.random         = drandom;

    char *daemon_name = NULL;
    char *daemon_path = getenv("MOUNT_OSXFUSE_DAEMON_PATH");
    if (daemon_path) {
        daemon_name = basename(daemon_path);
    }

    if (!fsname) {
        if (daemon_name) {
            snprintf(args.fsname, MAXPATHLEN, "%s@" OSXFUSE_DEVICE_BASENAME
                     "%d", daemon_name, dindex);
        } else {
            snprintf(args.fsname, MAXPATHLEN, "instance@"
                     OSXFUSE_DEVICE_BASENAME "%d", dindex);
        }
    } else {
        snprintf(args.fsname, MAXPATHLEN, "%s", fsname);
    }

    if (fstypename) {
        if (strlen(fstypename) > FUSE_TYPE_NAME_MAXLEN) {
            errx(EX_USAGE, "fstypename can be at most %lu characters",
                 (long unsigned int) FUSE_TYPE_NAME_MAXLEN);
        } else {
            snprintf(args.fstypename, MFSTYPENAMELEN, "%s", fstypename);
        }
    }

    if (!volname) {
        #if __clang__
            #pragma clang diagnostic push
            #pragma clang diagnostic ignored "-Wformat-extra-args"
        #endif

        if (daemon_name) {
            snprintf(args.volname, MAXPATHLEN, OSXFUSE_VOLNAME_DAEMON_FORMAT,
                     dindex, daemon_name);
        } else {
            snprintf(args.volname, MAXPATHLEN, OSXFUSE_VOLNAME_FORMAT, dindex);
        }

        #if __clang__
            #pragma clang diagnostic pop
        #endif
    } else {
        snprintf(args.volname, MAXPATHLEN, "%s", volname);
    }

    if (cfd != -1) {
        result = send_fd(cfd, fd);
        if (result == -1) {
            err(EX_OSERR, "failed to send file descriptor");
        }
    }

    /* Finally! */
    result = mount(OSXFUSE_NAME, mntpath, mntflags, (void *)&args);

    if (result < 0) {
        err(EX_OSERR, "failed to mount %s@/dev/" OSXFUSE_DEVICE_BASENAME "%d",
            mntpath, dindex);
    } else {
        const char *dict[][2] = { { kFUSEMountPathKey, mntpath } };
        post_notification(NOTIFICATION_MOUNT, dict, 1);
    }

    signal_fd = -1;
    exit(0);
}