You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-08 14:02:17 +03:00
CONC-327:
Add support for !include an !includedir in configuration files
This commit is contained in:
@@ -39,6 +39,12 @@ static const char *ini_exts[]= {"cnf", 0};
|
|||||||
char **configuration_dirs= NULL;
|
char **configuration_dirs= NULL;
|
||||||
#define MAX_CONFIG_DIRS 6
|
#define MAX_CONFIG_DIRS 6
|
||||||
|
|
||||||
|
my_bool _mariadb_read_options(MYSQL *mysql,
|
||||||
|
const char *config_dir,
|
||||||
|
const char *config_file,
|
||||||
|
const char *group,
|
||||||
|
unsigned int recursion);
|
||||||
|
|
||||||
static int add_cfg_dir(char **cfg_dirs, const char *directory)
|
static int add_cfg_dir(char **cfg_dirs, const char *directory)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -139,7 +145,8 @@ static my_bool is_group(char *ptr, const char **groups)
|
|||||||
|
|
||||||
static my_bool _mariadb_read_options_from_file(MYSQL *mysql,
|
static my_bool _mariadb_read_options_from_file(MYSQL *mysql,
|
||||||
const char *config_file,
|
const char *config_file,
|
||||||
const char *group)
|
const char *group,
|
||||||
|
unsigned int recursion)
|
||||||
{
|
{
|
||||||
uint line=0;
|
uint line=0;
|
||||||
my_bool read_values= 0, found_group= 0, is_escaped= 0, is_quoted= 0;
|
my_bool read_values= 0, found_group= 0, is_escaped= 0, is_quoted= 0;
|
||||||
@@ -175,6 +182,23 @@ static my_bool _mariadb_read_options_from_file(MYSQL *mysql,
|
|||||||
is_quoted= !is_quoted;
|
is_quoted= !is_quoted;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/* CONC- 327: !includedir and !include */
|
||||||
|
if (*ptr == '!')
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
ptr++;
|
||||||
|
if (!(val= strchr(ptr, ' ')))
|
||||||
|
continue;
|
||||||
|
*val++= 0;
|
||||||
|
end= strchr(val, 0);
|
||||||
|
for ( ; isspace(end[-1]) ; end--) ; /* Remove end space */
|
||||||
|
*end= 0;
|
||||||
|
if (!strcmp(ptr, "includedir"))
|
||||||
|
_mariadb_read_options(mysql, (const char *)val, NULL, group, recursion + 1);
|
||||||
|
else if (!strcmp(ptr, "include"))
|
||||||
|
_mariadb_read_options(mysql, NULL, (const char *)val, group, recursion + 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (*ptr == '#' || *ptr == ';' || !*ptr)
|
if (*ptr == '#' || *ptr == ';' || !*ptr)
|
||||||
continue;
|
continue;
|
||||||
is_escaped= (*ptr == '\\');
|
is_escaped= (*ptr == '\\');
|
||||||
@@ -286,19 +310,37 @@ err:
|
|||||||
|
|
||||||
|
|
||||||
my_bool _mariadb_read_options(MYSQL *mysql,
|
my_bool _mariadb_read_options(MYSQL *mysql,
|
||||||
|
const char *config_dir,
|
||||||
const char *config_file,
|
const char *config_file,
|
||||||
const char *group)
|
const char *group,
|
||||||
|
unsigned int recursion)
|
||||||
{
|
{
|
||||||
int i= 0,
|
int i= 0,
|
||||||
exts,
|
exts,
|
||||||
errors= 0;
|
errors= 0;
|
||||||
char filename[FN_REFLEN + 1];
|
char filename[FN_REFLEN + 1];
|
||||||
|
unsigned int recursion_stop= 64;
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
char *env;
|
char *env;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (config_file)
|
if (recursion >= recursion_stop)
|
||||||
return _mariadb_read_options_from_file(mysql, config_file, group);
|
return 1;
|
||||||
|
|
||||||
|
if (config_file && config_file[0])
|
||||||
|
return _mariadb_read_options_from_file(mysql, config_file, group, recursion);
|
||||||
|
|
||||||
|
if (config_dir && config_dir[0])
|
||||||
|
{
|
||||||
|
for (exts= 0; ini_exts[exts]; exts++)
|
||||||
|
{
|
||||||
|
snprintf(filename, FN_REFLEN,
|
||||||
|
"%s%cmy.%s", config_dir, FN_LIBCHAR, ini_exts[exts]);
|
||||||
|
if (!access(filename, R_OK))
|
||||||
|
errors+= _mariadb_read_options_from_file(mysql, filename, group, recursion);
|
||||||
|
}
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
for (i=0; i < MAX_CONFIG_DIRS && configuration_dirs[i]; i++)
|
for (i=0; i < MAX_CONFIG_DIRS && configuration_dirs[i]; i++)
|
||||||
{
|
{
|
||||||
@@ -307,7 +349,7 @@ my_bool _mariadb_read_options(MYSQL *mysql,
|
|||||||
snprintf(filename, FN_REFLEN,
|
snprintf(filename, FN_REFLEN,
|
||||||
"%s%cmy.%s", configuration_dirs[i], FN_LIBCHAR, ini_exts[exts]);
|
"%s%cmy.%s", configuration_dirs[i], FN_LIBCHAR, ini_exts[exts]);
|
||||||
if (!access(filename, R_OK))
|
if (!access(filename, R_OK))
|
||||||
errors+= _mariadb_read_options_from_file(mysql, filename, group);
|
errors+= _mariadb_read_options_from_file(mysql, filename, group, recursion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
@@ -319,7 +361,7 @@ my_bool _mariadb_read_options(MYSQL *mysql,
|
|||||||
snprintf(filename, FN_REFLEN,
|
snprintf(filename, FN_REFLEN,
|
||||||
"%s%c.my.%s", env, FN_LIBCHAR, ini_exts[exts]);
|
"%s%c.my.%s", env, FN_LIBCHAR, ini_exts[exts]);
|
||||||
if (!access(filename, R_OK))
|
if (!access(filename, R_OK))
|
||||||
errors+= _mariadb_read_options_from_file(mysql, filename, group);
|
errors+= _mariadb_read_options_from_file(mysql, filename, group, recursion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -106,8 +106,7 @@ extern int mthd_stmt_fetch_row(MYSQL_STMT *stmt, unsigned char **row);
|
|||||||
extern int mthd_stmt_fetch_to_bind(MYSQL_STMT *stmt, unsigned char *row);
|
extern int mthd_stmt_fetch_to_bind(MYSQL_STMT *stmt, unsigned char *row);
|
||||||
extern int mthd_stmt_read_all_rows(MYSQL_STMT *stmt);
|
extern int mthd_stmt_read_all_rows(MYSQL_STMT *stmt);
|
||||||
extern void mthd_stmt_flush_unbuffered(MYSQL_STMT *stmt);
|
extern void mthd_stmt_flush_unbuffered(MYSQL_STMT *stmt);
|
||||||
extern my_bool _mariadb_read_options(MYSQL *mysql, const char *config_file,
|
extern my_bool _mariadb_read_options(MYSQL *mysql, const char *dir, const char *config_file, char *group, unsigned int recursion);
|
||||||
char *group);
|
|
||||||
extern unsigned char *mysql_net_store_length(unsigned char *packet, size_t length);
|
extern unsigned char *mysql_net_store_length(unsigned char *packet, size_t length);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
@@ -1203,10 +1202,10 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
/* use default options */
|
/* use default options */
|
||||||
if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
|
if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
|
||||||
{
|
{
|
||||||
_mariadb_read_options(mysql,
|
_mariadb_read_options(mysql, NULL,
|
||||||
(mysql->options.my_cnf_file ?
|
(mysql->options.my_cnf_file ?
|
||||||
mysql->options.my_cnf_file : NULL),
|
mysql->options.my_cnf_file : NULL),
|
||||||
mysql->options.my_cnf_group);
|
mysql->options.my_cnf_group, 0);
|
||||||
free(mysql->options.my_cnf_file);
|
free(mysql->options.my_cnf_file);
|
||||||
free(mysql->options.my_cnf_group);
|
free(mysql->options.my_cnf_group);
|
||||||
mysql->options.my_cnf_file=mysql->options.my_cnf_group=0;
|
mysql->options.my_cnf_file=mysql->options.my_cnf_group=0;
|
||||||
|
@@ -1026,6 +1026,9 @@ static int test_reset(MYSQL *mysql)
|
|||||||
if (mysql_get_server_version(mysql) < 100200)
|
if (mysql_get_server_version(mysql) < 100200)
|
||||||
return SKIP;
|
return SKIP;
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
|
||||||
|
check_mysql_rc(rc, mysql);
|
||||||
|
|
||||||
rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
|
rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
|
||||||
check_mysql_rc(rc, mysql);
|
check_mysql_rc(rc, mysql);
|
||||||
|
|
||||||
@@ -1410,10 +1413,82 @@ static int test_conc317(MYSQL *unused __attribute__((unused)))
|
|||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_conc327(MYSQL *unused __attribute__((unused)))
|
||||||
|
{
|
||||||
|
MYSQL *mysql;
|
||||||
|
my_bool reconnect = 0;
|
||||||
|
FILE *fp1= NULL, *fp2= NULL;
|
||||||
|
const char *env= getenv("MYSQL_TMP_DIR");
|
||||||
|
char cnf_file1[FN_REFLEN + 1];
|
||||||
|
char cnf_file2[FN_REFLEN + 1];
|
||||||
|
|
||||||
|
if (travis_test)
|
||||||
|
return SKIP;
|
||||||
|
|
||||||
|
if (!env)
|
||||||
|
env= "/tmp";
|
||||||
|
|
||||||
|
setenv("HOME", env, 1);
|
||||||
|
|
||||||
|
snprintf(cnf_file1, FN_REFLEN, "%s%c.my.cnf", env, FN_LIBCHAR);
|
||||||
|
snprintf(cnf_file2, FN_REFLEN, "%s%c.my.tmp", env, FN_LIBCHAR);
|
||||||
|
|
||||||
|
FAIL_IF(!access(cnf_file1, R_OK), "access");
|
||||||
|
|
||||||
|
fp1= fopen(cnf_file1, "w");
|
||||||
|
fp2= fopen(cnf_file2, "w");
|
||||||
|
FAIL_IF(!fp1 || !fp2, "fopen failed");
|
||||||
|
|
||||||
|
fprintf(fp1, "!include %s\n", cnf_file2);
|
||||||
|
|
||||||
|
fprintf(fp2, "[client]\ndefault-character-set = latin2\nreconnect= 1\n");
|
||||||
|
fclose(fp1);
|
||||||
|
fclose(fp2);
|
||||||
|
|
||||||
|
mysql= mysql_init(NULL);
|
||||||
|
mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "");
|
||||||
|
my_test_connect(mysql, hostname, username, password,
|
||||||
|
schema, 0, socketname, 0);
|
||||||
|
|
||||||
|
remove(cnf_file1);
|
||||||
|
remove(cnf_file2);
|
||||||
|
|
||||||
|
FAIL_IF(strcmp(mysql_character_set_name(mysql), "latin2"), "expected charset latin2");
|
||||||
|
mysql_get_optionv(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
FAIL_IF(reconnect != 1, "expected reconnect=1");
|
||||||
|
mysql_close(mysql);
|
||||||
|
|
||||||
|
snprintf(cnf_file1, FN_REFLEN, "%s%cmy.cnf", env, FN_LIBCHAR);
|
||||||
|
fp1= fopen(cnf_file1, "w");
|
||||||
|
fp2= fopen(cnf_file2, "w");
|
||||||
|
FAIL_IF(!fp1 || !fp2, "fopen failed");
|
||||||
|
|
||||||
|
fprintf(fp2, "!includedir %s\n", env);
|
||||||
|
|
||||||
|
fprintf(fp1, "[client]\ndefault-character-set = latin2\nreconnect= 1\n");
|
||||||
|
fclose(fp1);
|
||||||
|
fclose(fp2);
|
||||||
|
mysql= mysql_init(NULL);
|
||||||
|
mysql_options(mysql, MYSQL_READ_DEFAULT_FILE, cnf_file2);
|
||||||
|
my_test_connect(mysql, hostname, username, password,
|
||||||
|
schema, 0, socketname, 0);
|
||||||
|
|
||||||
|
remove(cnf_file1);
|
||||||
|
remove(cnf_file2);
|
||||||
|
|
||||||
|
FAIL_IF(strcmp(mysql_character_set_name(mysql), "latin2"), "expected charset latin2");
|
||||||
|
mysql_get_optionv(mysql, MYSQL_OPT_RECONNECT, &reconnect);
|
||||||
|
FAIL_IF(reconnect != 1, "expected reconnect=1");
|
||||||
|
mysql_close(mysql);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct my_tests_st my_tests[] = {
|
struct my_tests_st my_tests[] = {
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
{"test_conc327", test_conc327, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
{"test_conc317", test_conc317, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_conc317", test_conc317, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
#endif
|
#endif
|
||||||
{"test_conc315", test_conc315, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_conc315", test_conc315, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
|
Reference in New Issue
Block a user