From 9e112497785d5e7ce627c825aa39e2b17a5aa73e Mon Sep 17 00:00:00 2001 From: Chuck Bell Date: Tue, 19 Jul 2011 10:27:15 -0400 Subject: BUG#12707948 : mysql_plugin cannot run on Windows Patch fixes an issue with reading basedir on Windows. It fixes how the code interprets opt_basedir on Windows by adding the correct path separators and quotes for paths with spaces. BUG#12664302 : mysql_plugin cannot recognize the plugin config file Patch fixes an issue with reading a plugin config file. It adds more information to the error messages to ensure the user is using the options correctly. Also deals with paths with spacs on Windows. --- client/mysql_plugin.c | 136 ++++++++++++++++++++--- mysql-test/include/daemon_example.ini | 8 -- mysql-test/include/daemon_example_bad_format.ini | 10 +- mysql-test/include/daemon_example_bad_soname.ini | 9 ++ mysql-test/r/mysql_plugin.result | 2 +- mysql-test/t/mysql_plugin.test | 2 +- 6 files changed, 136 insertions(+), 31 deletions(-) delete mode 100644 mysql-test/include/daemon_example.ini create mode 100644 mysql-test/include/daemon_example_bad_soname.ini diff --git a/client/mysql_plugin.c b/client/mysql_plugin.c index d904d2dabcd..2da9c2d6f16 100644 --- a/client/mysql_plugin.c +++ b/client/mysql_plugin.c @@ -228,6 +228,69 @@ static int run_command(char* cmd, const char *mode) } +#ifdef __WIN__ +/** + Check to see if there are spaces in a path. + + @param[in] path The Windows path to examine. + + @retval int spaces found = 1, no spaces = 0 +*/ +static int has_spaces(const char *path) +{ + if (strchr(path, ' ') != NULL) + return 1; + return 0; +} + + +/** + Convert a Unix path to a Windows path. + + @param[in] path The Windows path to examine. + + @returns string containing path with / changed to \\ +*/ +static char *convert_path(const char *argument) +{ + /* Convert / to \\ to make Windows paths */ + char *winfilename= my_strdup(argument, MYF(MY_FAE)); + char *pos, *end; + int length= strlen(argument); + + for (pos= winfilename, end= pos+length ; pos < end ; pos++) + { + if (*pos == '/') + { + *pos= '\\'; + } + } + return winfilename; +} + + +/** + Add quotes if the path has spaces in it. + + @param[in] path The Windows path to examine. + + @returns string containing excaped quotes if spaces found in path +*/ +static char *add_quotes(const char *path) +{ + char windows_cmd_friendly[FN_REFLEN]; + + if (has_spaces(path)) + snprintf(windows_cmd_friendly, sizeof(windows_cmd_friendly), + "\"%s\"", path); + else + snprintf(windows_cmd_friendly, sizeof(windows_cmd_friendly), + "%s", path); + return my_strdup(windows_cmd_friendly, MYF(MY_FAE)); +} +#endif + + /** Get the default values from the my.cnf file. @@ -259,11 +322,26 @@ static int get_default_values() { if ((error= make_tempfile(defaults_file, "txt"))) goto exit; + +#ifdef __WIN__ + { + char *format_str= 0; + + if (has_spaces(tool_path) || has_spaces(defaults_file)) + format_str = "\"%s mysqld > %s\""; + else + format_str = "%s mysqld > %s"; + + snprintf(defaults_cmd, sizeof(defaults_cmd), format_str, + add_quotes(tool_path), add_quotes(defaults_file)); + } +#else snprintf(defaults_cmd, sizeof(defaults_cmd), "%s mysqld > %s", tool_path, defaults_file); +#endif /* Execute the command */ - if (opt_verbose > 1) + if (opt_verbose) { printf("# Command: %s\n", defaults_cmd); } @@ -517,14 +595,14 @@ static int load_plugin_data(char *plugin_name, char *config_file) } if (!file_exists(opt_plugin_ini)) { - reason= "File does not exist."; + reason= (char *)"File does not exist."; goto error; } file_ptr= fopen(opt_plugin_ini, "r"); if (file_ptr == NULL) { - reason= "Cannot open file."; + reason= (char *)"Cannot open file."; goto error; } @@ -542,6 +620,12 @@ static int load_plugin_data(char *plugin_name, char *config_file) } if (res == NULL) { + if (i < 1) + { + reason= (char *)"Bad format in plugin configuration file."; + fclose(file_ptr); + goto error; + } break; } if ((line[0] == '#') || (line[0] == '\n')) // skip comment and blank lines @@ -552,11 +636,6 @@ static int load_plugin_data(char *plugin_name, char *config_file) { /* save so_name */ plugin_data.so_name= my_strdup(line, MYF(MY_WME)); - if (plugin_data.so_name == NULL) - { - reason= "Cannot read library name."; - goto error; - } /* Add proper file extension for soname */ strcat((char *)plugin_data.so_name, FN_SOEXT); i++; @@ -574,6 +653,7 @@ static int load_plugin_data(char *plugin_name, char *config_file) } } } + fclose(file_ptr); return 0; @@ -735,6 +815,19 @@ static int process_options(int argc, char *argv[], char *operation) goto exit; } + /* Add a trailing directory separator if not present */ + if (opt_basedir) + { + i= (int)strlength(opt_basedir); + if (opt_basedir[i-1] != FN_LIBCHAR || opt_basedir[i-1] != FN_LIBCHAR2) +#ifdef __WIN__ + if (opt_basedir[i-1] != '/') + strcat(opt_basedir, "//"); +#else + strcat(opt_basedir, FN_DIRSEP); +#endif + } + /* If the user did not specify the option to skip loading defaults from a config file and the required options are not present or there was an error @@ -758,13 +851,6 @@ static int process_options(int argc, char *argv[], char *operation) goto exit; } - /* Add a trailing directory separator if not present */ - i= (int)strlength(opt_basedir); - if (opt_basedir[i-1] != FN_LIBCHAR || opt_basedir[i-1] != FN_LIBCHAR2) - { - strcat(opt_basedir, FN_DIRSEP); - } - if (opt_verbose) { printf("# basedir = %s\n", opt_basedir); @@ -1029,12 +1115,30 @@ static int bootstrap_server(char *server_path, char *bootstrap_file) int error= 0; int ret= 0; +#ifdef __WIN__ + char *format_str= 0; + char *verbose_str= ""; + + if (opt_verbose) + strcat(verbose_str, "--console"); + if (has_spaces(opt_datadir) || has_spaces(opt_basedir) || + has_spaces(bootstrap_file)) + format_str= "\"%s %s --bootstrap --datadir=%s --basedir=%s < %s\""; + else + format_str= "%s %s --bootstrap --datadir=%s --basedir=%s < %s"; + + snprintf(bootstrap_cmd, sizeof(bootstrap_cmd), format_str, + add_quotes(convert_path(server_path)), verbose_str, + add_quotes(opt_datadir), add_quotes(opt_basedir), + add_quotes(bootstrap_file)); +#else snprintf(bootstrap_cmd, sizeof(bootstrap_cmd), "%s --no-defaults --bootstrap --datadir=%s --basedir=%s" " < %s", server_path, opt_datadir, opt_basedir, bootstrap_file); +#endif /* Execute the command */ - if (opt_verbose > 1) + if (opt_verbose) { printf("# Command: %s\n", bootstrap_cmd); } diff --git a/mysql-test/include/daemon_example.ini b/mysql-test/include/daemon_example.ini deleted file mode 100644 index 2fbfca203ea..00000000000 --- a/mysql-test/include/daemon_example.ini +++ /dev/null @@ -1,8 +0,0 @@ -# -# Plugin initialization file. Format using comma-separated values: -# name, libname, symbol, [symbol, ] -# Note: trailing comma is required. -# -# File is used by mysql_plugin.test for testing missing library error. -# -daemon_example, libdaemon_example, daemon_example, diff --git a/mysql-test/include/daemon_example_bad_format.ini b/mysql-test/include/daemon_example_bad_format.ini index a08e50632c9..8f880ef0ba0 100644 --- a/mysql-test/include/daemon_example_bad_format.ini +++ b/mysql-test/include/daemon_example_bad_format.ini @@ -1,8 +1,8 @@ # -# Plugin initialization file. Format using comma-separated values: -# name, libname, symbol, [symbol, ] -# Note: trailing comma is required. +# Plugin configuration file. Place the following on a separate line: # -# File is used by mysql_plugin.test for testing bad library name. +# library binary file name (without .so or .dll) +# component_name +# [component_name] - additional components in plugin # -daemon_BADNAME, libdaemon_example, daemon_example, +libdaemon_example diff --git a/mysql-test/include/daemon_example_bad_soname.ini b/mysql-test/include/daemon_example_bad_soname.ini new file mode 100644 index 00000000000..5f42b5a6214 --- /dev/null +++ b/mysql-test/include/daemon_example_bad_soname.ini @@ -0,0 +1,9 @@ +# +# Plugin configuration file. Place the following on a separate line: +# +# library binary file name (without .so or .dll) +# component_name +# [component_name] - additional components in plugin +# +libdaemon_BADNAME +daemon_BADNAME diff --git a/mysql-test/r/mysql_plugin.result b/mysql-test/r/mysql_plugin.result index f64d215978a..90924b6f4e3 100644 --- a/mysql-test/r/mysql_plugin.result +++ b/mysql-test/r/mysql_plugin.result @@ -55,7 +55,7 @@ ERROR: The plugin library is missing or in a different location. # # Bad format for config file # -ERROR: The plugin library is missing or in a different location. +ERROR: Cannot read plugin config file daemon_example. Bad format in plugin configuration file. # # Missing base_dir option # diff --git a/mysql-test/t/mysql_plugin.test b/mysql-test/t/mysql_plugin.test index 3257adfeb61..c2c0a403ab3 100644 --- a/mysql-test/t/mysql_plugin.test +++ b/mysql-test/t/mysql_plugin.test @@ -149,7 +149,7 @@ let $MYSQLD_BOOTSTRAP_CMD= $MYSQL_PLUGIN -n --datadir=$MYSQLD_DATADIR --basedir= --echo # --echo # Missing library --echo # -let $MYSQLD_BOOTSTRAP_CMD= $MYSQL_PLUGIN -n --datadir=$MYSQLD_DATADIR --basedir=$MYSQLD_BASEDIR/sql --plugin-dir=$MYSQL_TEST_DIR/include/; +let $MYSQLD_BOOTSTRAP_CMD= $MYSQL_PLUGIN -n --datadir=$MYSQLD_DATADIR --basedir=$MYSQLD_BASEDIR/sql --plugin-dir=$DAEMONEXAMPLE_DIR --plugin-ini=$MYSQL_TEST_DIR/include/daemon_example_bad_soname.ini; --error 1,2,256 --exec $MYSQLD_BOOTSTRAP_CMD DISABLE daemon_example 2>&1 -- cgit v1.2.1