X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fconf.c;h=81c280a405fcd85c7ac0062cc2923015887a9ae9;hb=bf5fc85f37af5698d477edc5dae250bf8984ed00;hp=e0214ce9d58a8bfa56cd39e973cfcc70e5d36aec;hpb=75fa0c73ee4ee2648f587e2eb852316061fc1053;p=ncmpc.git diff --git a/src/conf.c b/src/conf.c index e0214ce..81c280a 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1,7 +1,6 @@ -/* - * $Id$ - * - * (c) 2004 by Kalle Wallin +/* ncmpc (Ncurses MPD Client) + * (c) 2004-2017 The Music Player Daemon Project + * Project homepage: http://musicpd.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -12,315 +11,332 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define NO_GLOBAL_OPTIONS #include "conf.h" #include "config.h" #include "defaults.h" -#include "ncmpc.h" -#include "support.h" +#include "i18n.h" #include "command.h" #include "colors.h" #include "screen_list.h" +#include "options.h" +#include #include #include #include #include -#include #include -#include -#include -#include +#include +#include #define MAX_LINE_LENGTH 1024 -#define COMMENT_TOKEN '#' +#define COMMENT_TOKEN '#' /* configuration field names */ -#define CONF_ENABLE_COLORS "enable-colors" -#define CONF_AUTO_CENTER "auto-center" -#define CONF_WIDE_CURSOR "wide-cursor" -#define CONF_ENABLE_BELL "enable-bell" -#define CONF_KEY_DEFINITION "key" -#define CONF_COLOR "color" -#define CONF_COLOR_DEFINITION "colordef" -#define CONF_LIST_FORMAT "list-format" -#define CONF_STATUS_FORMAT "status-format" -#define CONF_XTERM_TITLE_FORMAT "xterm-title-format" -#define CONF_LIST_WRAP "wrap-around" -#define CONF_FIND_WRAP "find-wrap" -#define CONF_FIND_SHOW_LAST "find-show-last" -#define CONF_AUDIBLE_BELL "audible-bell" -#define CONF_VISIBLE_BELL "visible-bell" -#define CONF_XTERM_TITLE "set-xterm-title" -#define CONF_ENABLE_MOUSE "enable-mouse" -#define CONF_CROSSFADE_TIME "crossfade-time" -#define CONF_SEARCH_MODE "search-mode" -#define CONF_HIDE_CURSOR "hide-cursor" -#define CONF_SEEK_TIME "seek-time" -#define CONF_SCREEN_LIST "screen-list" -#define CONF_TIMEDISPLAY_TYPE "timedisplay-type" -#define CONF_HOST "host" -#define CONF_PORT "port" -#define CONF_PASSWORD "password" -#define CONF_LYRICS_TIMEOUT "lyrics-timeout" -#define CONF_SHOW_SPLASH "show-splash" -#define CONF_SCROLL "scroll" -#define CONF_SCROLL_SEP "scroll-sep" -#define CONF_VISIBLE_BITRATE "visible-bitrate" -#define CONF_WELCOME_SCREEN_LIST "welcome-screen-list" - -typedef enum { - KEY_PARSER_UNKNOWN, - KEY_PARSER_CHAR, - KEY_PARSER_DEC, - KEY_PARSER_HEX, - KEY_PARSER_DONE -} key_parser_state_t; - -static gboolean +#define CONF_ENABLE_COLORS "enable-colors" +#define CONF_SCROLL_OFFSET "scroll-offset" +#define CONF_AUTO_CENTER "auto-center" +#define CONF_WIDE_CURSOR "wide-cursor" +#define CONF_KEY_DEFINITION "key" +#define CONF_COLOR "color" +#define CONF_COLOR_DEFINITION "colordef" +#define CONF_LIST_FORMAT "list-format" +#define CONF_SEARCH_FORMAT "search-format" +#define CONF_STATUS_FORMAT "status-format" +#define CONF_XTERM_TITLE_FORMAT "xterm-title-format" +#define CONF_LIST_WRAP "wrap-around" +#define CONF_FIND_WRAP "find-wrap" +#define CONF_FIND_SHOW_LAST "find-show-last" +#define CONF_AUDIBLE_BELL "audible-bell" +#define CONF_VISIBLE_BELL "visible-bell" +#define CONF_BELL_ON_WRAP "bell-on-wrap" +#define CONF_STATUS_MESSAGE_TIME "status-message-time" +#define CONF_XTERM_TITLE "set-xterm-title" +#define CONF_ENABLE_MOUSE "enable-mouse" +#define CONF_CROSSFADE_TIME "crossfade-time" +#define CONF_SEARCH_MODE "search-mode" +#define CONF_HIDE_CURSOR "hide-cursor" +#define CONF_SEEK_TIME "seek-time" +#define CONF_SCREEN_LIST "screen-list" +#define CONF_TIMEDISPLAY_TYPE "timedisplay-type" +#define CONF_HOST "host" +#define CONF_PORT "port" +#define CONF_PASSWORD "password" +#define CONF_TIMEOUT "timeout" +#define CONF_LYRICS_TIMEOUT "lyrics-timeout" +#define CONF_SCROLL "scroll" +#define CONF_SCROLL_SEP "scroll-sep" +#define CONF_VISIBLE_BITRATE "visible-bitrate" +#define CONF_HARDWARE_CURSOR "hardware-cursor" +#define CONF_WELCOME_SCREEN_LIST "welcome-screen-list" +#define CONF_DISPLAY_TIME "display-time" +#define CONF_JUMP_PREFIX_ONLY "jump-prefix-only" +#define CONF_LYRICS_AUTOSAVE "lyrics-autosave" +#define CONF_LYRICS_SHOW_PLUGIN "lyrics-show-plugin" +#define CONF_TEXT_EDITOR "text-editor" +#define CONF_TEXT_EDITOR_ASK "text-editor-ask" +#define CONF_CHAT_PREFIX "chat-prefix" +#define CONF_SECOND_COLUMN "second-column" + +gcc_const +static bool +is_space_not_null(char ch) +{ + unsigned char uch = (unsigned char)ch; + return uch <= 0x20 && uch > 0; +} + +/** + * Returns the first non-space character (or a pointer to the null + * terminator). Similar to g_strchug(), but just moves the pointer + * forward without modifying the string contents. + */ +gcc_pure +static char * +skip_spaces(char *p) +{ + while (is_space_not_null(*p)) + ++p; + return p; +} + +static bool str2bool(char *str) { - if (!strcasecmp(str, "yes") || !strcasecmp(str, "true") || - !strcasecmp(str, "on") || !strcasecmp(str, "1")) - return TRUE; - return FALSE; + return strcasecmp(str, "yes") == 0 || strcasecmp(str, "true") == 0 || + strcasecmp(str, "on") == 0 || strcasecmp(str, "1") == 0; } -static int -parse_key_value(char *str, size_t len, char **end) +static void +print_error(const char *msg, const char *input) { - size_t i; - int value; - key_parser_state_t state; - - i=0; - value=0; - state=KEY_PARSER_UNKNOWN; - *end = str; - - while (i < len && state != KEY_PARSER_DONE) { - int next = 0; - int c = str[i]; - - if( i+1 str+len ) - *end = str+len; + ++p; - return value; + while (is_word_char(*p)) + ++p; + + return p; } static int -parse_key_definition(char *str) +parse_key_value(char *str, char **end) { - char buf[MAX_LINE_LENGTH]; - char *p, *end; - size_t len = strlen(str), i; - int j,key; - int keys[MAX_COMMAND_KEYS]; - command_t cmd; + if (*str == '\'') { + if (str[1] == '\'' || str[2] != '\'') { + print_error(_("Malformed hotkey definition"), str); + return -1; + } + + *end = str + 3; + return str[1]; + } else { + long value = strtol(str, end, 0); + if (*end == str) { + print_error(_("Malformed hotkey definition"), str); + return -1; + } + + return (int)value; + } +} +static bool +parse_key_definition(char *str) +{ /* get the command name */ - i=0; - j=0; + const size_t len = strlen(str); + size_t i = 0; + int j = 0; + char buf[MAX_LINE_LENGTH]; memset(buf, 0, MAX_LINE_LENGTH); - while( i=0 ) { - rgb[i++] = value; - while( p=0 && IS_WHITESPACE(line[i]) ) - { - line[i] = '\0'; - i--; - } - len = i+1; - - if( len>0 ) + char * test; + const int mode = strtol(value, &test, 10); + if (*test == '\0') { - i = 0; - /* skip whitespace */ - while( ienable_colors = str2bool(value); - } - /* auto center */ - else if( !strcasecmp(CONF_AUTO_CENTER, name) ) - { - options->auto_center = str2bool(value); - } - /* color assignment */ - else if( !strcasecmp(CONF_COLOR, name) ) - { - parse_color(value); - } - /* wide cursor */ - else if( !strcasecmp(CONF_WIDE_CURSOR, name) ) - { - options->wide_cursor = str2bool(value); - } - /* welcome screen list */ - else if (!strcasecmp(CONF_WELCOME_SCREEN_LIST, name)) { - options->welcome_screen_list = str2bool(value); - } - /* visible bitrate */ - else if (!strcasecmp(CONF_VISIBLE_BITRATE, name)) { - options->visible_bitrate = str2bool(value); - } - /* timer display type */ - else if( !strcasecmp(CONF_TIMEDISPLAY_TYPE, name) ) - { - g_free(options->timedisplay_type); - options->timedisplay_type=g_strdup(parse_timedisplay_type(value)); - } - /* color definition */ - else if( !strcasecmp(CONF_COLOR_DEFINITION, name) ) - { - parse_color_definition(value); - } - /* list format string */ - else if( !strcasecmp(CONF_LIST_FORMAT, name) ) - { - g_free(options->list_format); - options->list_format = get_format(value); - } - /* status format string */ - else if( !strcasecmp(CONF_STATUS_FORMAT, name) ) - { - g_free(options->status_format); - options->status_format = get_format(value); - } - /* xterm title format string */ - else if( !strcasecmp(CONF_XTERM_TITLE_FORMAT, name) ) - { - g_free(options->xterm_title_format); - options->xterm_title_format = get_format(value); - } - else if( !strcasecmp(CONF_LIST_WRAP, name) ) - { - options->list_wrap = str2bool(value); - } - else if( !strcasecmp(CONF_FIND_WRAP, name) ) - { - options->find_wrap = str2bool(value); - } - else if( !strcasecmp(CONF_FIND_SHOW_LAST,name) ) - { - options->find_show_last_pattern = str2bool(value); - } - else if( !strcasecmp(CONF_AUDIBLE_BELL, name) ) - { - options->audible_bell = str2bool(value); - } - else if( !strcasecmp(CONF_VISIBLE_BELL, name) ) - { - options->visible_bell = str2bool(value); - } - else if( !strcasecmp(CONF_XTERM_TITLE, name) ) - { - options->enable_xterm_title = str2bool(value); - } - else if( !strcasecmp(CONF_ENABLE_MOUSE, name) ) - { - options->enable_mouse = str2bool(value); - } - else if( !strcasecmp(CONF_CROSSFADE_TIME, name) ) - { - options->crossfade_time = atoi(value); - } - else if( !strcasecmp(CONF_SEARCH_MODE, name) ) - { - options->search_mode = atoi(value); - } - else if( !strcasecmp(CONF_HIDE_CURSOR, name) ) - { - options->hide_cursor = atoi(value); - } - else if( !strcasecmp(CONF_SEEK_TIME, name) ) - { - options->seek_time = atoi(value); - } - else if( !strcasecmp(CONF_SCREEN_LIST, name) ) - { - g_strfreev(options->screen_list); - options->screen_list = check_screen_list(value); - } - else if( !strcasecmp(CONF_SHOW_SPLASH, name) ) - { - /* the splash screen was removed */ - } - else if( !strcasecmp(CONF_HOST, name)) - { - options->host = get_format(value); - } - else if( !strcasecmp(CONF_PORT, name)) - { - options->port = atoi(get_format(value)); - } - else if( !strcasecmp(CONF_PASSWORD, name)) - { - options->password = get_format(value); - } - else if( !strcasecmp(CONF_LYRICS_TIMEOUT, name)) - { - options->lyrics_timeout = atoi(get_format(value)); - } - else if( !strcasecmp(CONF_SCROLL, name)) - { - options->scroll = str2bool(value); - } - else if( !strcasecmp(CONF_SCROLL_SEP, name)) - { - g_free(options->scroll_sep); - options->scroll_sep = get_format(value); - } - else +static bool +parse_line(char *line) +{ + /* get the name part */ + char *const name = line; + char *const name_end = after_unquoted_word(line); + if (name_end == NULL) + return false; + + line = skip_spaces(name_end); + if (*line == '=') { + ++line; + line = skip_spaces(line); + } else if (line == name_end) { + print_error(_("Missing '='"), name_end); + return false; + } + + *name_end = 0; + + /* get the value part */ + char *const value = line; + + /* key definition */ + if (!strcasecmp(CONF_KEY_DEFINITION, name)) + parse_key_definition(value); + /* enable colors */ + else if(!strcasecmp(CONF_ENABLE_COLORS, name)) +#ifdef ENABLE_COLORS + options.enable_colors = str2bool(value); +#else + {} +#endif + else if (!strcasecmp(CONF_SCROLL_OFFSET, name)) + options.scroll_offset = atoi(value); + /* auto center */ + else if (!strcasecmp(CONF_AUTO_CENTER, name)) + options.auto_center = str2bool(value); + /* color assignment */ + else if (!strcasecmp(CONF_COLOR, name)) +#ifdef ENABLE_COLORS + parse_color(value); +#else + {} +#endif + /* wide cursor */ + else if (!strcasecmp(CONF_WIDE_CURSOR, name)) + options.wide_cursor = str2bool(value); + else if (strcasecmp(name, CONF_HARDWARE_CURSOR) == 0) + options.hardware_cursor = str2bool(value); + /* welcome screen list */ + else if (!strcasecmp(CONF_WELCOME_SCREEN_LIST, name)) + options.welcome_screen_list = str2bool(value); + /* visible bitrate */ + else if (!strcasecmp(CONF_VISIBLE_BITRATE, name)) + options.visible_bitrate = str2bool(value); + /* timer display type */ + else if (!strcasecmp(CONF_TIMEDISPLAY_TYPE, name)) + options.display_remaining_time = parse_timedisplay_type(value); + /* color definition */ + else if (!strcasecmp(CONF_COLOR_DEFINITION, name)) +#ifdef ENABLE_COLORS + parse_color_definition(value); +#else + {} +#endif + /* list format string */ + else if (!strcasecmp(CONF_LIST_FORMAT, name)) { + g_free(options.list_format); + options.list_format = get_format(value); + /* search format string */ + } else if (!strcasecmp(CONF_SEARCH_FORMAT, name)) { + g_free(options.search_format); + options.search_format = get_format(value); + /* status format string */ + } else if (!strcasecmp(CONF_STATUS_FORMAT, name)) { + g_free(options.status_format); + options.status_format = get_format(value); + /* xterm title format string */ + } else if (!strcasecmp(CONF_XTERM_TITLE_FORMAT, name)) { + g_free(options.xterm_title_format); + options.xterm_title_format = get_format(value); + } else if (!strcasecmp(CONF_LIST_WRAP, name)) + options.list_wrap = str2bool(value); + else if (!strcasecmp(CONF_FIND_WRAP, name)) + options.find_wrap = str2bool(value); + else if (!strcasecmp(CONF_FIND_SHOW_LAST,name)) + options.find_show_last_pattern = str2bool(value); + else if (!strcasecmp(CONF_AUDIBLE_BELL, name)) + options.audible_bell = str2bool(value); + else if (!strcasecmp(CONF_VISIBLE_BELL, name)) + options.visible_bell = str2bool(value); + else if (!strcasecmp(CONF_BELL_ON_WRAP, name)) + options.bell_on_wrap = str2bool(value); + else if (!strcasecmp(CONF_STATUS_MESSAGE_TIME, name)) + options.status_message_time = atoi(value); + else if (!strcasecmp(CONF_XTERM_TITLE, name)) + options.enable_xterm_title = str2bool(value); + else if (!strcasecmp(CONF_ENABLE_MOUSE, name)) +#ifdef HAVE_GETMOUSE + options.enable_mouse = str2bool(value); +#else + {} +#endif + else if (!strcasecmp(CONF_CROSSFADE_TIME, name)) + options.crossfade_time = atoi(value); + else if (!strcasecmp(CONF_SEARCH_MODE, name)) + options.search_mode = get_search_mode(value); + else if (!strcasecmp(CONF_HIDE_CURSOR, name)) + options.hide_cursor = atoi(value); + else if (!strcasecmp(CONF_SEEK_TIME, name)) + options.seek_time = atoi(value); + else if (!strcasecmp(CONF_SCREEN_LIST, name)) { + g_strfreev(options.screen_list); + options.screen_list = check_screen_list(value); + } else if (!strcasecmp(CONF_HOST, name)) + options.host = get_format(value); + else if (!strcasecmp(CONF_PORT, name)) + options.port = atoi(get_format(value)); + else if (!strcasecmp(CONF_PASSWORD, name)) + options.password = get_format(value); + else if (!strcasecmp(CONF_TIMEOUT, name)) + options.timeout_ms = atoi(get_format(value)) + * 1000 /* seconds -> milliseconds */; + else if (!strcasecmp(CONF_LYRICS_TIMEOUT, name)) +#ifdef ENABLE_LYRICS_SCREEN + options.lyrics_timeout = atoi(get_format(value)); +#else + {} +#endif + else if (!strcasecmp(CONF_SCROLL, name)) + options.scroll = str2bool(value); + else if (!strcasecmp(CONF_SCROLL_SEP, name)) { + g_free(options.scroll_sep); + options.scroll_sep = get_format(value); + } else if (!strcasecmp(CONF_DISPLAY_TIME, name)) + /* obsolete, ignore */ + {} + else if (!strcasecmp(CONF_JUMP_PREFIX_ONLY, name)) +#ifdef NCMPC_MINI + {} +#else + options.jump_prefix_only = str2bool(value); +#endif + else if (!strcasecmp(CONF_LYRICS_AUTOSAVE, name)) +#ifdef ENABLE_LYRICS_SCREEN + options.lyrics_autosave = str2bool(value); +#else + {} +#endif + else if (!strcasecmp(CONF_LYRICS_SHOW_PLUGIN, name)) +#ifdef ENABLE_LYRICS_SCREEN + options.lyrics_show_plugin = str2bool(value); +#else + {} +#endif + else if (!strcasecmp(name, CONF_TEXT_EDITOR)) +#ifdef ENABLE_LYRICS_SCREEN { - match_found = 0; + g_free(options.text_editor); + options.text_editor = get_format(value); } +#else + {} +#endif + else if (!strcasecmp(name, CONF_TEXT_EDITOR_ASK)) +#ifdef ENABLE_LYRICS_SCREEN + options.text_editor_ask = str2bool(value); +#else + {} +#endif + else if (!strcasecmp(name, CONF_CHAT_PREFIX)) +#ifdef ENABLE_CHAT_SCREEN + options.chat_prefix = get_format(value); +#else + {} +#endif + else if (!strcasecmp(CONF_SECOND_COLUMN, name)) +#ifdef NCMPC_MINI + {} +#else + options.second_column = str2bool(value); +#endif + else { + print_error(_("Unknown configuration parameter"), name); + return false; + } - if( !match_found ) - fprintf(stderr, - _("Unknown configuration parameter: %s\n"), - name); - } - } - } - - if( free_filename ) - g_free(filename); - - return 0; + return true; } -int +static int +read_rc_file(char *filename) +{ + assert(filename != NULL); + + FILE *file = fopen(filename, "r"); + if (file == NULL) { + perror(filename); + return -1; + } + + char line[MAX_LINE_LENGTH]; + while (fgets(line, sizeof(line), file) != NULL) { + char *p = skip_spaces(line); + + if (*p != 0 && *p != COMMENT_TOKEN) + parse_line(g_strchomp(p)); + } + + fclose(file); + return 0; +} + +bool check_user_conf_dir(void) { - int retval; char *directory = g_build_filename(g_get_home_dir(), "." PACKAGE, NULL); if (g_file_test(directory, G_FILE_TEST_IS_DIR)) { g_free(directory); - return 0; + return true; } - retval = mkdir(directory, 0755); + bool success = g_mkdir(directory, 0755) == 0; g_free(directory); - return retval; + return success; } char * -get_user_key_binding_filename(void) +build_user_conf_filename(void) { - return g_build_filename(g_get_home_dir(), "." PACKAGE, "keys", NULL); +#ifdef WIN32 + return g_build_filename(g_get_user_config_dir(), PACKAGE, "ncmpc.conf", NULL); +#else + return g_build_filename(g_get_home_dir(), "." PACKAGE, "config", NULL); +#endif } - -int -read_configuration(options_t *options) +char * +build_system_conf_filename(void) { - char *filename = NULL; - - /* check for command line configuration file */ - if( options->config_file ) - filename = g_strdup(options->config_file); - - /* check for user configuration ~/.ncmpc/config */ - if( filename == NULL ) - { - filename = g_build_filename(g_get_home_dir(), - "." PACKAGE, "config", NULL); - if( !g_file_test(filename, G_FILE_TEST_IS_REGULAR) ) - { - g_free(filename); - filename = NULL; - } - } +#ifdef WIN32 + const gchar* const *system_data_dirs; + gchar *pathname = NULL; - /* check for global configuration SYSCONFDIR/ncmpc/config */ - if( filename == NULL ) - { - filename = g_build_filename(SYSCONFDIR, PACKAGE, "config", NULL); - if( !g_file_test(filename, G_FILE_TEST_IS_REGULAR) ) - { - g_free(filename); - filename = NULL; - } - } - - /* load configuration */ - if( filename ) - { - read_rc_file(filename, options); - g_free(filename); - filename = NULL; - } - - /* check for command line key binding file */ - if( options->key_file ) - filename = g_strdup(options->key_file); - - /* check for user key bindings ~/.ncmpc/keys */ - if( filename == NULL ) - { - filename = get_user_key_binding_filename(); - if( !g_file_test(filename, G_FILE_TEST_IS_REGULAR) ) + for (system_data_dirs = g_get_system_config_dirs (); *system_data_dirs != NULL; system_data_dirs++) { - g_free(filename); - filename = NULL; + pathname = g_build_filename(*system_data_dirs, PACKAGE, "ncmpc.conf", NULL); + if (g_file_test(pathname, G_FILE_TEST_EXISTS)) + { + break; + } + else + { + g_free (pathname); + pathname = NULL; + } } - } + return pathname; +#else + return g_build_filename(SYSCONFDIR, PACKAGE, "config", NULL); +#endif +} + +char * +build_user_key_binding_filename(void) +{ +#ifdef WIN32 + return g_build_filename(g_get_user_config_dir(), PACKAGE, "keys.conf", NULL); +#else + return g_build_filename(g_get_home_dir(), "." PACKAGE, "keys", NULL); +#endif +} - /* check for global key bindings SYSCONFDIR/ncmpc/keys */ - if( filename == NULL ) - { - filename = g_build_filename(SYSCONFDIR, PACKAGE, "keys", NULL); - if( !g_file_test(filename, G_FILE_TEST_IS_REGULAR) ) +static char * +g_build_system_key_binding_filename(void) +{ +#ifdef WIN32 + const gchar* const *system_data_dirs; + gchar *pathname = NULL; + + for (system_data_dirs = g_get_system_config_dirs (); *system_data_dirs != NULL; system_data_dirs++) { - g_free(filename); - filename = NULL; + pathname = g_build_filename(*system_data_dirs, PACKAGE, "keys.conf", NULL); + if (g_file_test(pathname, G_FILE_TEST_EXISTS)) + { + break; + } + else + { + g_free (pathname); + pathname = NULL; + } } - } + return pathname; +#else + return g_build_filename(SYSCONFDIR, PACKAGE, "keys", NULL); +#endif +} + +static char * +find_config_file(void) +{ + /* check for command line configuration file */ + if (options.config_file != NULL) + return g_strdup(options.config_file); + + /* check for user configuration ~/.ncmpc/config */ + char *filename = build_user_conf_filename(); + if (g_file_test(filename, G_FILE_TEST_IS_REGULAR)) + return filename; + + g_free(filename); + + /* check for global configuration SYSCONFDIR/ncmpc/config */ + filename = build_system_conf_filename(); + if (g_file_test(filename, G_FILE_TEST_IS_REGULAR)) + return filename; + + g_free(filename); + return NULL; +} - /* load key bindings */ - if( filename ) - { - read_rc_file(filename, options); - g_free(filename); - filename = NULL; - } +static char * +find_keys_file(void) +{ + /* check for command line key binding file */ + if (options.key_file != NULL) + return g_strdup(options.key_file); - return 0; + /* check for user key bindings ~/.ncmpc/keys */ + char *filename = build_user_key_binding_filename(); + if (g_file_test(filename, G_FILE_TEST_IS_REGULAR)) + return filename; + + g_free(filename); + + /* check for global key bindings SYSCONFDIR/ncmpc/keys */ + filename = g_build_system_key_binding_filename(); + if (g_file_test(filename, G_FILE_TEST_IS_REGULAR)) + return filename; + + g_free(filename); + return NULL; +} + +void +read_configuration(void) +{ + /* load configuration */ + char *filename = find_config_file(); + if (filename != NULL) { + read_rc_file(filename); + g_free(filename); + } + + /* load key bindings */ + filename = find_keys_file(); + if (filename != NULL) { + read_rc_file(filename); + g_free(filename); + } }