From fdc6f61257cd72259d5efce4bef7512dfefd5ed9 Mon Sep 17 00:00:00 2001 From: Ian Barwick Date: Wed, 29 Apr 2020 13:28:28 +0900 Subject: [PATCH] Pass base configuration file directory to configuration parser If provided, the parser will use this to process include directives with unqualified filenames. --- configfile-scan.l | 49 +++++++++++++++++++++++++---------------------- configfile.c | 11 ++++++++--- configfile.h | 4 ++-- 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/configfile-scan.l b/configfile-scan.l index acff07fb..c4ab5025 100644 --- a/configfile-scan.l +++ b/configfile-scan.l @@ -38,11 +38,11 @@ static sigjmp_buf *CONF_flex_fatal_jmp; static char *CONF_scanstr(const char *s); static int CONF_flex_fatal(const char *msg); -static bool ProcessConfigFile(const char *config_file, const char *calling_file, KeyValueList *contents, t_configuration_options *options, ItemList *error_list, ItemList *warning_list); +static bool ProcessConfigFile(const char *base_dir, const char *config_file, const char *calling_file, KeyValueList *contents, t_configuration_options *options, ItemList *error_list, ItemList *warning_list); static bool ProcessConfigFp(FILE *fp, const char *config_file, KeyValueList *contents, t_configuration_options *options, ItemList *error_list, ItemList *warning_list); -static char *AbsoluteConfigLocation(const char *location, const char *calling_file); + static char *AbsoluteConfigLocation(const char *base_dir, const char *location, const char *calling_file); %} @@ -95,19 +95,19 @@ STRING \'([^'\\\n]|\\.|\'\')*\' %% extern bool -ProcessRepmgrConfigFile(const char *config_file, t_configuration_options *options, ItemList *error_list, ItemList *warning_list) +ProcessRepmgrConfigFile(const char *config_file, const char *base_dir, t_configuration_options *options, ItemList *error_list, ItemList *warning_list) { - return ProcessConfigFile(config_file, NULL, NULL, options, error_list, warning_list); + return ProcessConfigFile(base_dir, config_file, NULL, NULL, options, error_list, warning_list); } extern bool -ProcessPostgresConfigFile(const char *config_file, KeyValueList *contents, ItemList *error_list, ItemList *warning_list) +ProcessPostgresConfigFile(const char *config_file, const char *base_dir, KeyValueList *contents, ItemList *error_list, ItemList *warning_list) { - return ProcessConfigFile(config_file, NULL, contents, NULL, error_list, warning_list); + return ProcessConfigFile(base_dir, config_file, NULL, contents, NULL, error_list, warning_list); } static bool -ProcessConfigFile(const char *config_file, const char *calling_file, KeyValueList *contents, t_configuration_options *options, ItemList *error_list, ItemList *warning_list) +ProcessConfigFile(const char *base_dir, const char *config_file, const char *calling_file, KeyValueList *contents, t_configuration_options *options, ItemList *error_list, ItemList *warning_list) { char *abs_path; bool success = true; @@ -123,7 +123,7 @@ ProcessConfigFile(const char *config_file, const char *calling_file, KeyValueLis return false; } - abs_path = AbsoluteConfigLocation(config_file, calling_file); + abs_path = AbsoluteConfigLocation(base_dir, config_file, calling_file); // XXX reject direct recursion. @@ -398,31 +398,34 @@ CONF_scanstr(const char *s) * the directory holding the calling file, or to DataDir if no calling file. */ static char * -AbsoluteConfigLocation(const char *location, const char *calling_file) +AbsoluteConfigLocation(const char *base_dir, const char *location, const char *calling_file) { char abs_path[MAXPGPATH]; if (is_absolute_path(location)) return strdup(location); + + if (calling_file != NULL) + { + strlcpy(abs_path, calling_file, sizeof(abs_path)); + get_parent_directory(abs_path); + join_path_components(abs_path, abs_path, location); + canonicalize_path(abs_path); + } + else if (base_dir != NULL) + { + join_path_components(abs_path, base_dir, location); + canonicalize_path(abs_path); + } else { - if (calling_file != NULL) - { - strlcpy(abs_path, calling_file, sizeof(abs_path)); - get_parent_directory(abs_path); - join_path_components(abs_path, abs_path, location); - canonicalize_path(abs_path); - } - else - { - /*AssertState(DataDir); - join_path_components(abs_path, DataDir, location); - canonicalize_path(abs_path);*/ - } - return strdup(abs_path); + strlcpy(abs_path, location, sizeof(abs_path)); } + + return strdup(abs_path); } + /* * Flex fatal errors bring us here. Stash the error message and jump back to * ParseConfigFp(). Assume all msg arguments point to string constants; this diff --git a/configfile.c b/configfile.c index 42bdb029..dc9ed907 100644 --- a/configfile.c +++ b/configfile.c @@ -279,6 +279,7 @@ static void _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *warning_list) { FILE *fp; + char base_directory[MAXPGPATH]; /* * Clear lists pointing to allocated memory @@ -497,8 +498,13 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList * fclose(fp); + + strncpy(base_directory, config_file_path, MAXPGPATH); + canonicalize_path(base_directory); + get_parent_directory(base_directory); + // XXX fail here if processing issue found - (void) ProcessRepmgrConfigFile(config_file_path, options, error_list, warning_list); + (void) ProcessRepmgrConfigFile(config_file_path, base_directory, options, error_list, warning_list); /* check required parameters */ @@ -1970,8 +1976,7 @@ modify_auto_conf(const char *data_dir, KeyValueList *items) } fclose(fp); - success = ProcessPostgresConfigFile(auto_conf.data, &config, NULL, NULL); - + success = ProcessPostgresConfigFile(auto_conf.data, NULL, &config, NULL, NULL); if (success == false) { diff --git a/configfile.h b/configfile.h index cc2e64c2..96854ea5 100644 --- a/configfile.h +++ b/configfile.h @@ -351,8 +351,8 @@ const char *print_connection_check_type(ConnectionCheckType type); extern bool modify_auto_conf(const char *data_dir, KeyValueList *items); -extern bool ProcessRepmgrConfigFile(const char *config_file, t_configuration_options *options, ItemList *error_list, ItemList *warning_list); +extern bool ProcessRepmgrConfigFile(const char *config_file, const char *base_dir, t_configuration_options *options, ItemList *error_list, ItemList *warning_list); -extern bool ProcessPostgresConfigFile(const char *config_file, KeyValueList *contents, ItemList *error_list, ItemList *warning_list); +extern bool ProcessPostgresConfigFile(const char *config_file, const char *base_dir, KeyValueList *contents, ItemList *error_list, ItemList *warning_list); #endif /* _REPMGR_CONFIGFILE_H_ */