20 #include <my_getopt.h>
22 #include <my_global.h>
27 #define SHOW_VERSION "1.0.0"
28 #define PRINT_VERSION do { printf("%s Ver %s Distrib %s\n", \
29 my_progname, SHOW_VERSION, MYSQL_SERVER_VERSION); \
33 static uint my_end_arg= 0;
34 static uint opt_verbose=0;
35 static uint opt_no_defaults= 0;
36 static uint opt_print_defaults= 0;
37 static char *opt_datadir=0, *opt_basedir=0,
38 *opt_plugin_dir=0, *opt_plugin_ini=0,
39 *opt_mysqld=0, *opt_my_print_defaults=0;
40 static char bootstrap[FN_REFLEN];
48 const char *components[16];
53 static struct my_option my_long_options[] =
55 {
"help",
'?',
"Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
57 {
"basedir",
'b',
"The basedir for the server.",
58 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
59 {
"datadir",
'd',
"The datadir for the server.",
60 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
61 {
"plugin-dir",
'p',
"The plugin dir for the server.",
62 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
63 {
"plugin-ini",
'i',
"Read plugin information from configuration file "
64 "specified instead of from <plugin-dir>/<plugin_name>.ini.",
65 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
66 {
"no-defaults",
'n',
"Do not read values from configuration file.",
67 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
68 {
"print-defaults",
'P',
"Show default values from configuration file.",
69 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
70 {
"mysqld",
'm',
"Path to mysqld executable. Example: /sbin/temp1/mysql/bin",
71 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
72 {
"my-print-defaults",
'f',
"Path to my_print_defaults executable. "
73 "Example: /source/temp11/extra",
74 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
76 "More verbose output; you can use this multiple times to get even more "
78 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
79 {
"version",
'V',
"Output version information and exit.", 0, 0, 0, GET_NO_ARG,
80 NO_ARG, 0, 0, 0, 0, 0, 0},
81 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
86 static int process_options(
int argc,
char *argv[],
char *operation);
88 static int find_tool(
const char *tool_name,
char *tool_path);
89 static int find_plugin(
char *tp_path);
90 static int build_bootstrap_file(
char *operation,
char *bootstrap);
91 static int dump_bootstrap_file(
char *bootstrap_file);
92 static int bootstrap_server(
char *server_path,
char *bootstrap_file);
95 int main(
int argc,
char *argv[])
98 char tp_path[FN_REFLEN];
99 char server_path[FN_REFLEN];
122 if ((error= process_options(argc, argv, operation)) ||
124 (error= find_tool(
"mysqld" FN_EXEEXT, server_path)) ||
125 (error= find_plugin(tp_path)) ||
126 (error= build_bootstrap_file(operation, bootstrap)))
130 if (opt_verbose && ((error= dump_bootstrap_file(bootstrap))))
134 error= bootstrap_server(server_path, bootstrap);
138 my_delete(bootstrap, MYF(0));
139 if (opt_verbose && error == 0)
141 printf(
"# Operation succeeded.\n");
159 static int make_tempfile(
char *filename,
const char *ext)
163 if ((fd=create_temp_file(filename, NullS, ext, O_CREAT | O_WRONLY,
166 fprintf(stderr,
"ERROR: Cannot generate temporary file. Error code: %d.\n",
170 my_close(fd, MYF(0));
184 static char *get_value(
char *line,
const char *item)
186 char *destination= 0;
187 int item_len= (int)strlen(item);
188 int line_len = (int)strlen(line);
190 if ((strncasecmp(line, item, item_len) == 0))
195 s = line + item_len + 1;
196 destination= my_strndup(s, line_len - start, MYF(MY_FAE));
197 destination[line_len - item_len - 2]= 0;
217 static int run_command(
char* cmd,
const char *
mode)
223 if (!(res_file= popen(cmd, mode)))
228 while (fgets(buf,
sizeof(buf), res_file))
230 fprintf(stdout,
"%s", buf);
233 error= pclose(res_file);
246 static int has_spaces(
const char *path)
248 if (strchr(path,
' ') != NULL)
261 static char *convert_path(
const char *argument)
264 char *winfilename= my_strdup(argument, MYF(MY_FAE));
266 int length= strlen(argument);
268 for (pos= winfilename, end= pos+length ; pos < end ; pos++)
286 static char *add_quotes(
const char *path)
288 char windows_cmd_friendly[FN_REFLEN];
290 if (has_spaces(path))
291 snprintf(windows_cmd_friendly,
sizeof(windows_cmd_friendly),
294 snprintf(windows_cmd_friendly,
sizeof(windows_cmd_friendly),
296 return my_strdup(windows_cmd_friendly, MYF(MY_FAE));
316 static int get_default_values()
318 char tool_path[FN_REFLEN];
319 char defaults_cmd[FN_REFLEN];
320 char defaults_file[FN_REFLEN];
321 char line[FN_REFLEN];
326 memset(tool_path, 0, FN_REFLEN);
327 if ((error= find_tool(
"my_print_defaults" FN_EXEEXT, tool_path)))
331 if ((error= make_tempfile(defaults_file,
"txt")))
338 if (has_spaces(tool_path) || has_spaces(defaults_file))
339 format_str =
"\"%s mysqld > %s\"";
341 format_str =
"%s mysqld > %s";
343 snprintf(defaults_cmd,
sizeof(defaults_cmd), format_str,
344 add_quotes(tool_path), add_quotes(defaults_file));
347 printf(
"# my_print_defaults found: %s\n", tool_path);
351 snprintf(defaults_cmd,
sizeof(defaults_cmd),
352 "%s mysqld > %s", tool_path, defaults_file);
358 printf(
"# Command: %s\n", defaults_cmd);
360 error= run_command(defaults_cmd,
"r");
363 fprintf(stderr,
"ERROR: my_print_defaults failed. Error code: %d.\n",
368 file= fopen(defaults_file,
"r");
369 while (fgets(line, FN_REFLEN, file) != NULL)
373 if ((opt_datadir == 0) && ((value= get_value(line,
"--datadir"))))
375 opt_datadir= my_strdup(value, MYF(MY_FAE));
377 if ((opt_basedir == 0) && ((value= get_value(line,
"--basedir"))))
379 opt_basedir= my_strdup(value, MYF(MY_FAE));
381 if ((opt_plugin_dir == 0) && ((value= get_value(line,
"--plugin_dir"))))
383 opt_plugin_dir= my_strdup(value, MYF(MY_FAE));
385 if ((opt_plugin_ini == 0) && ((value= get_value(line,
"--plugin_ini"))))
387 opt_plugin_ini= my_strdup(value, MYF(MY_FAE));
396 my_delete(defaults_file, MYF(0));
406 static void usage(
void)
409 puts(
"Copyright (c) 2011, Oracle and/or its affiliates. "
410 "All rights reserved.\n");
411 puts(
"Enable or disable plugins.");
412 printf(
"\nUsage: %s [options] <plugin> ENABLE|DISABLE\n\nOptions:\n",
414 my_print_help(my_long_options);
431 static void print_default_values(
void)
433 printf(
"%s would have been started with the following arguments:\n",
435 get_default_values();
438 printf(
"--datadir=%s ", opt_datadir);
442 printf(
"--basedir=%s ", opt_basedir);
446 printf(
"--plugin_dir=%s ", opt_plugin_dir);
450 printf(
"--plugin_ini=%s ", opt_plugin_ini);
454 printf(
"--mysqld=%s ", opt_mysqld);
456 if (opt_my_print_defaults)
458 printf(
"--my_print_defaults=%s ", opt_my_print_defaults);
473 get_one_option(
int optid,
474 const struct my_option *opt __attribute__((unused)),
482 opt_print_defaults++;
483 print_default_values();
497 opt_datadir= my_strdup(argument, MYF(MY_FAE));
500 opt_basedir= my_strdup(argument, MYF(MY_FAE));
503 opt_plugin_dir= my_strdup(argument, MYF(MY_FAE));
506 opt_plugin_ini= my_strdup(argument, MYF(MY_FAE));
509 opt_mysqld= my_strdup(argument, MYF(MY_FAE));
512 opt_my_print_defaults= my_strdup(argument, MYF(MY_FAE));
527 static int file_exists(
char * filename)
531 if (!my_stat(filename, &stat_arg, MYF(0)))
550 static int search_dir(
const char * base_path,
const char *tool_name,
551 const char *subdir,
char *tool_path)
553 char new_path[FN_REFLEN];
554 char source_path[FN_REFLEN];
556 char win_abs_path[FN_REFLEN];
557 char self_name[FN_REFLEN];
558 const char *last_fn_libchar;
561 if ((strlen(base_path) + strlen(subdir) + 1) > FN_REFLEN)
563 fprintf(stderr,
"WARNING: Search path is too long\n");
566 strcpy(source_path, base_path);
567 strcat(source_path, subdir);
568 fn_format(new_path, tool_name, source_path,
"", MY_UNPACK_FILENAME);
569 if (file_exists(new_path))
571 strcpy(tool_path, new_path);
582 if (GetModuleFileName(NULL, self_name, FN_REFLEN -1) == 0)
583 strncpy(self_name, my_progname, FN_REFLEN - 1);
584 self_name[FN_REFLEN - 1]=
'\0';
586 last_fn_libchar= strrchr(self_name, FN_LIBCHAR);
587 if (NULL != last_fn_libchar)
589 strncpy(win_abs_path, self_name, last_fn_libchar - self_name + 1 );
590 win_abs_path[(last_fn_libchar - self_name + 1)]= 0;
591 strncat(win_abs_path, new_path,
592 sizeof(win_abs_path) - strlen(win_abs_path) - 1);
593 if (file_exists(win_abs_path))
595 strcpy(tool_path, win_abs_path);
614 static int search_paths(
const char *base_path,
const char *tool_name,
619 static const char *paths[]= {
620 "",
"/share/",
"/scripts/",
"/bin/",
"/sbin/",
"/libexec/",
623 for (i = 0 ; i < (int)array_elements(paths); i++)
625 if (!search_dir(base_path, tool_name, paths[i], tool_path))
644 static int load_plugin_data(
char *plugin_name,
char *config_file)
647 char path[FN_REFLEN];
653 if (opt_plugin_ini == 0)
655 fn_format(path, config_file, opt_plugin_dir,
"", MYF(0));
656 opt_plugin_ini= my_strdup(path, MYF(MY_FAE));
658 if (!file_exists(opt_plugin_ini))
660 reason= (
char *)
"File does not exist.";
664 file_ptr= fopen(opt_plugin_ini,
"r");
665 if (file_ptr == NULL)
667 reason= (
char *)
"Cannot open file.";
672 plugin_data.name= my_strdup(plugin_name, MYF(MY_WME));
677 res= fgets(line,
sizeof(line), file_ptr);
679 if (line[strlen(line)-1] ==
'\n')
681 line[strlen(line)-1]=
'\0';
687 reason= (
char *)
"Bad format in plugin configuration file.";
693 if ((line[0] ==
'#') || (line[0] ==
'\n'))
700 strcat(line, FN_SOEXT);
702 plugin_data.so_name= my_strdup(line, MYF(MY_WME|MY_ZEROFILL));
707 if (strlen(line) > 0)
709 plugin_data.components[
i]= my_strdup(line, MYF(MY_WME));
714 plugin_data.components[
i]= NULL;
723 fprintf(stderr,
"ERROR: Cannot read plugin config file %s. %s\n",
724 plugin_name, reason);
743 static int check_options(
int argc,
char **argv,
char *operation)
747 char config_file[FN_REFLEN];
748 char plugin_name[FN_REFLEN];
751 const char *basedir_prefix =
"--basedir=";
752 int basedir_len= strlen(basedir_prefix);
753 const char *datadir_prefix =
"--datadir=";
754 int datadir_len= strlen(datadir_prefix);
755 const char *plugin_dir_prefix =
"--plugin_dir=";
756 int plugin_dir_len= strlen(plugin_dir_prefix);
758 strcpy(plugin_name,
"");
759 for (i = 0; i < argc && num_found < 5; i++)
766 if ((strcasecmp(argv[i],
"ENABLE") == 0) ||
767 (strcasecmp(argv[i],
"DISABLE") == 0))
769 strcpy(operation, argv[i]);
772 else if ((strncasecmp(argv[i], basedir_prefix, basedir_len) == 0) &&
775 opt_basedir= my_strndup(argv[i]+basedir_len,
776 strlen(argv[i])-basedir_len, MYF(MY_FAE));
779 else if ((strncasecmp(argv[i], datadir_prefix, datadir_len) == 0) &&
782 opt_datadir= my_strndup(argv[i]+datadir_len,
783 strlen(argv[i])-datadir_len, MYF(MY_FAE));
786 else if ((strncasecmp(argv[i], plugin_dir_prefix, plugin_dir_len) == 0) &&
789 opt_plugin_dir= my_strndup(argv[i]+plugin_dir_len,
790 strlen(argv[i])-plugin_dir_len, MYF(MY_FAE));
796 strcpy(plugin_name, argv[i]);
797 strcpy(config_file, argv[i]);
798 strcat(config_file,
".ini");
804 fprintf(stderr,
"ERROR: Missing --basedir option.\n");
810 fprintf(stderr,
"ERROR: Missing --datadir option.\n");
816 fprintf(stderr,
"ERROR: Missing --plugin_dir option.\n");
820 else if (strlen(plugin_name) > 0)
822 if (load_plugin_data(plugin_name, config_file))
826 if (strcasecmp(plugin_data.name, plugin_name) != 0)
828 fprintf(stderr,
"ERROR: plugin name requested does not match config "
835 fprintf(stderr,
"ERROR: No plugin specified.\n");
839 if ((strlen(operation) == 0))
841 fprintf(stderr,
"ERROR: missing operation. Please specify either "
842 "'<plugin> ENABLE' or '<plugin> DISABLE'.\n");
864 static int process_options(
int argc,
char *argv[],
char *operation)
870 if ((error= handle_options(&argc, &argv, my_long_options, get_one_option)))
874 if (opt_print_defaults)
883 i= (int)strlength(opt_basedir);
884 if (opt_basedir[i-1] != FN_LIBCHAR || opt_basedir[i-1] != FN_LIBCHAR2)
886 char buff[FN_REFLEN];
888 strncpy(buff, opt_basedir,
sizeof(buff) - 1);
890 strncat(buff,
"/",
sizeof(buff) - strlen(buff) - 1);
892 strncat(buff, FN_DIRSEP,
sizeof(buff) - strlen(buff) - 1);
894 buff[
sizeof(buff) - 1]= 0;
895 my_delete(opt_basedir, MYF(0));
896 opt_basedir= my_strdup(buff, MYF(MY_FAE));
905 if (!opt_no_defaults && ((error= get_default_values())))
917 strcpy(operation,
"");
918 if ((error = check_options(argc, argv, operation)))
925 printf(
"# basedir = %s\n", opt_basedir);
926 printf(
"# plugin_dir = %s\n", opt_plugin_dir);
927 printf(
"# datadir = %s\n", opt_datadir);
928 printf(
"# plugin_ini = %s\n", opt_plugin_ini);
950 if ((error= my_access(opt_basedir, F_OK)))
952 fprintf(stderr,
"ERROR: Cannot access basedir at '%s'.\n",
956 if ((error= my_access(opt_plugin_dir, F_OK)))
958 fprintf(stderr,
"ERROR: Cannot access plugin_dir at '%s'.\n",
962 if ((error= my_access(opt_datadir, F_OK)))
964 fprintf(stderr,
"ERROR: Cannot access datadir at '%s'.\n",
968 if (opt_plugin_ini && (error= my_access(opt_plugin_ini, F_OK)))
970 fprintf(stderr,
"ERROR: Cannot access plugin config file at '%s'.\n",
974 if (opt_mysqld && (error= my_access(opt_mysqld, F_OK)))
976 fprintf(stderr,
"ERROR: Cannot access mysqld path '%s'.\n",
980 if (opt_my_print_defaults && (error= my_access(opt_my_print_defaults, F_OK)))
982 fprintf(stderr,
"ERROR: Cannot access my-print-defaults path '%s'.\n",
983 opt_my_print_defaults);
1001 static int find_tool(
const char *tool_name,
char *tool_path)
1005 const char *paths[]= {
1006 opt_mysqld, opt_basedir, opt_my_print_defaults,
"",
1007 "/usr",
"/usr/local/mysql",
"/usr/sbin",
"/usr/share",
1008 "/extra",
"/extra/debug",
"/../../extra/debug",
1009 "/release/",
"/extra/release",
"/../../extra/release",
1010 "/bin",
"/usr/bin",
"/mysql/bin"
1012 for (i= 0; i < (int)array_elements(paths); i++)
1014 if (paths[i] && !(search_paths(paths[i], tool_name, tool_path)))
1017 fprintf(stderr,
"WARNING: Cannot find %s.\n", tool_name);
1021 printf(
"# Found tool '%s' as '%s'.\n", tool_name, tool_path);
1037 static int find_plugin(
char *tp_path)
1040 fn_format(tp_path, plugin_data.so_name, opt_plugin_dir,
"", MYF(0));
1041 if (!file_exists(tp_path))
1043 fprintf(stderr,
"ERROR: The plugin library is missing or in a different"
1047 else if (opt_verbose)
1049 printf(
"# Found plugin '%s' as '%s'\n", plugin_data.name, tp_path);
1067 static int build_bootstrap_file(
char *operation,
char *bootstrap)
1087 if ((error= make_tempfile(bootstrap,
"sql")))
1090 fprintf(stderr,
"ERROR: Cannot create bootstrap file.\n");
1093 if ((file= fopen(bootstrap,
"w+")) == NULL)
1095 fprintf(stderr,
"ERROR: Cannot open bootstrap file for writing.\n");
1099 if (strcasecmp(operation,
"enable") == 0)
1102 fprintf(file,
"REPLACE INTO mysql.plugin VALUES ");
1103 for (i= 0; i < (int)array_elements(plugin_data.components); i++)
1106 if (plugin_data.components[i] == NULL)
1112 fprintf(file,
", ");
1114 fprintf(file,
"('%s','%s')",
1115 plugin_data.components[i], plugin_data.so_name);
1117 fprintf(file,
";\n");
1120 printf(
"# Enabling %s...\n", plugin_data.name);
1126 "DELETE FROM mysql.plugin WHERE dl = '%s';", plugin_data.so_name);
1129 printf(
"# Disabling %s...\n", plugin_data.name);
1149 static int dump_bootstrap_file(
char *bootstrap_file)
1153 char query_str[512];
1156 if ((file= fopen(bootstrap_file,
"r")) == NULL)
1158 fprintf(stderr,
"ERROR: Cannot open bootstrap file for reading.\n");
1162 ret= fgets(query_str, 512, file);
1165 fprintf(stderr,
"ERROR: Cannot read bootstrap file.\n");
1169 printf(
"# Query: %s\n", query_str);
1201 static int bootstrap_server(
char *server_path,
char *bootstrap_file)
1203 char bootstrap_cmd[FN_REFLEN];
1207 char *format_str= 0;
1208 const char *verbose_str= NULL;
1212 verbose_str=
"--console";
1215 if (has_spaces(opt_datadir) || has_spaces(opt_basedir) ||
1216 has_spaces(bootstrap_file))
1217 format_str=
"\"%s %s --bootstrap --datadir=%s --basedir=%s < %s\"";
1219 format_str=
"%s %s --bootstrap --datadir=%s --basedir=%s < %s";
1221 snprintf(bootstrap_cmd,
sizeof(bootstrap_cmd), format_str,
1222 add_quotes(convert_path(server_path)), verbose_str,
1223 add_quotes(opt_datadir), add_quotes(opt_basedir),
1224 add_quotes(bootstrap_file));
1226 snprintf(bootstrap_cmd,
sizeof(bootstrap_cmd),
1227 "%s --no-defaults --bootstrap --datadir=%s --basedir=%s"
1228 " < %s", server_path, opt_datadir, opt_basedir, bootstrap_file);
1234 printf(
"# Command: %s\n", bootstrap_cmd);
1236 error= run_command(bootstrap_cmd,
"r");
1239 "ERROR: Unexpected result from bootstrap. Error code: %d.\n",