示例#1
0
文件: toxic.c 项目: gracchus163/toxic
int main(int argc, char *argv[])
{
    char *user_config_dir = get_user_config_dir();
    int config_err = 0;

    parse_args(argc, argv);

    /* Make sure all written files are read/writeable only by the current user. */
    umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);

    signal(SIGINT, catch_SIGINT);

    config_err = create_user_config_dir(user_config_dir);

    if (DATA_FILE == NULL ) {
        if (config_err) {
            DATA_FILE = strdup("data");

            if (DATA_FILE == NULL)
                exit_toxic_err("failed in main", FATALERR_MEMORY);
        } else {
            DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1);

            if (DATA_FILE == NULL)
                exit_toxic_err("failed in main", FATALERR_MEMORY);

            strcpy(DATA_FILE, user_config_dir);
            strcat(DATA_FILE, CONFIGDIR);
            strcat(DATA_FILE, "data");
        }
    }

    free(user_config_dir);

    /* init user_settings struct and load settings from conf file */
    user_settings_ = calloc(1, sizeof(struct user_settings));

    if (user_settings_ == NULL)
        exit_toxic_err("failed in main", FATALERR_MEMORY);

    char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL;
    int settings_err = settings_load(user_settings_, p);

    Tox *m = init_tox(arg_opts.use_ipv4);
    init_term();

    if (m == NULL)
        exit_toxic_err("failed in main", FATALERR_NETWORKINIT);

    if (!arg_opts.ignore_data_file)
        load_data(m, DATA_FILE);

    prompt = init_windows(m);
    prompt_init_statusbar(prompt, m);

    /* thread for ncurses stuff */
    if (pthread_mutex_init(&Winthread.lock, NULL) != 0)
        exit_toxic_err("failed in main", FATALERR_MUTEX_INIT);

    if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0)
        exit_toxic_err("failed in main", FATALERR_THREAD_CREATE);

#ifdef _AUDIO

    av = init_audio(prompt, m);


    set_primary_device(input, user_settings_->audio_in_dev);
    set_primary_device(output, user_settings_->audio_out_dev);
#elif _SOUND_NOTIFY
    if ( init_devices() == de_InternalError )
        line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to init devices");

#endif /* _AUDIO */
    
    init_notify(60, 3000);

#ifdef _SOUND_NOTIFY
    notify(prompt, self_log_in, 0);
#endif /* _SOUND_NOTIFY */
    
    const char *msg;

    if (config_err) {
        msg = "Unable to determine configuration directory. Defaulting to 'data' for a keyfile...";
        line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
    }

    if (settings_err == -1) {
        msg = "Failed to load user settings";
        line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
    }

    sort_friendlist_index();

    uint64_t last_save = (uint64_t) time(NULL);

    while (true) {
        update_unix_time();
        do_toxic(m, prompt);
        uint64_t cur_time = get_unix_time();

        if (timed_out(last_save, cur_time, AUTOSAVE_FREQ)) {
            pthread_mutex_lock(&Winthread.lock);
            store_data(m, DATA_FILE);
            pthread_mutex_unlock(&Winthread.lock);

            last_save = cur_time;
        }

        usleep(40000);
    }

    return 0;
}
示例#2
0
文件: main.c 项目: stqism/toxic
int main(int argc, char *argv[])
{
    char *user_config_dir = get_user_config_dir();
    int config_err = 0;

    f_loadfromfile = 1;
    int f_flag = 0;
    int i = 0;
    int f_use_ipv4 = 0;

    /* Make sure all written files are read/writeable only by the current user. */
    umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);

    for (i = 0; i < argc; ++i) {
        if (argv[i] == NULL)
            break;
        else if (argv[i][0] == '-') {
            if (argv[i][1] == 'f') {
                if (argv[i + 1] != NULL)
                    DATA_FILE = strdup(argv[i + 1]);
                else
                    f_flag = -1;
            } else if (argv[i][1] == 'n') {
                f_loadfromfile = 0;
            } else if (argv[i][1] == '4') {
                f_use_ipv4 = 1;
            }
        }
    }

    config_err = create_user_config_dir(user_config_dir);
    if (DATA_FILE == NULL ) {
        if (config_err) {
            DATA_FILE = strdup("data");
        } else {
            DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1);
            if (DATA_FILE != NULL) {
                strcpy(DATA_FILE, user_config_dir);
                strcat(DATA_FILE, CONFIGDIR);
                strcat(DATA_FILE, "data");     
            } else {
                endwin();
                fprintf(stderr, "malloc() failed. Aborting...\n");
                exit(EXIT_FAILURE);
            }
        }
    }

    free(user_config_dir);

    init_term();
    Tox *m = init_tox(f_use_ipv4);

    if (m == NULL) {
        endwin();
        fprintf(stderr, "Failed to initialize network. Aborting...\n");
        exit(EXIT_FAILURE);
    }

    prompt = init_windows(m);

    /* create new thread for ncurses stuff */
    if (pthread_mutex_init(&Winthread.lock, NULL) != 0) {
        endwin();
        fprintf(stderr, "Mutex init failed. Aborting...\n");
        exit(EXIT_FAILURE);
    }

    if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0) {
        endwin();
        fprintf(stderr, "Thread creation failed. Aborting...\n");
        exit(EXIT_FAILURE);
    }

    uint8_t *msg;

#ifdef _SUPPORT_AUDIO

    av = init_audio(prompt, m);

    if ( errors() == NoError )
        msg = "Audio started with no problems.";
    else /* Get error code and stuff */
        msg = "Error starting audio!";

    line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);

#endif /* _SUPPORT_AUDIO */

    if (f_loadfromfile)
        load_data(m, DATA_FILE);

    if (f_flag == -1) {
        msg = "You passed '-f' without giving an argument. Defaulting to 'data' for a keyfile...";
        line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
    }

    if (config_err) {
        msg = "Unable to determine configuration directory. Defaulting to 'data' for a keyfile...";
        line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
    }

    sort_friendlist_index();
    prompt_init_statusbar(prompt, m);

    while (true) {
        update_unix_time();
        do_toxic(m, prompt);
        usleep(10000);
    }
        
    return 0;
}
示例#3
0
文件: toxic.c 项目: dardevelin/toxic
int main(int argc, char *argv[])
{
    init_signal_catchers();
    parse_args(argc, argv);

    /* Make sure all written files are read/writeable only by the current user. */
    umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    int config_err = init_data_files();

    /* init user_settings struct and load settings from conf file */
    user_settings_ = calloc(1, sizeof(struct user_settings));

    if (user_settings_ == NULL)
        exit_toxic_err("failed in main", FATALERR_MEMORY);

    char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL;
    int settings_err = settings_load(user_settings_, p);

    Tox *m = init_tox();
    init_term();

    /* enable stderr for debugging */
    if (!arg_opts.debug)
        freopen("/dev/null", "w", stderr);

    if (m == NULL)
        exit_toxic_err("failed in main", FATALERR_NETWORKINIT);

    if (!arg_opts.ignore_data_file)
        load_data(m, DATA_FILE);

    prompt = init_windows(m);
    prompt_init_statusbar(prompt, m);

    /* thread for ncurses stuff */
    if (pthread_mutex_init(&Winthread.lock, NULL) != 0)
        exit_toxic_err("failed in main", FATALERR_MUTEX_INIT);

    if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0)
        exit_toxic_err("failed in main", FATALERR_THREAD_CREATE);

#ifdef _AUDIO

    av = init_audio(prompt, m);


    set_primary_device(input, user_settings_->audio_in_dev);
    set_primary_device(output, user_settings_->audio_out_dev);
#elif _SOUND_NOTIFY
    if ( init_devices() == de_InternalError )
        line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to init devices");

#endif /* _AUDIO */
    
    init_notify(60, 3000);

#ifdef _SOUND_NOTIFY
//     sound_notify(prompt, self_log_in, 0, NULL);
#endif /* _SOUND_NOTIFY */
    
    const char *msg;
    
    if (config_err) {
        msg = "Unable to determine configuration directory. Defaulting to 'data' for data file...";
        line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
    }

    if (settings_err == -1)
        line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to load user settings");

    if (arg_opts.use_proxy && !arg_opts.force_tcp) {
        msg = "* WARNING: Using a proxy without disabling UDP may leak your real IP address.";
        line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, "%s", msg);
        msg = "  Use the -t option to disable UDP.";
        line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, "%s", msg);
    }

    uint64_t last_save = (uint64_t) time(NULL);
    uint64_t looptimer = last_save;
    useconds_t msleepval = 40000;
    uint64_t loopcount = 0;

    while (true) {
        update_unix_time();
        do_toxic(m, prompt);
        uint64_t cur_time = get_unix_time();

        if (timed_out(last_save, cur_time, AUTOSAVE_FREQ)) {
            pthread_mutex_lock(&Winthread.lock);
            store_data(m, DATA_FILE);
            pthread_mutex_unlock(&Winthread.lock);

            last_save = cur_time;
        }

        msleepval = optimal_msleepval(&looptimer, &loopcount, cur_time, msleepval);
        usleep(msleepval);
    }

    return 0;
}
示例#4
0
int main(int argc, char **argv)
{
    parse_args(argc, argv);

    /* Use the -b flag to enable stderr */
    if (!arg_opts.debug)
        freopen("/dev/null", "w", stderr);

    if (arg_opts.encrypt_data && arg_opts.unencrypt_data) {
        arg_opts.encrypt_data = 0;
        arg_opts.unencrypt_data = 0;
        queue_init_message("Warning: Using --unencrypt-data and --encrypt-data simultaneously has no effect");
    }

    /* Make sure all written files are read/writeable only by the current user. */
    umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);

    init_default_data_files();

    bool datafile_exists = file_exists(DATA_FILE);

    if (!datafile_exists && !arg_opts.unencrypt_data)
        first_time_encrypt("Creating new data file. Would you like to encrypt it? Y/n (q to quit)");
    else if (arg_opts.encrypt_data)
        first_time_encrypt("Encrypt existing data file? Y/n (q to quit)");


    /* init user_settings struct and load settings from conf file */
    user_settings = calloc(1, sizeof(struct user_settings));

    if (user_settings == NULL)
        exit_toxic_err("failed in main", FATALERR_MEMORY);

    const char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL;

    if (settings_load(user_settings, p) == -1) {
        queue_init_message("Failed to load user settings");
    }

    int curl_init = curl_global_init(CURL_GLOBAL_ALL);
    int nameserver_ret = name_lookup_init(curl_init);

    if (nameserver_ret == -1) {
        queue_init_message("curl failed to initialize; name lookup service is disabled.");
    } else if (nameserver_ret == -2) {
        queue_init_message("Name lookup server list could not be found.");
    } else if (nameserver_ret == -3) {
        queue_init_message("Name lookup server list does not contain any valid entries.");
    }

#ifdef X11

    if (init_xtra(DnD_callback) == -1)
        queue_init_message("X failed to initialize");

#endif

    Tox *m = load_toxic(DATA_FILE);

    if (arg_opts.encrypt_data && !datafile_exists)
        arg_opts.encrypt_data = 0;


    init_term();

    prompt = init_windows(m);
    prompt_init_statusbar(prompt, m);

    /* thread for ncurses stuff */
    if (pthread_mutex_init(&Winthread.lock, NULL) != 0)
        exit_toxic_err("failed in main", FATALERR_MUTEX_INIT);

    if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0)
        exit_toxic_err("failed in main", FATALERR_THREAD_CREATE);

    /* thread for message queue */
    if (pthread_create(&cqueue_thread.tid, NULL, thread_cqueue, (void *) m) != 0)
        exit_toxic_err("failed in main", FATALERR_THREAD_CREATE);

#ifdef AUDIO

    av = init_audio(prompt, m);

#ifdef VIDEO
    init_video(prompt, m);

#endif /* VIDEO */

    /* AV thread */
    if (pthread_create(&av_thread.tid, NULL, thread_av, (void *) av) != 0)
        exit_toxic_err("failed in main", FATALERR_THREAD_CREATE);

    set_primary_device(input, user_settings->audio_in_dev);
    set_primary_device(output, user_settings->audio_out_dev);

#elif SOUND_NOTIFY

    if ( init_devices() == de_InternalError )
        queue_init_message("Failed to init audio devices");

#endif /* AUDIO */

    init_notify(60, 3000);

    /* screen/tmux auto-away timer */
    if (init_mplex_away_timer(m) == -1)
        queue_init_message("Failed to init mplex auto-away.");

    int nodeslist_ret = load_DHT_nodeslist();

    if (nodeslist_ret != 0) {
        queue_init_message("DHT nodeslist failed to load (error %d)", nodeslist_ret);
    }

    pthread_mutex_lock(&Winthread.lock);
    print_init_messages(prompt);
    pthread_mutex_unlock(&Winthread.lock);

    cleanup_init_messages();

    /* set user avatar from config file. if no path is supplied tox_unset_avatar is called */
    char avatarstr[MAX_STR_SIZE];
    snprintf(avatarstr, sizeof(avatarstr), "/avatar \"%s\"", user_settings->avatar_path);
    execute(prompt->chatwin->history, prompt, m, avatarstr, GLOBAL_COMMAND_MODE);

    time_t last_save = get_unix_time();

    while (true) {
        do_toxic(m);

        time_t cur_time = get_unix_time();

        if (timed_out(last_save, AUTOSAVE_FREQ)) {
            pthread_mutex_lock(&Winthread.lock);

            if (store_data(m, DATA_FILE) != 0)
                line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, "WARNING: Failed to save to data file");

            pthread_mutex_unlock(&Winthread.lock);

            last_save = cur_time;
        }

        usleep(tox_iteration_interval(m) * 1000);
    }

    return 0;
}
示例#5
0
文件: main.c 项目: FullName/toxic
int main(int argc, char *argv[])
{
    char *user_config_dir = get_user_config_dir();
    int config_err = 0;

    f_loadfromfile = 1;
    int f_flag = 0;
    int i = 0;

    for (i = 0; i < argc; ++i) {
        if (argv[i] == NULL)
            break;
        else if (argv[i][0] == '-') {
            if (argv[i][1] == 'f') {
                if (argv[i + 1] != NULL)
                    DATA_FILE = strdup(argv[i + 1]);
                else
                    f_flag = -1;
            } else if (argv[i][1] == 'n') {
                f_loadfromfile = 0;
            }
        }
    }

    config_err = create_user_config_dir(user_config_dir);
    if (DATA_FILE == NULL ) {
        if (config_err) {
            DATA_FILE = strdup("data");
        } else {
            DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1);
            if (DATA_FILE != NULL) {
                strcpy(DATA_FILE, user_config_dir);
                strcat(DATA_FILE, CONFIGDIR);
                strcat(DATA_FILE, "data");
            } else {
                endwin();
                fprintf(stderr, "malloc() failed. Aborting...\n");
                exit(EXIT_FAILURE);
            }
        }
    }

    if (config_err) {
        SRVLIST_FILE = strdup(PACKAGE_DATADIR "/DHTservers");
    } else {
        SRVLIST_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("DHTservers") + 1);
        if (SRVLIST_FILE != NULL) {
            strcpy(SRVLIST_FILE, user_config_dir);
            strcat(SRVLIST_FILE, CONFIGDIR);
            strcat(SRVLIST_FILE, "DHTservers");
        } else {
            endwin();
            fprintf(stderr, "malloc() failed. Aborting...\n");
            exit(EXIT_FAILURE);
        }
    }

    free(user_config_dir);

    init_term();
    Tox *m = init_tox();

    if (m == NULL) {
        endwin();
        fprintf(stderr, "Failed to initialize network. Aborting...\n");
        exit(EXIT_FAILURE);
    }

    prompt = init_windows(m);

    if (f_loadfromfile)
        load_data(m, DATA_FILE);

    if (f_flag == -1) {
        attron(COLOR_PAIR(RED) | A_BOLD);
        wprintw(prompt->window, "You passed '-f' without giving an argument.\n"
                "defaulting to 'data' for a keyfile...\n");
        attroff(COLOR_PAIR(RED) | A_BOLD);
    }

    if (config_err) {
        attron(COLOR_PAIR(RED) | A_BOLD);
        wprintw(prompt->window, "Unable to determine configuration directory.\n"
                "defaulting to 'data' for a keyfile...\n");
        attroff(COLOR_PAIR(RED) | A_BOLD);
    }

    prompt_init_statusbar(prompt, m);

    while (true) {
        /* Update tox */
        do_tox(m, prompt);

        /* Draw */
        draw_active_window(m);
    }

    exit_toxic(m);
    return 0;
}
示例#6
0
文件: toxic.c 项目: jin-eld/toxic
int main(int argc, char *argv[])
{
    char *user_config_dir = get_user_config_dir();
    int config_err = 0;

    parse_args(argc, argv);

    /* Make sure all written files are read/writeable only by the current user. */
    umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);

    signal(SIGINT, ignore_SIGINT);

    config_err = create_user_config_dir(user_config_dir);

    if (DATA_FILE == NULL ) {
        if (config_err) {
            DATA_FILE = strdup("data");
        } else {
            DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1);

            if (DATA_FILE != NULL) {
                strcpy(DATA_FILE, user_config_dir);
                strcat(DATA_FILE, CONFIGDIR);
                strcat(DATA_FILE, "data");
            } else {
                endwin();
                fprintf(stderr, "malloc() failed. Aborting...\n");
                exit(EXIT_FAILURE);
            }
        }
    }

    free(user_config_dir);

    /* init user_settings struct and load settings from conf file */
    user_settings = malloc(sizeof(struct user_settings));

    if (user_settings == NULL) {
        endwin();
        fprintf(stderr, "malloc() failed. Aborting...\n");
        exit(EXIT_FAILURE);
    }

    memset(user_settings, 0, sizeof(struct user_settings));

    char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL;
    int settings_err = settings_load(user_settings, p);

    Tox *m = init_tox(arg_opts.use_ipv4);
    init_term();

    if (m == NULL) {
        endwin();
        fprintf(stderr, "Failed to initialize network. Aborting...\n");
        exit(EXIT_FAILURE);
    }

    if (!arg_opts.ignore_data_file)
        load_data(m, DATA_FILE);

    prompt = init_windows(m);

    /* create new thread for ncurses stuff */
    if (pthread_mutex_init(&Winthread.lock, NULL) != 0) {
        endwin();
        fprintf(stderr, "Mutex init failed. Aborting...\n");
        exit(EXIT_FAILURE);
    }

    if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0) {
        endwin();
        fprintf(stderr, "Thread creation failed. Aborting...\n");
        exit(EXIT_FAILURE);
    }

    uint8_t *msg;

#ifdef _SUPPORT_AUDIO

    av = init_audio(prompt, m);
    
    device_set(prompt, input, user_settings->audio_in_dev);
    device_set(prompt, output, user_settings->audio_out_dev);

    if ( errors() == NoError )
        msg = "Audio initiated with no problems.";
    else /* Get error code and stuff */
        msg = "Error initiating audio!";

    line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);

#endif /* _SUPPORT_AUDIO */

    if (config_err) {
        msg = "Unable to determine configuration directory. Defaulting to 'data' for a keyfile...";
        line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
    }


    if (settings_err == -1) {
        msg = "Failed to load user settings";
        line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
    }


    sort_friendlist_index();
    prompt_init_statusbar(prompt, m);

    while (true) {
        update_unix_time();
        do_toxic(m, prompt);
        usleep(10000);
    }

    return 0;
}
示例#7
0
文件: main.c 项目: Jman012/toxic
int main(int argc, char *argv[])
{
    char *user_config_dir = get_user_config_dir();
    int config_err = 0;

    f_loadfromfile = 1;
    int f_flag = 0;
    int i = 0;
    int f_use_ipv4 = 0;

    /* Make sure all written files are read/writeable only by the current user. */
    umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);

    for (i = 0; i < argc; ++i) {
        if (argv[i] == NULL)
            break;
        else if (argv[i][0] == '-') {
            if (argv[i][1] == 'f') {
                if (argv[i + 1] != NULL)
                    DATA_FILE = strdup(argv[i + 1]);
                else
                    f_flag = -1;
            } else if (argv[i][1] == 'n') {
                f_loadfromfile = 0;
            } else if (argv[i][1] == '4') {
                f_use_ipv4 = 1;
            }
        }
    }

    config_err = create_user_config_dir(user_config_dir);
    if (DATA_FILE == NULL ) {
        if (config_err) {
            DATA_FILE = strdup("data");
        } else {
            DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1);
            if (DATA_FILE != NULL) {
                strcpy(DATA_FILE, user_config_dir);
                strcat(DATA_FILE, CONFIGDIR);
                strcat(DATA_FILE, "data");     
            } else {
                endwin();
                fprintf(stderr, "malloc() failed. Aborting...\n");
                exit(EXIT_FAILURE);
            }
        }
    }

    free(user_config_dir);

    init_term();
    Tox *m = init_tox(f_use_ipv4);

    if (m == NULL) {
        endwin();
        fprintf(stderr, "Failed to initialize network. Aborting...\n");
        exit(EXIT_FAILURE);
    }

    prompt = init_windows(m);

#ifdef _SUPPORT_AUDIO 
    
    attron(COLOR_PAIR(RED) | A_BOLD);
    wprintw(prompt->window, "Starting audio...\n");
    attroff(COLOR_PAIR(RED) | A_BOLD);
    
    av = init_audio(prompt, m);
        
    if ( errors() == NoError )
        wprintw(prompt->window, "Audio started with no problems.\n");
    else /* Get error code and stuff */
        wprintw(prompt->window, "Error starting audio!\n");
    
    
#endif /* _SUPPORT_AUDIO */
    
    if (f_loadfromfile)
        load_data(m, DATA_FILE);

    if (f_flag == -1) {
        attron(COLOR_PAIR(RED) | A_BOLD);
        wprintw(prompt->window, "You passed '-f' without giving an argument.\n"
                "defaulting to 'data' for a keyfile...\n");
        attroff(COLOR_PAIR(RED) | A_BOLD);
    }

    if (config_err) {
        attron(COLOR_PAIR(RED) | A_BOLD);
        wprintw(prompt->window, "Unable to determine configuration directory.\n"
                "defaulting to 'data' for a keyfile...\n");
        attroff(COLOR_PAIR(RED) | A_BOLD);
    }

    prompt_init_statusbar(prompt, m);
    sort_friendlist_index(m);

    while (true) 
        do_toxic(m, prompt);
        
    return 0;
}