bool SMTPFileSystem::parseOptions(int argc, char **argv)
{
    #define SMTPFS_OPT_KEY(t, p, v) { t, offsetof(SMTPFileSystemOptions, p), v }

    static struct fuse_opt smtpfs_opts[] = {
        SMTPFS_OPT_KEY("enable-move", m_enable_move, 1),
        SMTPFS_OPT_KEY("--device %i", m_device_no, 0),
        SMTPFS_OPT_KEY("-l", m_list_devices, 1),
        SMTPFS_OPT_KEY("--list-devices", m_list_devices, 1),
        SMTPFS_OPT_KEY("-v", m_verbose, 1),
        SMTPFS_OPT_KEY("--verbose", m_verbose, 1),
        SMTPFS_OPT_KEY("-V", m_version, 1),
        SMTPFS_OPT_KEY("--version", m_version, 1),
        SMTPFS_OPT_KEY("-h", m_help, 1),
        SMTPFS_OPT_KEY("--help", m_help, 1),
        FUSE_OPT_END
    };

    if (argc < 2) {
        logerr("Wrong usage.\n");
        m_options.m_good = false;
        return false;
    }

    fuse_opt_free_args(&m_args);
    m_args = FUSE_ARGS_INIT(argc, argv);
    if (fuse_opt_parse(&m_args, &m_options, smtpfs_opts, SMTPFileSystemOptions::opt_proc) == -1) {
        m_options.m_good = false;
        return false;
    }

    if (m_options.m_version || m_options.m_help || m_options.m_list_devices) {
        m_options.m_good = true;
        return true;
    }

    if (m_options.m_device_file && !m_options.m_mount_point) {
        m_options.m_mount_point = m_options.m_device_file;
        m_options.m_device_file = nullptr;
    }

    if (!m_options.m_mount_point) {
        logerr("Mount point missing.\n");
        m_options.m_good = false;
        return false;
    }

    fuse_opt_add_arg(&m_args, m_options.m_mount_point);
    fuse_opt_add_arg(&m_args, "-s");

    if (m_options.m_verbose) {
        Logger::setGlobalVerbose();
        fuse_opt_add_arg(&m_args, "-f");
    }

    --m_options.m_device_no;

    // device file and -- device are mutually exclusive, fail if both set
    if (m_options.m_device_no && m_options.m_device_file) {
        m_options.m_good = false;
        return false;
    }

    m_options.m_good = true;
    return true;
}
bool SMTPFileSystem::parseOptions(int argc, char **argv)
{
    #define SMTPFS_OPT_KEY(t, p, v) { t, offsetof(SMTPFileSystemOptions, p), v }

    static struct fuse_opt smtpfs_opts[] = {
        SMTPFS_OPT_KEY("enable-move", m_enable_move, 1),
        SMTPFS_OPT_KEY("tmp-dir=%s", m_tmp_dir, 0),
        SMTPFS_OPT_KEY("--device %i", m_device, 0),
        SMTPFS_OPT_KEY("-l", m_list_devices, 1),
        SMTPFS_OPT_KEY("--list-devices", m_list_devices, 1),
        SMTPFS_OPT_KEY("-v", m_verbose, 1),
        SMTPFS_OPT_KEY("--verbose", m_verbose, 1),
        SMTPFS_OPT_KEY("-V", m_version, 1),
        SMTPFS_OPT_KEY("--version", m_version, 1),
        SMTPFS_OPT_KEY("-h", m_help, 1),
        SMTPFS_OPT_KEY("--help", m_help, 1),
        FUSE_OPT_END
    };

    if (argc < 2) {
        m_options.m_good = false;
        return false;
    }

    fuse_opt_free_args(&m_args);
    m_args = FUSE_ARGS_INIT(argc, argv);
    if (fuse_opt_parse(&m_args, &m_options, smtpfs_opts, nullptr) == -1) {
        m_options.m_good = false;
        return false;
    }

    fuse_opt_add_arg(&m_args, "-s");

    if (m_options.m_version || m_options.m_help || m_options.m_list_devices) {
        m_options.m_good = true;
        return true;
    }

    if (--m_options.m_device < 0) {
        m_options.m_good = false;
        return false;
    }

    if (m_options.m_tmp_dir)
        removeTmpDir();
    m_options.m_tmp_dir = expandTmpDir(m_options.m_tmp_dir);
    if (!m_options.m_tmp_dir) {
        m_options.m_good = false;
        return false;
    }

    m_tmp_files_pool.setTmpDir(m_options.m_tmp_dir);
    ::mkdir(static_cast<const char*>(m_options.m_tmp_dir), 0700);

    if (m_options.m_verbose) {
        Logger::setGlobalVerbose();
        fuse_opt_add_arg(&m_args, "-f");
    }

    m_options.m_good = true;
    return true;
}