diff --git a/client/client_priv.h b/client/client_priv.h index bcd4fd53cbb155ef4119285a2006e7b8f073b653..f321b47aec013b59644c398d48b05f9c720a0bc9 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -31,5 +31,10 @@ enum options { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_LOW_PRIORITY, OPT_AUTO_REPAIR, OPT_COMPRESS, OPT_DROP, OPT_LOCKS, OPT_KEYWORDS, OPT_DELAYED, OPT_OPTIMIZE, OPT_FTB, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_TABLES, - OPT_MASTER_DATA, OPT_AUTOCOMMIT, OPT_LOCAL_INFILE, OPT_PROMPT, - OPT_IGN_LINES }; + OPT_MASTER_DATA, OPT_AUTOCOMMIT, OPT_AUTO_REHASH, + OPT_LINE_NUMBERS, OPT_COLUMN_NAMES, OPT_CONNECT_TIMEOUT, + OPT_MAX_ALLOWED_PACKET, OPT_NET_BUFFER_LENGTH, + OPT_SELECT_LIMIT, OPT_MAX_JOIN_SIZE, OPT_SSL_SSL, + OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH, + OPT_SSL_CIPHER, OPT_SHUTDOWN_TIMEOUT, OPT_LOCAL_INFILE, + OPT_PROMPT, OPT_IGN_LINES }; diff --git a/client/mysql.cc b/client/mysql.cc index e97e349790e72ee66ea9b78de5e796217d2b1c32..b18a07f73fd27d58709b63e7efa1f37744946d7b 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -19,18 +19,19 @@ * * Written by: * Michael 'Monty' Widenius - * Andi Gutmans <andi@zend.com> - * Zeev Suraski <zeev@zend.com> - * Jani Tolonen <jani@mysql.com> - * Matt Wagner <matt@mysql.com> - * Jeremy Cole <jcole@mysql.com> - * Tonu Samuel <tonu@mysql.com> - * Harrison Fisk <hcfisk@buffalo.edu> + * Andi Gutmans <andi@zend.com> + * Zeev Suraski <zeev@zend.com> + * Jani Tolonen <jani@mysql.com> + * Matt Wagner <matt@mysql.com> + * Jeremy Cole <jcole@mysql.com> + * Tonu Samuel <tonu@mysql.com> * **/ #include "client_priv.h" #include <m_ctype.h> +#include <stdarg.h> +#include <my_getopt.h> #include <my_dir.h> #ifndef __GNU_LIBRARY__ #define __GNU_LIBRARY__ // Skip warnings in getopt.h @@ -39,7 +40,7 @@ #include <signal.h> #include <violite.h> -const char *VER="12.1"; +const char *VER= "12.0"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -98,8 +99,6 @@ extern "C" { #include "completion_hash.h" -#define PROMPT_CHAR '\\' - typedef struct st_status { int exit_status; @@ -116,22 +115,20 @@ enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT}; typedef enum enum_info_type INFO_TYPE; static MYSQL mysql; /* The connection */ -static bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, - connected=0,opt_raw_data=0,unbuffered=0,output_tables=0, - no_rehash=0,skip_updates=0,safe_updates=0,one_database=0, - opt_compress=0, using_opt_local_infile=0, - vertical=0,skip_line_numbers=0,skip_column_names=0,opt_html=0, - opt_xml=0,opt_nopager=1, opt_outfile=0, no_named_cmds=1, - opt_nobeep=0; -static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0; +static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, + connected=0,opt_raw_data=0,unbuffered=0,output_tables=0, + no_rehash=0,skip_updates=0,safe_updates=0,one_database=0, + opt_compress=0, + vertical=0, line_numbers=1, column_names=1,opt_html=0, + opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0, + tty_password= 0; +static uint verbose=0, opt_silent=0, opt_mysql_port=0; static my_string opt_mysql_unix_port=0; static int connect_flag=CLIENT_INTERACTIVE; static char *current_host,*current_db,*current_user=0,*opt_password=0, - *current_prompt=0, *default_charset; + *default_charset; static char *histfile; static String glob_buffer,old_buffer; -static String processed_prompt; -static char *full_username=0,*part_username=0,*default_prompt=0; static int wait_time = 5; static STATUS status; static ulong select_limit,max_join_size,opt_connect_timeout=0; @@ -141,14 +138,10 @@ static const char *xmlmeta[] = { "<", "<", 0, 0 }; -static const char *day_names[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; -static const char *month_names[]={"Jan","Feb","Mar","Apr","May","Jun","Jul", - "Aug","Sep","Oct","Nov","Dec"}; -static char default_pager[FN_REFLEN]; +char default_pager[FN_REFLEN]; char pager[FN_REFLEN], outfile[FN_REFLEN]; FILE *PAGER, *OUTFILE; MEM_ROOT hash_mem_root; -static uint prompt_counter; #include "sslopt-vars.h" @@ -169,8 +162,7 @@ static int com_quit(String *str,char*), com_connect(String *str,char*), com_status(String *str,char*), com_use(String *str,char*), com_source(String *str, char*), com_rehash(String *str, char*), com_tee(String *str, char*), - com_notee(String *str, char*), com_shell(String *str, char *), - com_prompt(String *str, char*); + com_notee(String *str, char*), com_shell(String *str, char *); #ifndef __WIN__ static int com_nopager(String *str, char*), com_pager(String *str, char*), @@ -187,9 +179,6 @@ static void init_pager(); static void end_pager(); static void init_tee(); static void end_tee(); -static const char* construct_prompt(); -static void init_username(); -static void add_int_to_prompt(int toadd); /* A structure which contains information on the commands this program can understand. */ @@ -224,7 +213,6 @@ static COMMANDS commands[] = { "Set PAGER [to_pager]. Print the query results via PAGER." }, #endif { "print", 'p', com_print, 0, "Print current command." }, - { "prompt", 'R', com_prompt, 1, "Change your mysql prompt."}, { "quit", 'q', com_quit, 0, "Quit mysql." }, { "rehash", '#', com_rehash, 0, "Rebuild completion hash." }, { "source", '.', com_source, 1, @@ -294,12 +282,6 @@ int main(int argc,char *argv[]) DBUG_ENTER("main"); DBUG_PROCESS(argv[0]); - default_prompt = my_strdup(getenv("MYSQL_PS1") ? - getenv("MYSQL_PS1") : - "mysql> ",MYF(MY_WME)); - current_prompt = my_strdup(default_prompt,MYF(MY_WME)); - prompt_counter=0; - strmov(outfile, "\0"); // no (default) outfile, unless given at least once strmov(pager, "stdout"); // the default, if --pager wasn't given { @@ -316,7 +298,7 @@ int main(int argc,char *argv[]) status.add_to_history=1; status.exit_status=1; load_defaults("my",load_default_groups,&argc,&argv); - if (get_options(argc,(char **) argv)) + if (get_options(argc, (char **) argv)) { my_end(0); exit(1); @@ -340,7 +322,6 @@ int main(int argc,char *argv[]) if (!status.batch) ignore_errors=1; // Don't abort monitor signal(SIGINT, mysql_end); // Catch SIGINT to clean up - signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up /* ** Run in interactive mode like the ingres/postgres monitor @@ -427,92 +408,154 @@ sig_handler mysql_end(int sig) put_info(sig ? "Aborted" : "Bye", INFO_RESULT); glob_buffer.free(); old_buffer.free(); - processed_prompt.free(); my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); my_free(opt_mysql_unix_port,MYF(MY_ALLOW_ZERO_PTR)); my_free(histfile,MYF(MY_ALLOW_ZERO_PTR)); my_free(current_db,MYF(MY_ALLOW_ZERO_PTR)); my_free(current_host,MYF(MY_ALLOW_ZERO_PTR)); my_free(current_user,MYF(MY_ALLOW_ZERO_PTR)); - my_free(full_username,MYF(MY_ALLOW_ZERO_PTR)); - my_free(part_username,MYF(MY_ALLOW_ZERO_PTR)); - my_free(default_prompt,MYF(MY_ALLOW_ZERO_PTR)); - my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR)); mysql_server_end(); my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); exit(status.exit_status); } -static struct option long_options[] = + +static struct my_option my_long_options[] = { - {"i-am-a-dummy", optional_argument, 0, 'U'}, - {"batch", no_argument, 0, 'B'}, - {"character-sets-dir",required_argument, 0, OPT_CHARSETS_DIR}, - {"compress", no_argument, 0, 'C'}, + {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, + 0, 0, 0, 0, 0}, + {"auto-rehash", OPT_AUTO_REHASH, + "Enable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time. Disable with --disable-auto-rehash.", + (gptr*) &no_rehash, (gptr*) &no_rehash, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, + 0}, + {"no-auto-rehash", 'A', + "No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect. WARNING: options depricated; use --disable-auto-rehash instead.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"batch", 'B', + "Print results with a tab as separator, each row on new line. Doesn't use history file.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"character-sets-dir", OPT_CHARSETS_DIR, + "Directory where character sets are.", (gptr*) &charsets_dir, + (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"compress", 'C', "Use compression in server/client protocol.", + (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, #ifndef DBUG_OFF - {"debug", optional_argument, 0, '#'}, + {"debug", '#', "Output debug log.", (gptr*) &default_dbug_option, + (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, +#endif + {"database", 'D', "Database to use.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"execute", 'e', "Execute command and quit. (Output like with --batch).", 0, + 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"vertical", 'E', "Print the output of a query (rows) vertically.", + (gptr*) &vertical, (gptr*) &vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, + 0}, + {"force", 'f', "Continue even if we get an sql error.", + (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0, + 0, 0, 0, 0}, + {"no-named-commands", 'g', "Named commands are disabled. Use \\* form only, or use named commands only in the beginning of a line ending with a semicolon (;) Since version 10.9 the client now starts with this option ENABLED by default! Disable with '-G'. Long format commands still work from the first line. WARNING: option depricated; use --disable-named-commands instead.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"named-commands", 'G', + "Enable named commands. Disable with --disable-named-commands. This option is disabled by default.", + (gptr*) &named_cmds, (gptr*) &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, + {"ignore-space", 'i', "Ignore space after function names.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"host", 'h', "Connect to host.", (gptr*) ¤t_host, + (gptr*) ¤t_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"html", 'H', "Produce HTML output.", (gptr*) &opt_html, (gptr*) &opt_html, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"xml", 'X', "Produce XML output", (gptr*) &opt_xml, (gptr*) &opt_xml, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.", + (gptr*) &line_numbers, (gptr*) &line_numbers, 0, GET_BOOL, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"skip-line-numbers", 'L', "Don't write line number for errors. WARNING: -L is depricated, use long version of this option instead.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, +#ifndef __WIN__ + {"no-pager", OPT_NOPAGER, + "Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option depricated; use --disable-pager instead.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"database", required_argument, 0, 'D'}, - {"debug-info", no_argument, 0, 'T'}, - {"default-character-set", required_argument,0, OPT_DEFAULT_CHARSET}, - {"enable-named-commands", no_argument, 0, 'G'}, - {"execute", required_argument, 0, 'e'}, - {"force", no_argument, 0, 'f'}, - {"help", no_argument, 0, '?'}, - {"html", no_argument, 0, 'H'}, - {"xml", no_argument, 0, 'X'}, - {"host", required_argument, 0, 'h'}, - {"ignore-spaces", no_argument, 0, 'i'}, - {"local-infile", optional_argument, 0, OPT_LOCAL_INFILE}, - {"no-auto-rehash",no_argument, 0, 'A'}, - {"no-beep", no_argument, 0, 'b'}, - {"no-named-commands", no_argument, 0, 'g'}, + {"no-tee", OPT_NOTEE, "Disable outfile. See interactive help (\\h) also. WARNING: option depricated; use --disable-tee instead", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"unbuffered", 'n', "Flush buffer after each query.", (gptr*) &unbuffered, + (gptr*) &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"column-names", OPT_COLUMN_NAMES, "Write column names in results.", + (gptr*) &column_names, (gptr*) &column_names, 0, GET_BOOL, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"skip-column-names", 'N', + "Don't write column names in results. WARNING: -N is depricated, use long version of this options instead.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"set-variable", 'O', + "Change the value of a variable. Please note that this option is depricated; you can set variables directly with --variable-name=value.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"one-database", 'o', + "Only update the default database. This is useful for skipping updates to other database in the update log.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifndef __WIN__ - {"no-pager", no_argument, 0, OPT_NOPAGER}, - {"nopager", no_argument, 0, OPT_NOPAGER}, /* we are kind */ - {"pager", optional_argument, 0, OPT_PAGER}, + {"pager", OPT_PAGER, + "Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode.", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"no-tee", no_argument, 0, OPT_NOTEE}, - {"notee", no_argument, 0, OPT_NOTEE}, /* we are kind */ - {"tee", required_argument, 0, OPT_TEE}, - {"one-database", no_argument, 0, 'o'}, - {"password", optional_argument, 0, 'p'}, + {"password", 'p', + "Password to use when connecting to server. If password is not given it's asked from the tty.", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __WIN__ - {"pipe", no_argument, 0, 'W'}, + {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"port", required_argument, 0, 'P'}, - {"prompt", required_argument, 0, OPT_PROMPT}, - {"quick", no_argument, 0, 'q'}, - {"set-variable", required_argument, 0, 'O'}, - {"raw", no_argument, 0, 'r'}, - {"safe-updates", optional_argument, 0, 'U'}, - {"silent", no_argument, 0, 's'}, - {"skip-column-names",no_argument, 0, 'N'}, - {"skip-line-numbers",no_argument, 0, 'L'}, - {"socket", required_argument, 0, 'S'}, + {"port", 'P', "Port number to use for connection.", 0, 0, 0, + GET_LONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"quick", 'q', + "Don't cache result, print it row by row. This may slow down the server if the output is suspended. Doesn't use history file. ", + (gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"raw", 'r', "Write fields without conversion. Used with --batch", + (gptr*) &opt_raw_data, (gptr*) &opt_raw_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"silent", 's', "Be more silent.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, + 0, 0}, + {"socket", 'S', "Socket file to use for connection.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #include "sslopt-longopts.h" - {"table", no_argument, 0, 't'}, + {"table", 't', "Output in table format.", (gptr*) &output_tables, + (gptr*) &output_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", 'T', "Print some debug info at exit.", (gptr*) &info_flag, + (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"tee", OPT_TEE, + "Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifndef DONT_ALLOW_USER_CHANGE - {"user", required_argument, 0, 'u'}, + {"user", 'u', "User for login if not current user.", (gptr*) ¤t_user, + (gptr*) ¤t_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"unbuffered", no_argument, 0, 'n'}, - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"vertical", no_argument, 0, 'E'}, - {"wait", optional_argument, 0, 'w'}, - {0, 0, 0, 0} -}; - - -CHANGEABLE_VAR changeable_vars[] = { - { "connect_timeout", (long*) &opt_connect_timeout, 0, 0, 3600*12, 0, 1}, - { "max_allowed_packet", (long*) &max_allowed_packet,16*1024L*1024L,4096, - 512*1024L*1024L, MALLOC_OVERHEAD,1024}, - { "net_buffer_length",(long*) &net_buffer_length,16384,1024,512*1024*1024L, - MALLOC_OVERHEAD,1024}, - { "select_limit", (long*) &select_limit, 1000L, 1, ~0L, 0, 1}, - { "max_join_size", (long*) &max_join_size, 1000000L, 1, ~0L, 0, 1}, - { 0, 0, 0, 0, 0, 0, 0} + {"safe-updates", 'U', "Only allow UPDATE and DELETE that uses keys.", + (gptr*) &safe_updates, (gptr*) &safe_updates, 0, GET_BOOL, OPT_ARG, 0, 0, + 0, 0, 0, 0}, + {"i-am-a-dummy", 'U', "Synonym for option --safe-updates, -U.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"verbose", 'v', "Write more. (-v -v -v gives the table output format)", 0, + 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"version", 'V', "Output version information and exit.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"connect_timeout", OPT_CONNECT_TIMEOUT, "", (gptr*) &opt_connect_timeout, + (gptr*) &opt_connect_timeout, 0, GET_LONG, REQUIRED_ARG, 0, 0, 3600*12, 0, + 0, 1}, + {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "", + (gptr*) &max_allowed_packet, (gptr*) &max_allowed_packet, 0, GET_LONG, + REQUIRED_ARG, 16 *1024L*1024L, 4096, 512*1024L*1024L, MALLOC_OVERHEAD, + 1024, 0}, + {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "", + (gptr*) &net_buffer_length, (gptr*) &net_buffer_length, 0, GET_LONG, + REQUIRED_ARG, 16384, 1024, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0}, + {"select_limit", OPT_SELECT_LIMIT, "", (gptr*) &select_limit, + (gptr*) &select_limit, 0, GET_LONG, REQUIRED_ARG, 1000L, 1, ~0L, 0, 1, 0}, + {"max_join_size", OPT_MAX_JOIN_SIZE, "", (gptr*) &max_join_size, + (gptr*) &max_join_size, 0, GET_LONG, REQUIRED_ARG, 1000000L, 1, ~0L, 0, 1, + 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -522,305 +565,213 @@ static void usage(int version) my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); if (version) return; - printf("\ -Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB\n\ -This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL license\n"); + puts("Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB"); + puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); printf("Usage: %s [OPTIONS] [database]\n", my_progname); - printf("\n\ - -?, --help Display this help and exit.\n\ - -A, --no-auto-rehash No automatic rehashing. One has to use 'rehash' to\n\ - get table and field completion. This gives a quicker\n\ - start of mysql and disables rehashing on reconnect.\n\ - -b, --no-beep Turn off beep on error.\n\ - -B, --batch Print results with a tab as separator, each row on\n\ - a new line. Doesn't use history file.\n\ - --character-sets-dir=...\n\ - Directory where character sets are located.\n\ - -C, --compress Use compression in server/client protocol.\n"); -#ifndef DBUG_OFF - printf("\ - -#, --debug[=...] Debug log. Default is '%s'.\n", default_dbug_option); -#endif - printf("\ - -D, --database=.. Database to use.\n\ - --default-character-set=...\n\ - Set the default character set.\n\ - -e, --execute=... Execute command and quit. (Output like with --batch)\n\ - -E, --vertical Print the output of a query (rows) vertically.\n\ - -f, --force Continue even if we get an sql error.\n\ - -g, --no-named-commands\n\ - Named commands are disabled. Use \\* form only, or\n\ - use named commands only in the beginning of a line\n\ - ending with a semicolon (;) Since version 10.9 the\n\ - client now starts with this option ENABLED by\n\ - default! Disable with '-G'. Long format commands\n\ - still work from the first line.\n\ - -G, --enable-named-commands\n\ - Named commands are enabled. Opposite to -g.\n\ - -i, --ignore-spaces Ignore spaces after function names.\n\ - -h, --host=... Connect to host.\n\ - -H, --html Produce HTML output.\n\ - -X, --xml Produce XML output.\n\ - --local-infile=[1|0] Enable/disable LOAD DATA LOCAL INFILE\n\ - -L, --skip-line-numbers\n\ - Don't write line number for errors.\n"); -#ifndef __WIN__ - printf("\ - --no-pager Disable pager and print to stdout. See interactive\n\ - help (\\h) also.\n"); -#endif - printf("\ - --no-tee Disable outfile. See interactive help (\\h) also.\n\ - -n, --unbuffered Flush buffer after each query.\n\ - -N, --skip-column-names\n\ - Don't write column names in results.\n\ - -O, --set-variable var=option\n\ - Give a variable an value. --help lists variables.\n\ - -o, --one-database Only update the default database. This is useful\n\ - for skipping updates to other database in the update\n\ - log.\n"); -#ifndef __WIN__ - printf("\ - --pager[=...] Pager to use to display results. If you don't supply\n\ - an option the default pager is taken from your ENV\n\ - variable PAGER (%s).\n\ - Valid pagers are less, more, cat [> filename], etc.\n\ - See interactive help (\\h) also. This option does\n\ - not work in batch mode.\n", - getenv("PAGER") ? getenv("PAGER") : ""); -#endif - printf("\ - -p[password], --password[=...]\n\ - Password to use when connecting to server\n\ - If password is not given it's asked from the tty.\n"); -#ifdef __WIN__ - printf("\ - -W, --pipe Use named pipes to connect to server"); -#endif - printf("\n\ - -P, --port=... Port number to use for connection.\n\ - -q, --quick Don't cache result, print it row by row. This may\n\ - slow down the server if the output is suspended.\n\ - Doesn't use history file.\n\ - -r, --raw Write fields without conversion. Used with --batch\n\ - --prompt=... Set the mysql prompt to this value\n\ - -s, --silent Be more silent.\n\ - -S --socket=... Socket file to use for connection.\n"); -#include "sslopt-usage.h" - printf("\ - -t, --table Output in table format.\n\ - -T, --debug-info Print some debug info at exit.\n\ - --tee=... Append everything into outfile. See interactive help\n\ - (\\h) also. Does not work in batch mode.\n"); -#ifndef DONT_ALLOW_USER_CHANGE - printf("\ - -u, --user=# User for login if not current user.\n"); -#endif - printf("\ - -U, --safe-updates[=#], --i-am-a-dummy[=#]\n\ - Only allow UPDATE and DELETE that uses keys.\n\ - -v, --verbose Write more. (-v -v -v gives the table output format)\n\ - -V, --version Output version information and exit.\n\ - -w, --wait Wait and retry if connection is down.\n"); - - print_defaults("my",load_default_groups); - - printf("\nPossible variables for option --set-variable (-O) are:\n"); - for (uint i=0 ; changeable_vars[i].name ; i++) - printf("%-20s current value: %lu\n", - changeable_vars[i].name, - (ulong) *changeable_vars[i].varptr); + print_defaults("my", load_default_groups); + my_print_help(my_long_options); + my_print_variables(my_long_options); } - -static int get_options(int argc, char **argv) +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument) { - int c,option_index=0; - bool tty_password=0; - - set_all_changeable_vars(changeable_vars); - while ((c=getopt_long(argc,argv, - (char*) "?AbBCD:LfgGHXinNoqrstTU::vVw::WEe:h:O:P:S:u:#::p::", - long_options, &option_index)) != EOF) - { - switch(c) { - case OPT_CHARSETS_DIR: - strmov(mysql_charsets_dir, optarg); - charsets_dir = mysql_charsets_dir; - break; + switch(optid) { case OPT_DEFAULT_CHARSET: - default_charset= optarg; + default_charset= argument; break; - case OPT_LOCAL_INFILE: - using_opt_local_infile=1; - opt_local_infile= test(!optarg || atoi(optarg)>0); + case OPT_CHARSETS_DIR: + strmov(mysql_charsets_dir, argument); + charsets_dir = mysql_charsets_dir; break; case OPT_TEE: - if (!opt_outfile && strlen(optarg)) + if (argument == disabled_my_option) { - strmov(outfile, optarg); - opt_outfile=1; - init_tee(); + if (opt_outfile) + end_tee(); + opt_outfile= 0; } + else + if (!opt_outfile) + { + strmov(outfile, argument); + opt_outfile= 1; + init_tee(); + } break; case OPT_NOTEE: + printf("WARNING: option depricated; use --disable-tee instead.\n"); if (opt_outfile) end_tee(); - opt_outfile=0; + opt_outfile= 0; break; case OPT_PAGER: - opt_nopager=0; - if (optarg) - strmov(pager, optarg); + opt_nopager= 0; + if (argument) + strmov(pager, argument); else - { - char *pagpoint = getenv("PAGER"); - if (!((char*) (pagpoint))) - { - strmov(pager, "stdout"); - opt_nopager=1; - } - else - strmov(pager, pagpoint); - } + strmov(pager, default_pager); strmov(default_pager, pager); break; case OPT_NOPAGER: - opt_nopager=1; - break; - case OPT_PROMPT: - my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR)); - current_prompt=my_strdup(optarg,MYF(MY_FAE)); - break; - case 'b': - opt_nobeep = 1; + printf("WARNING: option depricated; use --disable-pager instead.\n"); + opt_nopager= 1; break; case 'D': - my_free(current_db,MYF(MY_ALLOW_ZERO_PTR)); - current_db=my_strdup(optarg,MYF(MY_WME)); + my_free(current_db, MYF(MY_ALLOW_ZERO_PTR)); + current_db= my_strdup(argument, MYF(MY_WME)); break; case 'e': - status.batch=1; - status.add_to_history=0; + status.batch= 1; + status.add_to_history= 0; batch_readline_end(status.line_buff); // If multiple -e - if (!(status.line_buff=batch_readline_command(optarg))) + if (!(status.line_buff= batch_readline_command(argument))) return 1; - ignore_errors=0; - break; - case 'f': - ignore_errors=1; + ignore_errors= 0; break; case 'h': - my_free(current_host,MYF(MY_ALLOW_ZERO_PTR)); - current_host=my_strdup(optarg,MYF(MY_WME)); + my_free(current_host, MYF(MY_ALLOW_ZERO_PTR)); + current_host= my_strdup(argument, MYF(MY_WME)); break; #ifndef DONT_ALLOW_USER_CHANGE case 'u': - my_free(current_user,MYF(MY_ALLOW_ZERO_PTR)); - current_user= my_strdup(optarg,MYF(MY_WME)); + my_free(current_user, MYF(MY_ALLOW_ZERO_PTR)); + current_user= my_strdup(argument, MYF(MY_WME)); break; #endif - case 'U': - if (!optarg) - safe_updates=1; - else - safe_updates=atoi(optarg) != 0; - break; case 'o': - one_database=skip_updates=1; - break; - case 'O': - if (set_changeable_var(optarg, changeable_vars)) - { - usage(0); - return(1); - } + if (argument == disabled_my_option) + one_database= 0; + else + one_database= skip_updates= 1; break; case 'p': - if (optarg) + if (argument == disabled_my_option) + opt_password= ""; + else { - char *start=optarg; - my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); - opt_password=my_strdup(optarg,MYF(MY_FAE)); - while (*optarg) *optarg++= 'x'; // Destroy argument - if (*start) - start[1]=0; + if (argument) + { + char *start= argument; + my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR)); + opt_password= my_strdup(argument, MYF(MY_FAE)); + while (*argument) *argument++= 'x'; // Destroy argument + if (*start) + start[1]=0 ; + } + else + tty_password= 1; } + break; + case '#': + DBUG_PUSH(argument ? argument : default_dbug_option); + info_flag= 1; + break; + case 's': + if (argument == disabled_my_option) + opt_silent= 0; + else + opt_silent++; + break; + case 'v': + if (argument == disabled_my_option) + verbose= 0; else - tty_password=1; + verbose++; break; - case 't': output_tables=1; break; - case 'r': opt_raw_data=1; break; - case 'q': quick=1; break; - case 's': opt_silent++; break; - case 'T': info_flag=1; break; - case 'n': unbuffered=1; break; - case 'v': verbose++; break; - case 'E': vertical=1; break; - case 'A': no_rehash=1; break; - case 'G': no_named_cmds=0; break; - case 'g': no_named_cmds=1; break; - case 'H': opt_html=1; break; - case 'X': opt_xml=1; break; - case 'i': connect_flag|= CLIENT_IGNORE_SPACE; break; - case 'C': opt_compress=1; break; - case 'L': skip_line_numbers=1; break; - case 'N': skip_column_names=1; break; case 'w': - wait_flag=1; - if(optarg) wait_time = atoi(optarg) ; + if (argument == disabled_my_option) + wait_flag= 0; + else + { + wait_flag= 1; + if (argument) + wait_time= atoi(argument); + } + break; + case 'A': + printf("WARNING: option depricated; use --disable-auto-rehash instead.\n"); + no_rehash= 1; + break; + case 'g': + printf("WARNING: option depricated; use --disable-named-commands instead.\n"); + named_cmds= 0; + break; + case 'i': + connect_flag|= CLIENT_IGNORE_SPACE; break; case 'B': if (!status.batch) { - status.batch=1; - status.add_to_history=0; + status.batch= 1; + status.add_to_history= 0; opt_silent++; // more silent } break; case 'P': - opt_mysql_port= (unsigned int) atoi(optarg); + opt_mysql_port= (unsigned int) atoi(argument); break; case 'S': - my_free(opt_mysql_unix_port,MYF(MY_ALLOW_ZERO_PTR)); - opt_mysql_unix_port= my_strdup(optarg,MYF(0)); + my_free(opt_mysql_unix_port, MYF(MY_ALLOW_ZERO_PTR)); + opt_mysql_unix_port= my_strdup(argument, MYF(0)); break; case 'W': #ifdef __WIN__ - opt_mysql_unix_port=my_strdup(MYSQL_NAMEDPIPE,MYF(0)); + opt_mysql_unix_port= my_strdup(MYSQL_NAMEDPIPE, MYF(0)); #endif break; - case 'V': usage(1); exit(0); + case 'V': + usage(1); + exit(0); case 'I': case '?': usage(0); exit(0); - case '#': - DBUG_PUSH(optarg ? optarg : default_dbug_option); - info_flag=1; - break; #include "sslopt-case.h" - default: - tee_fprintf(stderr,"illegal option: -%c\n",opterr); - usage(0); - exit(1); - } } + return 0; +} + + +static int get_options(int argc, char **argv) +{ + char *tmp, *pagpoint; + int ho_error; + + tmp= (char *) getenv("MYSQL_HOST"); + if (tmp) + current_host= my_strdup(tmp, MYF(MY_WME)); + + pagpoint= getenv("PAGER"); + if (!((char*) (pagpoint))) + { + strmov(pager, "stdout"); + opt_nopager= 1; + } + else + strmov(pager, pagpoint); + strmov(default_pager, pager); + + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + { + printf("%s: handle_options() failed with error %d\n", my_progname, + ho_error); + exit(1); + } + if (status.batch) /* disable pager and outfile in this case */ { strmov(default_pager, "stdout"); strmov(pager, "stdout"); - opt_nopager=1; - opt_outfile=0; + opt_nopager= 1; + opt_outfile= 0; } if (default_charset) { if (set_default_charset_by_name(default_charset, MYF(MY_WME))) exit(1); } - argc-=optind; - argv+=optind; if (argc > 1) { usage(0); @@ -828,20 +779,25 @@ static int get_options(int argc, char **argv) } if (argc == 1) { - my_free(current_db,MYF(MY_ALLOW_ZERO_PTR)); - current_db= my_strdup(*argv,MYF(MY_WME)); - } - if (!current_host) - { /* If we don't have a hostname have a look at MYSQL_HOST */ - char *tmp=(char *) getenv("MYSQL_HOST"); - if (tmp) - current_host = my_strdup(tmp,MYF(MY_WME)); + my_free(current_db, MYF(MY_ALLOW_ZERO_PTR)); + current_db= my_strdup(*argv, MYF(MY_WME)); } if (tty_password) - opt_password=get_tty_password(NullS); + opt_password= get_tty_password(NullS); return(0); } +#if defined(OS2) +static char* readline( char* prompt) +{ +#if defined(OS2) + static char linebuffer[254]; +#endif + puts( prompt); + return gets( linebuffer); +} +#endif + static int read_lines(bool execute_commands) { #if defined( __WIN__) || defined(OS2) @@ -867,7 +823,7 @@ static int read_lines(bool execute_commands) #if defined( __WIN__) || defined(OS2) if (opt_outfile && glob_buffer.is_empty()) fflush(OUTFILE); - tee_fputs(glob_buffer.is_empty() ? construct_prompt() : + tee_fputs(glob_buffer.is_empty() ? "mysql> " : !in_string ? " -> " : in_string == '\'' ? " '> " : " \"> ",stdout); @@ -878,12 +834,12 @@ static int read_lines(bool execute_commands) { if (glob_buffer.is_empty()) fflush(OUTFILE); - fputs(glob_buffer.is_empty() ? construct_prompt() : + fputs(glob_buffer.is_empty() ? "mysql> " : !in_string ? " -> " : in_string == '\'' ? " '> " : " \"> ", OUTFILE); } - line=readline((char*) (glob_buffer.is_empty() ? construct_prompt() : + line=readline((char*) (glob_buffer.is_empty() ? "mysql> " : !in_string ? " -> " : in_string == '\'' ? " '> " : " \"> ")); @@ -903,7 +859,7 @@ static int read_lines(bool execute_commands) /* Check if line is a mysql command line */ /* (We want to allow help, print and clear anywhere at line start */ - if (execute_commands && (!no_named_cmds || glob_buffer.is_empty()) + if (execute_commands && (named_cmds || glob_buffer.is_empty()) && !in_string && (com=find_command(line,0))) { if ((*com->func)(&glob_buffer,line) > 0) @@ -1393,7 +1349,7 @@ com_help (String *buffer __attribute__((unused)), reg1 int i; put_info("\nMySQL commands:",INFO_INFO); - if (no_named_cmds) + if (!named_cmds) put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO); for (i = 0; commands[i].name; i++) { @@ -1643,7 +1599,7 @@ print_table_data(MYSQL_RES *result) separator.copy("+",1); while ((field = mysql_fetch_field(result))) { - uint length=skip_column_names ? 0 : (uint) strlen(field->name); + uint length= column_names ? (uint) strlen(field->name) : 0; if (quick) length=max(length,field->length); else @@ -1655,7 +1611,7 @@ print_table_data(MYSQL_RES *result) separator.append('+'); } tee_puts(separator.c_ptr(), PAGER); - if (!skip_column_names) + if (column_names) { mysql_field_seek(result,0); (void) tee_fputs("|", PAGER); @@ -1700,7 +1656,7 @@ print_table_data_html(MYSQL_RES *result) mysql_field_seek(result,0); (void) tee_fputs("<TABLE BORDER=1><TR>", PAGER); - if (!skip_column_names) + if (column_names) { while((field = mysql_fetch_field(result))) { @@ -1735,7 +1691,7 @@ print_table_data_xml(MYSQL_RES *result) mysql_field_seek(result,0); tee_fputs("<?xml version=\"1.0\"?>\n\n<resultset statement=\"", PAGER); - xmlencode_print(glob_buffer.ptr(), strlen(glob_buffer.ptr())); + xmlencode_print(glob_buffer.ptr(), strlen(glob_buffer.ptr()) - 1); tee_fputs("\">", PAGER); fields = mysql_fetch_fields(result); @@ -1863,7 +1819,7 @@ print_tab_data(MYSQL_RES *result) MYSQL_FIELD *field; ulong *lengths; - if (opt_silent < 2 && !skip_column_names) + if (opt_silent < 2 && column_names) { int first=0; while ((field = mysql_fetch_field(result))) @@ -2215,7 +2171,7 @@ com_use(String *buffer __attribute__((unused)), char *line) if (!current_db || cmp_database(current_db,tmp)) { if (one_database) - skip_updates=1; + skip_updates= 1; else { /* @@ -2242,7 +2198,7 @@ com_use(String *buffer __attribute__((unused)), char *line) } } else - skip_updates=0; + skip_updates= 0; put_info("Database changed",INFO_INFO); return 0; } @@ -2263,8 +2219,6 @@ sql_real_connect(char *host,char *database,char *user,char *password, } if (opt_compress) mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS); - if (using_opt_local_infile) - mysql_options(&mysql,MYSQL_OPT_LOCAL_INFILE, (char*) &opt_local_infile); #ifdef HAVE_OPENSSL if (opt_use_ssl) mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, @@ -2278,8 +2232,8 @@ sql_real_connect(char *host,char *database,char *user,char *password, select_limit,max_join_size); mysql_options(&mysql, MYSQL_INIT_COMMAND, init_command); } - if (!mysql_real_connect(&mysql,host,user,password, - database,opt_mysql_port,opt_mysql_unix_port, + if (!mysql_real_connect(&mysql, host, user, password, + database, opt_mysql_port, opt_mysql_unix_port, connect_flag)) { if (!silent || @@ -2340,7 +2294,7 @@ static int com_status(String *buffer __attribute__((unused)), char *line __attribute__((unused))) { - const char *status; + char *status; tee_puts("--------------", stdout); usage(1); /* Print version */ if (connected) @@ -2436,7 +2390,7 @@ put_info(const char *str,INFO_TYPE info_type,uint error) fprintf(stderr,"ERROR"); if (error) (void) fprintf(stderr," %d",error); - if (status.query_start_line && ! skip_line_numbers) + if (status.query_start_line && line_numbers) { (void) fprintf(stderr," at line %lu",status.query_start_line); if (status.file_name) @@ -2464,8 +2418,7 @@ put_info(const char *str,INFO_TYPE info_type,uint error) } if (info_type == INFO_ERROR) { - if(!opt_nobeep) - putchar('\007'); /* This should make a bell */ + putchar('\007'); /* This should make a bell */ vidattr(A_STANDOUT); if (error) (void) tee_fprintf(stderr, "ERROR %d: ", error); @@ -2608,175 +2561,6 @@ static void mysql_end_timer(ulong start_time,char *buff) strmov(strend(buff),")"); } -static const char* construct_prompt() { - //erase the old prompt - processed_prompt.free(); - //get the date struct - time_t lclock = time(NULL); - struct tm *t = localtime(&lclock); - //parse thru the settings for the prompt - for (char *c = current_prompt;*c;*c++) { - if (*c != PROMPT_CHAR) { - processed_prompt.append(*c); - } - else { - switch (*++c) { - case '\0': - //stop it from going beyond if ends with % - c--; - break; - case 'c': - add_int_to_prompt(++prompt_counter); - break; - case 'v': - processed_prompt.append(mysql_get_server_info(&mysql)); - break; - case 'd': - processed_prompt.append(current_db ? current_db : "(none)"); - break; - case 'h': - { - const char *prompt=mysql_get_host_info(&mysql); - if (strstr(prompt, "Localhost")) - processed_prompt.append("localhost"); - else - { - const char *end=strcend(prompt,' '); - processed_prompt.append(prompt, (uint) (end-prompt)); - } - break; - } - case 'p': - if (strstr(mysql_get_host_info(&mysql),"TCP/IP") || - ! mysql.unix_socket) - add_int_to_prompt(mysql.port); - else - processed_prompt.append(strrchr(mysql.unix_socket,'/')+1); - break; - case 'U': - if (!full_username) - init_username(); - processed_prompt.append(full_username); - break; - case 'u': - if (!full_username) - init_username(); - processed_prompt.append(part_username); - break; - case PROMPT_CHAR: - processed_prompt.append(PROMPT_CHAR); - break; - case 'n': - processed_prompt.append('\n'); - break; - case ' ': - case '_': - processed_prompt.append(' '); - break; - case 'R': - add_int_to_prompt(t->tm_hour); - break; - case 'r': - int getHour; - getHour = t->tm_hour % 12; - if (getHour == 0) - getHour=12; - add_int_to_prompt(getHour); - break; - case 'm': - if (t->tm_min < 10) - processed_prompt.append('0'); - add_int_to_prompt(t->tm_min); - break; - case 'y': - int getYear; - getYear = t->tm_year % 100; - if (getYear < 10) - processed_prompt.append('0'); - add_int_to_prompt(getYear); - break; - case 'Y': - add_int_to_prompt(t->tm_year+1900); - break; - case 'D': - char* dateTime; - time_t lclock; - lclock = time(NULL); - dateTime = ctime(&lclock); - processed_prompt.append(strtok(dateTime,"\n")); - break; - case 's': - add_int_to_prompt(t->tm_sec); - break; - case 'w': - processed_prompt.append(day_names[t->tm_wday]); - break; - case 'P': - processed_prompt.append(t->tm_hour < 12 ? "am" : "pm"); - break; - case 'o': - add_int_to_prompt(t->tm_mon+1); - break; - case 'O': - processed_prompt.append(month_names[t->tm_mon]); - break; - case '\'': - processed_prompt.append("'"); - break; - case '"': - processed_prompt.append('"'); - break; - case 'S': - processed_prompt.append(';'); - break; - case 't': - processed_prompt.append('\t'); - break; - default: - processed_prompt.append(c); - } - } - } - processed_prompt.append('\0'); - return processed_prompt.ptr(); -} - -static void add_int_to_prompt(int toadd) { - char buffer[16]; - int10_to_str(toadd,buffer,10); - processed_prompt.append(buffer); -} - -static void init_username() { - my_free(full_username,MYF(MY_ALLOW_ZERO_PTR)); - my_free(part_username,MYF(MY_ALLOW_ZERO_PTR)); - - MYSQL_RES *result; - LINT_INIT(result); - if (!mysql_query(&mysql,"select USER()") && - (result=mysql_use_result(&mysql))) - { - MYSQL_ROW cur=mysql_fetch_row(result); - full_username=my_strdup(cur[0],MYF(MY_WME)); - part_username=my_strdup(strtok(cur[0],"@"),MYF(MY_WME)); - (void) mysql_fetch_row(result); // Read eof - } -} - -static int -com_prompt(String *buffer, char *line __attribute__((unused))) { - prompt_counter = 0; - my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR)); - current_prompt=my_strdup(strchr(line, ' ') ? - strchr(line, ' ')+1 : - default_prompt,MYF(MY_WME)); - if (!strchr(line, ' ')) - tee_fprintf(stdout, "Returning to default PROMPT of %s\n", default_prompt); - else - tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt); - return 0; -} - #ifndef EMBEDDED_LIBRARY /* Keep sql_string library happy */ diff --git a/client/mysqladmin.c b/client/mysqladmin.c index 17a453adbdf3d5156e51bc9227e322862c9d9595..c5f8d653d82f6a7219c417b1d38acc1397852c10 100644 --- a/client/mysqladmin.c +++ b/client/mysqladmin.c @@ -19,21 +19,24 @@ #include "client_priv.h" #include <signal.h> +#include <my_getopt.h> #ifdef THREAD #include <my_pthread.h> /* because of signal() */ #endif -#define ADMIN_VERSION "8.23" +#define ADMIN_VERSION "8.30" #define MAX_MYSQL_VAR 64 #define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */ #define MAX_TRUNC_LENGTH 3 +char *host= NULL, *user= 0, *opt_password= 0; char truncated_var_names[MAX_MYSQL_VAR][MAX_TRUNC_LENGTH]; char ex_var_names[MAX_MYSQL_VAR][FN_REFLEN]; ulonglong last_values[MAX_MYSQL_VAR]; static int interval=0; static my_bool option_force=0,interrupted=0,new_line=0, - opt_compress=0, opt_relative=0, opt_verbose=0, opt_vertical=0; + opt_compress=0, opt_relative=0, opt_verbose=0, opt_vertical=0, + tty_password=0; static uint tcp_port = 0, option_wait = 0, option_silent=0; static ulong opt_connect_timeout, opt_shutdown_timeout; static my_string unix_port=0; @@ -49,8 +52,7 @@ static uint ex_var_count, max_var_length, max_val_length; static void print_version(void); static void usage(void); -static my_bool sql_connect(MYSQL *mysql,const char *host, const char *user, - const char *password,uint wait); +static my_bool sql_connect(MYSQL *mysql, uint wait); static int execute_commands(MYSQL *mysql,int argc, char **argv); static int drop_db(MYSQL *mysql,const char *db); static sig_handler endprog(int signal_number); @@ -97,158 +99,176 @@ static const char *command_names[]= { static TYPELIB command_typelib= { array_elements(command_names)-1,"commands", command_names}; -static struct option long_options[] = { - {"compress", no_argument, 0, 'C'}, - {"character-sets-dir", required_argument, 0, OPT_CHARSETS_DIR}, - {"debug", optional_argument, 0, '#'}, - {"force", no_argument, 0, 'f'}, - {"help", no_argument, 0, '?'}, - {"host", required_argument, 0, 'h'}, - {"password", optional_argument, 0, 'p'}, +static struct my_option my_long_options[] = +{ + {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"force", 'f', + "Don't ask for confirmation on drop database; with multiple commands, continue even if an error occurs.", + (gptr*) &option_force, (gptr*) &option_force, 0, GET_BOOL, NO_ARG, 0, 0, + 0, 0, 0, 0}, + {"compress", 'C', "Use compression in server/client protocol", + (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"character-sets-dir", OPT_CHARSETS_DIR, + "Directory where character sets are.", (gptr*) &charsets_dir, + (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"host", 'h', "Connect to host", (gptr*) &host, (gptr*) &host, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"password", 'p', + "Password to use when connecting to server. If password is not given it's asked from the tty.", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __WIN__ - {"pipe", no_argument, 0, 'W'}, + {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"port", required_argument, 0, 'P'}, - {"relative", no_argument, 0, 'r'}, - {"set-variable", required_argument, 0, 'O'}, - {"silent", no_argument, 0, 's'}, - {"socket", required_argument, 0, 'S'}, - {"sleep", required_argument, 0, 'i'}, + {"port", 'P', "Port number to use for connection.", 0, 0, 0, + GET_LONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"relative", 'r', + "Show difference between current and previous values when used with -i. Currently works only with extended-status.", + (gptr*) &opt_relative, (gptr*) &opt_relative, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"set-variable", 'O', + "Change the value of a variable. Please note that this option is depricated; you can set variables directly with --variable-name=value.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"silent", 's', "Silently exit if one can't connect to server", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"socket", 'S', "Socket file to use for connection.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"sleep", 'i', "Execute commands again and again with a sleep between.", + 0, 0, 0, GET_LONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #include "sslopt-longopts.h" #ifndef DONT_ALLOW_USER_CHANGE - {"user", required_argument, 0, 'u'}, + {"user", 'u', "User for login if not current user.", (gptr*) &user, + (gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"vertical", no_argument, 0, 'E'}, - {"wait", optional_argument, 0, 'w'}, - {0, 0, 0, 0} + {"verbose", 'v', "Write more information.", (gptr*) &opt_verbose, + (gptr*) &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"version", 'V', "Output version information and exit", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"vertical", 'E', + "Print output vertically. Is similar to --relative, but prints output vertically.", + (gptr*) &opt_vertical, (gptr*) &opt_vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"wait", 'w', "Wait and retry if connection is down", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"connect_timeout", OPT_CONNECT_TIMEOUT, "", (gptr*) &opt_connect_timeout, + (gptr*) &opt_connect_timeout, 0, GET_LONG, REQUIRED_ARG, 3600*12, 0, + 3600*12, 0, 1, 0}, + {"shutdown_timeout", OPT_SHUTDOWN_TIMEOUT, "", (gptr*) &opt_shutdown_timeout, + (gptr*) &opt_shutdown_timeout, 0, GET_LONG, REQUIRED_ARG, + SHUTDOWN_DEF_TIMEOUT, 0, 3600*12, 0, 1, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; -static CHANGEABLE_VAR changeable_vars[] = { - { "connect_timeout", (long*) &opt_connect_timeout, 0, 0, 3600*12, 0, 1}, - { "shutdown_timeout", (long*) &opt_shutdown_timeout, SHUTDOWN_DEF_TIMEOUT, 0, - 3600*12, 0, 1}, - { 0, 0, 0, 0, 0, 0, 0} -}; static const char *load_default_groups[]= { "mysqladmin","client",0 }; -int main(int argc,char *argv[]) +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument) { - int c, error = 0,option_index=0; - MYSQL mysql; - char *host = NULL,*opt_password=0,*user=0,**commands; - my_bool tty_password=0; - MY_INIT(argv[0]); - mysql_init(&mysql); - load_defaults("my",load_default_groups,&argc,&argv); - set_all_changeable_vars( changeable_vars ); - - while ((c=getopt_long(argc,argv, - (char*) "h:i:p::u:#::P:sS:Ct:fq?vVw::WrEO:", - long_options, &option_index)) != EOF) - { - switch(c) { - case 'C': - opt_compress=1; - break; - case 'h': - host = optarg; - break; - case 'q': /* Allow old 'q' option */ - case 'f': - option_force++; - break; - case 'p': - if (optarg) - { - char *start=optarg; - my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); - opt_password=my_strdup(optarg,MYF(MY_FAE)); - while (*optarg) *optarg++= 'x'; /* Destroy argument */ - if (*start) - start[1]=0; /* Cut length of argument */ - } - else - tty_password=1; - break; + int error = 0; + + switch(optid) { + case 'h': + host = argument; + break; + case 'q': /* Allow old 'q' option */ + case 'p': + if (argument) + { + char *start=argument; + my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); + opt_password=my_strdup(argument,MYF(MY_FAE)); + while (*argument) *argument++= 'x'; /* Destroy argument */ + if (*start) + start[1]=0; /* Cut length of argument */ + } + else + tty_password=1; + break; #ifndef DONT_ALLOW_USER_CHANGE - case 'u': - user= my_strdup(optarg,MYF(0)); - break; + case 'u': + user= my_strdup(argument,MYF(0)); + break; #endif - case 'i': - interval=atoi(optarg); - break; - case 'P': - tcp_port= (unsigned int) atoi(optarg); - break; - case 'r': - opt_relative = 1; - break; - case 'E': - opt_vertical = 1; - break; - case 'O': - if (set_changeable_var(optarg, changeable_vars)) - { - usage(); - return(1); - } - break; - case 's': - option_silent++; - break; - case 'S': - unix_port= optarg; - break; - case 'W': + case 'i': + interval=atoi(argument); + break; + case 'P': + tcp_port= (unsigned int) atoi(argument); + break; + case 's': + option_silent++; + break; + case 'S': + unix_port= argument; + break; + case 'W': #ifdef __WIN__ - unix_port=MYSQL_NAMEDPIPE; + unix_port=MYSQL_NAMEDPIPE; #endif - break; - case '#': - DBUG_PUSH(optarg ? optarg : "d:t:o,/tmp/mysqladmin.trace"); - break; - case 'V': - print_version(); - exit(0); - break; - case 'v': - opt_verbose=1; - break; - case 'w': - if (optarg) - { - if ((option_wait=atoi(optarg)) <= 0) - option_wait=1; - } - else - option_wait= ~0; - break; + break; + case '#': + DBUG_PUSH(argument ? argument : "d:t:o,/tmp/mysqladmin.trace"); + break; + case 'V': + print_version(); + exit(0); + break; + case 'w': + if (argument) + { + if ((option_wait=atoi(argument)) <= 0) + option_wait=1; + } + else + option_wait= ~0; + break; #include "sslopt-case.h" - default: - fprintf(stderr,"Illegal option character '%c'\n",opterr); - /* Fall throught */ - case '?': - case 'I': /* Info */ - error++; - break; - case OPT_CHARSETS_DIR: + case '?': + case 'I': /* Info */ + error++; + break; + case OPT_CHARSETS_DIR: #if MYSQL_VERSION_ID > 32300 - charsets_dir = optarg; + charsets_dir = argument; #endif - break; - } + break; + } + if (error) + { + usage(); + exit(1); + } + return 0; +} + + +int main(int argc,char *argv[]) +{ + int error, ho_error; + MYSQL mysql; + char **commands; + MY_INIT(argv[0]); + mysql_init(&mysql); + load_defaults("my",load_default_groups,&argc,&argv); + + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + { + printf("%s: handle_options() failed with error %d\n", my_progname, + ho_error); + exit(1); } - argc -= optind; - commands = argv + optind; - if (error || argc == 0) + if (argc == 0) { usage(); exit(1); } + commands = argv; if (tty_password) opt_password = get_tty_password(NullS); @@ -267,7 +287,7 @@ int main(int argc,char *argv[]) mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); #endif /* HAVE_OPENSSL */ - if (sql_connect(&mysql,host,user,opt_password,option_wait)) + if (sql_connect(&mysql, option_wait)) error = 1; else { @@ -284,7 +304,7 @@ int main(int argc,char *argv[]) if (option_wait && !interrupted) { mysql_close(&mysql); - if (!sql_connect(&mysql,host,user,opt_password,option_wait)) + if (!sql_connect(&mysql, option_wait)) { sleep(1); /* Don't retry too rapidly */ continue; /* Retry */ @@ -320,15 +340,14 @@ static sig_handler endprog(int signal_number __attribute__((unused))) } -static my_bool sql_connect(MYSQL *mysql,const char *host, const char *user, - const char *password,uint wait) +static my_bool sql_connect(MYSQL *mysql, uint wait) { my_bool info=0; for (;;) { - if (mysql_real_connect(mysql,host,user,password,NullS,tcp_port,unix_port, - 0)) + if (mysql_real_connect(mysql,host,user,opt_password,NullS,tcp_port, + unix_port, 0)) { if (info) { @@ -343,7 +362,7 @@ static my_bool sql_connect(MYSQL *mysql,const char *host, const char *user, if (!option_silent) { if (!host) - host=LOCAL_HOST; + host= (char*) LOCAL_HOST; my_printf_error(0,"connect to server at '%s' failed\nerror: '%s'", MYF(ME_BELL), host, mysql_error(mysql)); if (mysql_errno(mysql) == CR_CONNECTION_ERROR) @@ -788,52 +807,14 @@ static void print_version(void) static void usage(void) { - uint i; print_version(); puts("Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB"); puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); puts("Administration program for the mysqld daemon."); printf("Usage: %s [OPTIONS] command command....\n", my_progname); - printf("\n\ - -#, --debug=... Output debug log. Often this is 'd:t:o,filename`\n\ - -f, --force Don't ask for confirmation on drop database; with\n\ - multiple commands, continue even if an error occurs\n\ - -?, --help Display this help and exit\n\ - --character-sets-dir=...\n\ - Set the character set directory\n\ - -C, --compress Use compression in server/client protocol\n\ - -h, --host=# Connect to host\n\ - -p, --password[=...] Password to use when connecting to server\n\ - If password is not given it's asked from the tty\n"); -#ifdef __WIN__ - puts("-W, --pipe Use named pipes to connect to server"); -#endif - printf("\ - -P --port=... Port number to use for connection\n\ - -i, --sleep=sec Execute commands again and again with a sleep between\n\ - -r, --relative Show difference between current and previous values\n\ - when used with -i. Currently works only with\n\ - extended-status\n\ - -E, --vertical Print output vertically. Is similar to --relative,\n\ - but prints output vertically.\n\ - -s, --silent Silently exit if one can't connect to server\n\ - -S, --socket=... Socket file to use for connection\n"); -#include "sslopt-usage.h" -#ifndef DONT_ALLOW_USER_CHANGE - printf("\ - -u, --user=# User for login if not current user\n"); -#endif - printf("\ - -v, --verbose Write more information\n\ - -V, --version Output version information and exit\n\ - -w, --wait[=retries] Wait and retry if connection is down\n"); + my_print_help(my_long_options); + my_print_variables(my_long_options); print_defaults("my",load_default_groups); - printf("\nPossible variables for option --set-variable (-O) are:\n"); - for (i=0 ; changeable_vars[i].name ; i++) - printf("%-20s current value: %lu\n", - changeable_vars[i].name, - (ulong) *changeable_vars[i].varptr); - puts("\nWhere command is a one or more of: (Commands may be shortened)\n\ create databasename Create a new database\n\ drop databasename Delete a database and all its tables\n\ diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index eccc08f59ec49c75e1f8f37440cbbf814ad3acad..86507bc0b31028858648d0df20168349d57e2867 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -16,9 +16,10 @@ /* By Jani Tolonen, 2001-04-20, MySQL Development Team */ -#define CHECK_VERSION "1.02" +#define CHECK_VERSION "2.0" #include "client_priv.h" +#include <my_getopt.h> #include <m_ctype.h> #include "mysql_version.h" #include "mysqld_error.h" @@ -33,7 +34,8 @@ static MYSQL mysql_connection, *sock = 0; static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0, opt_compress = 0, opt_databases = 0, opt_fast = 0, opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0, - opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0; + opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0, + tty_password = 0; static uint verbose = 0, opt_mysql_port=0; static my_string opt_mysql_unix_port = 0; static char *opt_password = 0, *current_user = 0, *default_charset = 0, @@ -43,45 +45,96 @@ DYNAMIC_ARRAY tables4repair; enum operations {DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE}; -static struct option long_options[] = +static struct my_option my_long_options[] = { - {"all-databases", no_argument, 0, 'A'}, - {"all-in-1", no_argument, 0, '1'}, - {"auto-repair", no_argument, 0, OPT_AUTO_REPAIR}, - {"analyze", no_argument, 0, 'a'}, - {"character-sets-dir", required_argument, 0, OPT_CHARSETS_DIR}, - {"check", no_argument, 0, 'c'}, - {"check-only-changed", no_argument, 0, 'C'}, - {"compress", no_argument, 0, OPT_COMPRESS}, - {"databases", no_argument, 0, 'B'}, - {"debug", optional_argument, 0, '#'}, - {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET}, - {"fast", no_argument, 0, 'F'}, - {"force", no_argument, 0, 'f'}, - {"extended", no_argument, 0, 'e'}, - {"help", no_argument, 0, '?'}, - {"host", required_argument, 0, 'h'}, - {"medium-check", no_argument, 0, 'm'}, - {"optimize", no_argument, 0, 'o'}, - {"password", optional_argument, 0, 'p'}, + {"all-databases", 'A', + "Check all the databases. This will be same as --databases with all databases selected.", + (gptr*) &opt_alldbs, (gptr*) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, + {"analyze", 'a', "Analyze given tables.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, + 0, 0, 0, 0}, + {"all-in-1", '1', + "Instead of making one query for each table, execute all queries in 1 query separately for each database. Table names will be in a comma separeted list.", + (gptr*) &opt_all_in_1, (gptr*) &opt_all_in_1, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"auto-repair", OPT_AUTO_REPAIR, + "If a checked table is corrupted, automatically fix it. Repairing will be done after all tables have been checked, if corrupted ones were found.", + (gptr*) &opt_auto_repair, (gptr*) &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0, + 0, 0, 0, 0, 0}, + {"character-sets-dir", OPT_CHARSETS_DIR, + "Directory where character sets are", (gptr*) &charsets_dir, + (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"check", 'c', "Check table for errors", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, + 0, 0, 0, 0}, + {"check-only-changed", 'C', + "Check only tables that have changed since last check or haven't been closed properly.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"compress", OPT_COMPRESS, "Use compression in server/client protocol.", + (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"databases", 'B', + "To check several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames.", + (gptr*) &opt_databases, (gptr*) &opt_databases, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, + {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"default-character-set", OPT_DEFAULT_CHARSET, + "Set the default character set", (gptr*) &default_charset, + (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"fast",'F', "Check only tables that hasn't been closed properly", + (gptr*) &opt_fast, (gptr*) &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, + 0}, + {"force", 'f', "Continue even if we get an sql-error.", + (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0, + 0, 0, 0, 0}, + {"extended", 'e', + "If you are using this option with CHECK TABLE, it will ensure that the table is 100 percent consistent, but will take a long time. If you are using this option with REPAIR TABLE, it will run an extended repair on the table, which may not only take a long time to execute, but may produce a lot of garbage rows also!", + (gptr*) &opt_extended, (gptr*) &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"host",'h', "Connect to host.", (gptr*) ¤t_host, + (gptr*) ¤t_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"medium-check", 'm', + "Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, + 0, 0}, + {"password", 'p', + "Password to use when connecting to server. If password is not given it's solicited on the tty.", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __WIN__ - {"pipe", no_argument, 0, 'W'}, + {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"port", required_argument, 0, 'P'}, - {"quick", no_argument, 0, 'q'}, - {"repair", no_argument, 0, 'r'}, - {"silent", no_argument, 0, 's'}, - {"socket", required_argument, 0, 'S'}, + {"port", 'P', "Port number to use for connection.", 0, 0, 0, GET_LONG, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"quick", 'q', + "If you are using this option with CHECK TABLE, it prevents the check from scanning the rows to check for wrong links. This is the fastest check. If you are using this option with REPAIR TABLE, it will try to repair only the index tree. This is the fastest repair method for a table.", + (gptr*) &opt_quick, (gptr*) &opt_quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, + 0}, + {"repair", 'r', + "Can fix almost anything except unique keys that aren't unique.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"silent", 's', "Print only error messages.", (gptr*) &opt_silent, + (gptr*) &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"socket", 'S', "Socket file to use for connection.", + (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #include "sslopt-longopts.h" - {"tables", no_argument, 0, OPT_TABLES}, + {"tables", OPT_TABLES, "Overrides option --databases (-B).", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifndef DONT_ALLOW_USER_CHANGE - {"user", required_argument, 0, 'u'}, + {"user", 'u', "User for login if not current user.", (gptr*) ¤t_user, + (gptr*) ¤t_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {0, 0, 0, 0} + {"verbose", 'v', "Print info about the various stages.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; - + static const char *load_default_groups[] = { "mysqlcheck", "client", 0 }; @@ -131,78 +184,99 @@ static void usage(void) printf("OR %s [OPTIONS] --databases DB1 [DB2 DB3...]\n", my_progname); printf("OR %s [OPTIONS] --all-databases\n", my_progname); - printf("\ - -A, --all-databases Check all the databases. This will be same as\n\ - --databases with all databases selected\n\ - -1, --all-in-1 Instead of making one query for each table, execute\n\ - all queries in 1 query separately for each database.\n\ - Table names will be in a comma separeted list.\n\ - -a, --analyze Analyze given tables.\n\ - --auto-repair If a checked table is corrupted, automatically fix\n\ - it. Repairing will be done after all tables have\n\ - been checked, if corrupted ones were found.\n\ - -#, --debug=... Output debug log. Often this is 'd:t:o,filename'\n\ - --character-sets-dir=...\n\ - Directory where character sets are\n\ - -c, --check Check table for errors\n\ - -C, --check-only-changed\n\ - Check only tables that have changed since last check\n\ - or haven't been closed properly.\n\ - --compress Use compression in server/client protocol.\n\ - -?, --help Display this help message and exit.\n\ - -B, --databases To check several databases. Note the difference in\n\ - usage; In this case no tables are given. All name\n\ - arguments are regarded as databasenames.\n\ - --default-character-set=...\n\ - Set the default character set\n\ - -F, --fast Check only tables that hasn't been closed properly\n\ - -f, --force Continue even if we get an sql-error.\n\ - -e, --extended If you are using this option with CHECK TABLE,\n\ - it will ensure that the table is 100 percent\n\ - consistent, but will take a long time.\n\n"); -printf("\ - If you are using this option with REPAIR TABLE,\n\ - it will run an extended repair on the table, which\n\ - may not only take a long time to execute, but\n\ - may produce a lot of garbage rows also!\n\ - -h, --host=... Connect to host.\n\ - -m, --medium-check Faster than extended-check, but only finds 99.99 percent\n\ - of all errors. Should be good enough for most cases.\n\ - -o, --optimize Optimize table\n\ - -p, --password[=...] Password to use when connecting to server.\n\ - If password is not given it's solicited on the tty.\n"); -#ifdef __WIN__ - puts("-W, --pipe Use named pipes to connect to server"); -#endif - printf("\ - -P, --port=... Port number to use for connection.\n\ - -q, --quick If you are using this option with CHECK TABLE, it\n\ - prevents the check from scanning the rows to check\n\ - for wrong links. This is the fastest check.\n\n\ - If you are using this option with REPAIR TABLE, it\n\ - will try to repair only the index tree. This is\n\ - the fastest repair method for a table.\n\ - -r, --repair Can fix almost anything except unique keys that aren't\n\ - unique.\n\ - -s, --silent Print only error messages.\n\ - -S, --socket=... Socket file to use for connection.\n\ - --tables Overrides option --databases (-B).\n"); -#include "sslopt-usage.h" -#ifndef DONT_ALLOW_USER_CHANGE - printf("\ - -u, --user=# User for login if not current user.\n"); -#endif - printf("\ - -v, --verbose Print info about the various stages.\n\ - -V, --version Output version information and exit.\n"); print_defaults("my", load_default_groups); + my_print_help(my_long_options); + my_print_variables(my_long_options); } /* usage */ +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument) +{ + switch(optid) { + case 'a': + what_to_do = DO_ANALYZE; + break; + case OPT_DEFAULT_CHARSET: + default_charset = argument; + break; + case OPT_CHARSETS_DIR: + charsets_dir = argument; + break; + case 'c': + what_to_do = DO_CHECK; + break; + case 'C': + what_to_do = DO_CHECK; + opt_check_only_changed = 1; + break; + case 'I': /* Fall through */ + case '?': + usage(); + exit(0); + case 'h': + my_free(current_host, MYF(MY_ALLOW_ZERO_PTR)); + current_host = my_strdup(argument, MYF(MY_WME)); + break; + case 'm': + what_to_do = DO_CHECK; + opt_medium_check = 1; + break; + case 'o': + what_to_do = DO_OPTIMIZE; + break; +#ifndef DONT_ALLOW_USER_CHANGE + case 'u': + current_user = argument; + break; +#endif + case 'p': + if (argument) + { + char *start = argument; + my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR)); + opt_password = my_strdup(argument, MYF(MY_FAE)); + while (*argument) *argument++= 'x'; /* Destroy argument */ + if (*start) + start[1] = 0; /* Cut length of argument */ + } + else + tty_password = 1; + break; + case 'P': + opt_mysql_port = (unsigned int) atoi(argument); + break; + case 'r': + what_to_do = DO_REPAIR; + break; + case 'S': + opt_mysql_unix_port = argument; + break; + case 'W': +#ifdef __WIN__ + opt_mysql_unix_port = MYSQL_NAMEDPIPE; +#endif + break; + case '#': + DBUG_PUSH(argument ? argument : "d:t:o"); + break; + case OPT_TABLES: + opt_databases = 0; + break; + case 'v': + verbose++; + break; + case 'V': print_version(); exit(0); +#include "sslopt-case.h" + } + return 0; +} + + static int get_options(int *argc, char ***argv) { - int c, option_index; - my_bool tty_password = 0; + int ho_error; if (*argc == 1) { @@ -211,119 +285,14 @@ static int get_options(int *argc, char ***argv) } load_defaults("my", load_default_groups, argc, argv); - while ((c = getopt_long(*argc, *argv, "#::p::h:u:P:S:BaAcCdeFfmqorsvVw:?I1", - long_options, &option_index)) != EOF) + + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) { - switch(c) { - case 'a': - what_to_do = DO_ANALYZE; - break; - case '1': - opt_all_in_1 = 1; - break; - case 'A': - opt_alldbs = 1; - break; - case OPT_AUTO_REPAIR: - opt_auto_repair = 1; - break; - case OPT_DEFAULT_CHARSET: - default_charset = optarg; - break; - case OPT_CHARSETS_DIR: - charsets_dir = optarg; - break; - case 'c': - what_to_do = DO_CHECK; - break; - case 'C': - what_to_do = DO_CHECK; - opt_check_only_changed = 1; - break; - case 'e': - opt_extended = 1; - break; - case OPT_COMPRESS: - opt_compress = 1; - break; - case 'B': - opt_databases = 1; - break; - case 'F': - opt_fast = 1; - break; - case 'f': - ignore_errors = 1; - break; - case 'I': /* Fall through */ - case '?': - usage(); - exit(0); - case 'h': - my_free(current_host, MYF(MY_ALLOW_ZERO_PTR)); - current_host = my_strdup(optarg, MYF(MY_WME)); - break; - case 'm': - what_to_do = DO_CHECK; - opt_medium_check = 1; - break; - case 'o': - what_to_do = DO_OPTIMIZE; - break; -#ifndef DONT_ALLOW_USER_CHANGE - case 'u': - current_user = optarg; - break; -#endif - case 'p': - if (optarg) - { - char *start = optarg; - my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR)); - opt_password = my_strdup(optarg, MYF(MY_FAE)); - while (*optarg) *optarg++= 'x'; /* Destroy argument */ - if (*start) - start[1] = 0; /* Cut length of argument */ - } - else - tty_password = 1; - break; - case 'P': - opt_mysql_port = (unsigned int) atoi(optarg); - break; - case 'q': - opt_quick = 1; - break; - case 'r': - what_to_do = DO_REPAIR; - break; - case 'S': - opt_mysql_unix_port = optarg; - break; - case 's': - opt_silent = 1; - break; - case 'W': -#ifdef __WIN__ - opt_mysql_unix_port = MYSQL_NAMEDPIPE; -#endif - break; - case '#': - DBUG_PUSH(optarg ? optarg : "d:t:o"); - break; - case OPT_TABLES: - opt_databases = 0; - break; - case 'v': - verbose++; - break; - case 'V': print_version(); exit(0); - default: - fprintf(stderr, "%s: Illegal option character '%c'\n", my_progname, - opterr); -#include "sslopt-case.h" - } + printf("%s: handle_options() failed with error %d\n", my_progname, + ho_error); + exit(1); } + if (!what_to_do) { int pnlen = strlen(my_progname); @@ -344,8 +313,6 @@ static int get_options(int *argc, char ***argv) if (set_default_charset_by_name(default_charset, MYF(MY_WME))) exit(1); } - (*argc) -= optind; - (*argv) += optind; if (*argc > 0 && opt_alldbs) { printf("You should give only options, no arguments at all, with option\n"); diff --git a/client/mysqldump.c b/client/mysqldump.c index 7eca92c04489bebb2a4f7961ac421bf272149660..f379e4e30a23e0511755af8d3ed77157223deb20 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -35,7 +35,7 @@ ** and adapted to mysqldump 05/11/01 by Jani Tolonen */ -#define DUMP_VERSION "8.24" +#define DUMP_VERSION "9.00" #include <my_global.h> #include <my_sys.h> @@ -46,7 +46,7 @@ #include "mysql.h" #include "mysql_version.h" #include "mysqld_error.h" -#include <getopt.h> +#include <my_getopt.h> /* Exit codes */ @@ -73,7 +73,8 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick=0, extended_insert = 0, ignore=0,opt_drop=0,opt_keywords=0,opt_lock=0,opt_compress=0, opt_delayed=0,create_options=0,opt_quoted=0,opt_databases=0, opt_alldbs=0,opt_create_db=0,opt_first_slave=0, - opt_autocommit=0,opt_master_data,opt_disable_keys=0,opt_xml=0; + opt_autocommit=0,opt_master_data,opt_disable_keys=0,opt_xml=0, + tty_password=0; static MYSQL mysql_connection,*sock=0; static char insert_pat[12 * 1024],*opt_password=0,*current_user=0, *current_host=0,*path=0,*fields_terminated=0, @@ -87,69 +88,154 @@ static DYNAMIC_STRING extended_row; #include "sslopt-vars.h" FILE *md_result_file; -static struct option long_options[] = +static struct my_option my_long_options[] = { - {"all-databases", no_argument, 0, 'A'}, - {"all", no_argument, 0, 'a'}, - {"add-drop-table", no_argument, 0, OPT_DROP}, - {"add-locks", no_argument, 0, OPT_LOCKS}, - {"allow-keywords", no_argument, 0, OPT_KEYWORDS}, - {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR}, - {"complete-insert", no_argument, 0, 'c'}, - {"compress", no_argument, 0, 'C'}, - {"databases", no_argument, 0, 'B'}, - {"debug", optional_argument, 0, '#'}, - {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET}, - {"delayed-insert", no_argument, 0, OPT_DELAYED}, - {"disable-keys", no_argument, 0, 'K'}, - {"extended-insert", no_argument, 0, 'e'}, - {"fields-terminated-by", required_argument, 0, (int) OPT_FTB}, - {"fields-enclosed-by", required_argument, 0, (int) OPT_ENC}, - {"fields-optionally-enclosed-by", required_argument, 0, (int) OPT_O_ENC}, - {"fields-escaped-by", required_argument, 0, (int) OPT_ESC}, - {"first-slave", no_argument, 0, 'x'}, - {"flush-logs", no_argument, 0, 'F'}, - {"force", no_argument, 0, 'f'}, - {"help", no_argument, 0, '?'}, - {"host", required_argument, 0, 'h'}, - {"lines-terminated-by", required_argument, 0, (int) OPT_LTB}, - {"lock-tables", no_argument, 0, 'l'}, - {"master-data", no_argument, 0, OPT_MASTER_DATA}, - {"no-autocommit", no_argument, 0, OPT_AUTOCOMMIT}, - {"no-create-db", no_argument, 0, 'n'}, - {"no-create-info", no_argument, 0, 't'}, - {"no-data", no_argument, 0, 'd'}, - {"opt", no_argument, 0, OPT_OPTIMIZE}, - {"password", optional_argument, 0, 'p'}, + {"all-databases", 'A', + "Dump all the databases. This will be same as --databases with all databases selected.", + (gptr*) &opt_alldbs, (gptr*) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, + {"all", 'a', "Include all MySQL specific create options.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"add-drop-table", OPT_DROP, "Add a 'drop table' before each create.", + (gptr*) &opt_drop, (gptr*) &opt_drop, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, + 0}, + {"add-locks", OPT_LOCKS, "Add locks around insert statements.", + (gptr*) &opt_lock, (gptr*) &opt_lock, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, + 0}, + {"allow-keywords", OPT_KEYWORDS, + "Allow creation of column names that are keywords.", (gptr*) &opt_keywords, + (gptr*) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"character-sets-dir", OPT_CHARSETS_DIR, + "Directory where character sets are", (gptr*) &charsets_dir, + (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"complete-insert", 'c', "Use complete insert statements.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"compress", 'C', "Use compression in server/client protocol.", + (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"databases", 'B', + "To dump several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames. 'USE db_name;' will be included in the output.", + (gptr*) &opt_databases, (gptr*) &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0, + 0, 0, 0, 0}, + {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"default-character-set", OPT_DEFAULT_CHARSET, + "Set the default character set.", (gptr*) &default_charset, + (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED.", + (gptr*) &opt_delayed, (gptr*) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, + {"disable-keys", 'K', + "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (gptr*) &opt_disable_keys, + (gptr*) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"extended-insert", 'e', + "Allows utilization of the new, much faster INSERT syntax.", + (gptr*) &extended_insert, (gptr*) &extended_insert, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, + {"fields-terminated-by", OPT_FTB, + "Fields in the textfile are terminated by ...", (gptr*) &fields_terminated, + (gptr*) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"fields-enclosed-by", OPT_ENC, + "Fields in the importfile are enclosed by ...", (gptr*) &enclosed, + (gptr*) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0}, + {"fields-optionally-enclosed-by", OPT_O_ENC, + "Fields in the i.file are opt. enclosed by ...", (gptr*) &opt_enclosed, + (gptr*) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0}, + {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...", + (gptr*) &escaped, (gptr*) &escaped, 0, GET_STR, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"first-slave", 'x', "Locks all tables across all databases.", + (gptr*) &opt_first_slave, (gptr*) &opt_first_slave, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, + {"flush-logs", 'F', "Flush logs file in server before starting dump.", + (gptr*) &flush_logs, (gptr*) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, + {"force", 'f', "Continue even if we get an sql-error.", + (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, + {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"host", 'h', "Connect to host.", (gptr*) ¤t_host, + (gptr*) ¤t_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...", + (gptr*) &lines_terminated, (gptr*) &lines_terminated, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"lock-tables", 'l', "Lock all tables for read.", (gptr*) &lock_tables, + (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"master-data", OPT_MASTER_DATA, + "This will cause the master position and filename to be appended to your output. This will automagically enable --first-slave.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"no-autocommit", OPT_AUTOCOMMIT, + "Wrap tables with autocommit/commit statements.", + (gptr*) &opt_autocommit, (gptr*) &opt_autocommit, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, + {"no-create-db", 'n', + "'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given.}", + (gptr*) &opt_create_db, (gptr*) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0, + 0, 0, 0, 0}, + {"no-create-info", 't', "Don't write table creation info.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"no-data", 'd', "No row information.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, + 0, 0, 0, 0}, + {"set-variable", 'O', + "Change the value of a variable. Please note that this option is depricated; you can set variables directly with --variable-name=value.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"opt", OPT_OPTIMIZE, + "Same as --add-drop-table --add-locks --all --quick --extended-insert --lock-tables --disable-keys", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"password", 'p', + "Password to use when connecting to server. If password is not given it's solicited on the tty.", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __WIN__ - {"pipe", no_argument, 0, 'W'}, + {"pipe", 'W', "Use named pipes to connect to server", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"port", required_argument, 0, 'P'}, - {"quick", no_argument, 0, 'q'}, - {"quote-names", no_argument, 0, 'Q'}, - {"result-file", required_argument, 0, 'r'}, - {"set-variable", required_argument, 0, 'O'}, - {"socket", required_argument, 0, 'S'}, + {"port", 'P', "Port number to use for connection.", 0, 0, 0, GET_LONG, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"quick", 'q', "Don't buffer query, dump directly to stdout.", + (gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"quote-names",'Q', "Quote table and column names with a `", + (gptr*) &opt_quoted, (gptr*) &opt_quoted, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, + {"result-file", 'r', + "Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\n\\r' (newline + carriage return).", + (gptr*) &md_result_file, (gptr*) &md_result_file, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, + {"socket", 'S', "Socket file to use for connection.", + (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #include "sslopt-longopts.h" - {"tab", required_argument, 0, 'T'}, - {"tables", no_argument, 0, OPT_TABLES}, + {"tab",'T', + "Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if mysqldump is run on the same machine as the mysqld daemon.", + (gptr*) &path, (gptr*) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"tables", OPT_TABLES, "Overrides option --databases (-B).", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifndef DONT_ALLOW_USER_CHANGE - {"user", required_argument, 0, 'u'}, + {"user", 'u', "User for login if not current user.", + (gptr*) ¤t_user, (gptr*) ¤t_user, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, #endif - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"where", required_argument, 0, 'w'}, - {"xml", no_argument, 0, 'X'}, - {0, 0, 0, 0} + {"verbose", 'v', "Print info about the various stages.", + (gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"version",'V', "Output version information and exit.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"where", 'w', "Dump only selected records; QUOTES mandatory!", + (gptr*) &where, (gptr*) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + { "max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "", + (gptr*) &max_allowed_packet, (gptr*) &max_allowed_packet, 0, + GET_LONG, REQUIRED_ARG, 24*1024*1024, 4096, 512*1024L*1024L, + MALLOC_OVERHEAD, 1024, 0}, + { "net_buffer_length", OPT_NET_BUFFER_LENGTH, "", + (gptr*) &net_buffer_length, (gptr*) &net_buffer_length, 0, + GET_LONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 512*1024L*1024L, + MALLOC_OVERHEAD, 1024, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; static const char *load_default_groups[]= { "mysqldump","client",0 }; CHANGEABLE_VAR md_changeable_vars[] = { - { "max_allowed_packet", (long*) &max_allowed_packet,24*1024*1024,4096, - 512*1024L*1024L,MALLOC_OVERHEAD,1024}, - { "net_buffer_length", (long*) &net_buffer_length,1024*1024L-1025,4096, - 16*1024L*1024L,MALLOC_OVERHEAD-1024,1024}, { 0, 0, 0, 0, 0, 0, 0} }; @@ -184,101 +270,9 @@ static void usage(void) printf("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n", my_progname); printf("OR %s [OPTIONS] --all-databases [OPTIONS]\n", my_progname); - printf("\n\ - -A, --all-databases Dump all the databases. This will be same as\n\ - --databases with all databases selected.\n\ - -a, --all Include all MySQL specific create options.\n\ - -#, --debug=... Output debug log. Often this is 'd:t:o,filename`.\n\ - --character-sets-dir=...\n\ - Directory where character sets are\n\ - -?, --help Display this help message and exit.\n\ - -B, --databases To dump several databases. Note the difference in\n\ - usage; In this case no tables are given. All name\n\ - arguments are regarded as databasenames.\n\ - 'USE db_name;' will be included in the output\n\ - -c, --complete-insert Use complete insert statements.\n\ - -C, --compress Use compression in server/client protocol.\n\ - --default-character-set=...\n\ - Set the default character set\n\ - -e, --extended-insert Allows utilization of the new, much faster\n\ - INSERT syntax.\n\ - --add-drop-table Add a 'drop table' before each create.\n\ - --add-locks Add locks around insert statements.\n\ - --allow-keywords Allow creation of column names that are keywords.\n\ - --delayed-insert Insert rows with INSERT DELAYED.\n\ - --master-data This will cause the master position and filename to \n\ - be appended to your output. This will automagically \n\ - enable --first-slave.\n\ - -F, --flush-logs Flush logs file in server before starting dump.\n\ - -f, --force Continue even if we get an sql-error.\n\ - -h, --host=... Connect to host.\n"); -puts("\ - -l, --lock-tables Lock all tables for read.\n\ - --no-autocommit Wrap tables with autocommit/commit statements.\n\ - -K, --disable-keys '/*!40000 ALTER TABLE tb_name DISABLE KEYS */;\n\ - and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */;\n\ - will be put in the output.\n\ - -n, --no-create-db 'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;'\n\ - will not be put in the output. The above line will\n\ - be added otherwise, if --databases or\n\ - --all-databases option was given.\n\ - -t, --no-create-info Don't write table creation info.\n\ - -d, --no-data No row information.\n\ - -O, --set-variable var=option\n\ - give a variable a value. --help lists variables\n\ - --opt Same as --add-drop-table --add-locks --all --quick\n\ - --extended-insert --lock-tables --disable-keys\n\ - -p, --password[=...] Password to use when connecting to server.\n\ - If password is not given it's solicited on the tty.\n"); -#ifdef __WIN__ - puts("-W, --pipe Use named pipes to connect to server"); -#endif - printf("\ - -P, --port=... Port number to use for connection.\n\ - -q, --quick Don't buffer query, dump directly to stdout.\n\ - -Q, --quote-names Quote table and column names with `\n\ - -r, --result-file=... Direct output to a given file. This option should be\n\ - used in MSDOS, because it prevents new line '\\n'\n\ - from being converted to '\\n\\r' (newline + carriage\n\ - return).\n\ - -S, --socket=... Socket file to use for connection.\n\ - --tables Overrides option --databases (-B).\n"); -#include "sslopt-usage.h" - printf("\ - -T, --tab=... Creates tab separated textfile for each table to\n\ - given path. (creates .sql and .txt files).\n\ - NOTE: This only works if mysqldump is run on\n\ - the same machine as the mysqld daemon.\n"); -#ifndef DONT_ALLOW_USER_CHANGE - printf("\ - -u, --user=# User for login if not current user.\n"); -#endif - printf("\ - -v, --verbose Print info about the various stages.\n\ - -V, --version Output version information and exit.\n\ - -w, --where= dump only selected records; QUOTES mandatory!\n\ - -X, --xml dump a database as well formed XML\n\ - -x, --first-slave Locks all tables across all databases.\n\ - EXAMPLES: \"--where=user=\'jimf\'\" \"-wuserid>1\" \"-wuserid<1\"\n\ - Use -T (--tab=...) with --fields-...\n\ - --fields-terminated-by=...\n\ - Fields in the textfile are terminated by ...\n\ - --fields-enclosed-by=...\n\ - Fields in the importfile are enclosed by ...\n\ - --fields-optionally-enclosed-by=...\n\ - Fields in the i.file are opt. enclosed by ...\n\ - --fields-escaped-by=...\n\ - Fields in the i.file are escaped by ...\n\ - --lines-terminated-by=...\n\ - Lines in the i.file are terminated by ...\n\ -"); print_defaults("my",load_default_groups); - - printf("\nPossible variables for option --set-variable (-O) are:\n"); - for (i=0 ; md_changeable_vars[i].name ; i++) - printf("%-20s current value: %lu\n", - md_changeable_vars[i].name, - (ulong) *md_changeable_vars[i].varptr); + my_print_help(my_long_options); + my_print_variables(my_long_options); } /* usage */ @@ -300,179 +294,137 @@ static void write_header(FILE *sql_file, char *db_name) } /* write_header */ -static int get_options(int *argc,char ***argv) +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument) { - int c,option_index; - my_bool tty_password=0; - - md_result_file=stdout; - load_defaults("my",load_default_groups,argc,argv); - set_all_changeable_vars(md_changeable_vars); - while ((c=getopt_long(*argc,*argv, - "#::p::h:u:O:P:r:S:T:EBaAcCdefFKlnqQtvVw:?IxX", - long_options, &option_index)) != EOF) - { - switch(c) { - case OPT_MASTER_DATA: - opt_master_data=1; - opt_first_slave=1; - break; - case OPT_AUTOCOMMIT: - opt_autocommit=1; - break; - case 'a': - create_options=1; - break; - case 'e': - extended_insert=1; - break; - case 'A': - opt_alldbs=1; - break; - case OPT_DEFAULT_CHARSET: - default_charset= optarg; - break; - case OPT_CHARSETS_DIR: - charsets_dir= optarg; - break; - case 'f': - ignore_errors=1; - break; - case 'F': - flush_logs=1; - break; - case 'h': - my_free(current_host,MYF(MY_ALLOW_ZERO_PTR)); - current_host=my_strdup(optarg,MYF(MY_WME)); - break; - case 'K': - opt_disable_keys=1; - break; - case 'n': - opt_create_db = 1; - break; + switch(optid) { + case OPT_MASTER_DATA: + opt_master_data=1; + opt_first_slave=1; + break; + case 'a': + create_options=1; + break; + case OPT_DEFAULT_CHARSET: + default_charset= argument; + break; + case OPT_CHARSETS_DIR: + charsets_dir= argument; + break; + case 'h': + my_free(current_host,MYF(MY_ALLOW_ZERO_PTR)); + current_host=my_strdup(argument,MYF(MY_WME)); + break; #ifndef DONT_ALLOW_USER_CHANGE - case 'u': - current_user=optarg; - break; + case 'u': + current_user=argument; + break; #endif - case 'O': - if (set_changeable_var(optarg, md_changeable_vars)) - { - usage(); - return(1); - } - break; - case 'p': - if (optarg) - { - char *start=optarg; - my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); - opt_password=my_strdup(optarg,MYF(MY_FAE)); - while (*optarg) *optarg++= 'x'; /* Destroy argument */ - if (*start) - start[1]=0; /* Cut length of argument */ - } - else - tty_password=1; - break; - case 'P': - opt_mysql_port= (unsigned int) atoi(optarg); - break; - case 'r': - if (!(md_result_file = my_fopen(optarg, O_WRONLY | O_BINARY, - MYF(MY_WME)))) - exit(1); - break; - case 'S': - opt_mysql_unix_port= optarg; - break; - case 'W': + case 'p': + if (argument) + { + char *start=argument; + my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); + opt_password=my_strdup(argument,MYF(MY_FAE)); + while (*argument) *argument++= 'x'; /* Destroy argument */ + if (*start) + start[1]=0; /* Cut length of argument */ + } + else + tty_password=1; + break; + case 'P': + opt_mysql_port= (unsigned int) atoi(argument); + break; + case 'r': + if (!(md_result_file = my_fopen(argument, O_WRONLY | O_BINARY, + MYF(MY_WME)))) + exit(1); + break; + case 'S': + opt_mysql_unix_port= argument; + break; + case 'W': #ifdef __WIN__ - opt_mysql_unix_port=MYSQL_NAMEDPIPE; + opt_mysql_unix_port=MYSQL_NAMEDPIPE; #endif - break; - case 'T': - path= optarg; - opt_disable_keys=0; - break; - case 'B': - opt_databases = 1; - break; - case '#': - DBUG_PUSH(optarg ? optarg : "d:t:o"); - break; - case 'c': cFlag=1; break; - case 'C': - opt_compress=1; - break; - case 'd': dFlag=1; break; - case 'l': lock_tables=1; break; - case 'q': quick=1; break; - case 'Q': opt_quoted=1; break; - case 't': tFlag=1; break; - case 'v': verbose=1; break; - case 'V': print_version(); exit(0); - case 'w': - where=optarg; - break; - case 'X': - opt_xml = 1; - opt_disable_keys=0; - break; - case 'x': - opt_first_slave=1; - break; - default: - fprintf(stderr,"%s: Illegal option character '%c'\n",my_progname,opterr); - /* Fall throught */ - case 'I': - case '?': - usage(); - exit(0); - case (int) OPT_FTB: - fields_terminated= optarg; - break; - case (int) OPT_LTB: - lines_terminated= optarg; - break; - case (int) OPT_ENC: - enclosed= optarg; - break; - case (int) OPT_O_ENC: - opt_enclosed= optarg; - break; - case (int) OPT_ESC: - escaped= optarg; - break; - case (int) OPT_DROP: - opt_drop=1; - break; - case (int) OPT_KEYWORDS: - opt_keywords=1; - break; - case (int) OPT_LOCKS: - opt_lock=1; - break; - case (int) OPT_OPTIMIZE: - extended_insert=opt_drop=opt_lock=lock_tables=quick=create_options= - opt_disable_keys=1; - break; - case (int) OPT_DELAYED: - opt_delayed=1; - break; - case (int) OPT_TABLES: - opt_databases=0; - break; + break; + case 'T': + path= argument; + opt_disable_keys=0; + break; + case '#': + DBUG_PUSH(argument ? argument : "d:t:o"); + break; + case 'c': cFlag=1; break; + case 'd': dFlag=1; break; + case 't': tFlag=1; break; + case 'V': print_version(); exit(0); + case 'w': + where=argument; + break; + case 'X': + opt_xml = 1; + opt_disable_keys=0; + break; + default: + fprintf(stderr,"%s: Illegal option character '%c'\n",my_progname,opterr); + /* Fall throught */ + case 'I': + case '?': + usage(); + exit(0); + case (int) OPT_FTB: + fields_terminated= argument; + break; + case (int) OPT_LTB: + lines_terminated= argument; + break; + case (int) OPT_ENC: + enclosed= argument; + break; + case (int) OPT_O_ENC: + opt_enclosed= argument; + break; + case (int) OPT_ESC: + escaped= argument; + break; + case (int) OPT_OPTIMIZE: + extended_insert=opt_drop=opt_lock=lock_tables=quick=create_options= + opt_disable_keys=1; + break; + case (int) OPT_TABLES: + opt_databases=0; + break; #include "sslopt-case.h" - } } + return 0; +} + + +static int get_options(int *argc, char ***argv) +{ + int ho_error; + + md_result_file= stdout; + load_defaults("my",load_default_groups,argc,argv); + set_all_changeable_vars(md_changeable_vars); + + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + { + printf("%s: handle_options() failed with error %d\n", my_progname, + ho_error); + exit(1); + } + if (opt_delayed) opt_lock=0; /* Can't have lock with delayed */ if (!path && (enclosed || opt_enclosed || escaped || lines_terminated || fields_terminated)) { - fprintf(stderr, "%s: You must use option --tab with --fields-...\n", my_progname); + fprintf(stderr, + "%s: You must use option --tab with --fields-...\n", my_progname); return(1); } @@ -498,8 +450,6 @@ static int get_options(int *argc,char ***argv) if (set_default_charset_by_name(default_charset, MYF(MY_WME))) exit(1); } - (*argc)-=optind; - (*argv)+=optind; if ((*argc < 1 && !opt_alldbs) || (*argc > 0 && opt_alldbs)) { usage(); @@ -651,7 +601,7 @@ static uint getTableStructure(char *table, char* db) /* Make an sql-file, if path was given iow. option -T was given */ char buff[20+FN_REFLEN]; - sprintf(buff,"show create table `%s`",table); + sprintf(buff,"show create table %s",table_name); if (mysql_query(sock, buff)) { fprintf(stderr, "%s: Can't get CREATE TABLE for table '%s' (%s)\n", @@ -784,7 +734,7 @@ static uint getTableStructure(char *table, char* db) { if (opt_keywords) fprintf(sql_file, " %s.%s %s", table_name, - quote_name(row[SHOW_FIELDNAME],name_buff), row[SHOW_TYPE]); + quote_name(row[SHOW_FIELDNAME],name_buff), row[SHOW_TYPE]); else fprintf(sql_file, " %s %s", quote_name(row[SHOW_FIELDNAME], name_buff), row[SHOW_TYPE]); @@ -897,6 +847,8 @@ static uint getTableStructure(char *table, char* db) fputs(";\n", sql_file); } } + if (opt_disable_keys) + fprintf(sql_file,"\n/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",table_name); if (cFlag) { strpos=strmov(strpos,") VALUES "); @@ -1021,7 +973,7 @@ static void dumpTable(uint numFields, char *table) strxmov(strend(query), " WHERE ",where,NullS); } if (!opt_xml) - fputs("\n", md_result_file); + fputs("\n\n", md_result_file); if (mysql_query(sock, query)) { DBerror(sock, "when retrieving data from server"); @@ -1046,9 +998,6 @@ static void dumpTable(uint numFields, char *table) return; } - if (opt_disable_keys) - fprintf(md_result_file,"/*!40000 ALTER TABLE %s DISABLE KEYS */;\n", - quote_name(table, table_buff)); if (opt_lock) fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", quote_name(table,table_buff)); @@ -1072,9 +1021,6 @@ static void dumpTable(uint numFields, char *table) fputs(insert_pat,md_result_file); mysql_field_seek(res,0); - if (opt_xml) - fprintf(md_result_file, "\t<row>\n"); - for (i = 0; i < mysql_num_fields(res); i++) { if (!(field = mysql_fetch_field(res))) @@ -1164,9 +1110,6 @@ static void dumpTable(uint numFields, char *table) } } - if (opt_xml) - fprintf(md_result_file, "\t</row>\n"); - if (extended_insert) { ulong row_length; @@ -1214,11 +1157,11 @@ static void dumpTable(uint numFields, char *table) safe_exit(EX_CONSCHECK); return; } + if (opt_disable_keys) + fprintf(md_result_file,"\n/*!40000 ALTER TABLE %s ENABLE KEYS */;\n", + quote_name(table,table_buff)); if (opt_lock) fputs("UNLOCK TABLES;\n", md_result_file); - if (opt_disable_keys) - fprintf(md_result_file,"/*!40000 ALTER TABLE %s ENABLE KEYS */;\n", - quote_name(table,table_buff)); if (opt_autocommit) fprintf(md_result_file, "commit;\n"); mysql_free_result(res); @@ -1244,7 +1187,7 @@ static void print_quoted_xml(FILE *output, char *fname, char *str, uint len) else fputc(*str, output); } - fprintf(output, "</%s>\n", fname); + fprintf(output, "<%s>\n", fname); } static char *getTableName(int reset) diff --git a/client/mysqlimport.c b/client/mysqlimport.c index ed71642507a2140f02ee5840ef60c3333a2be888..9eb93dc4808caa4a751ec35f7416de4a4f67069f 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -25,10 +25,11 @@ ** * * ** ************************* */ -#define IMPORT_VERSION "2.9" +#define IMPORT_VERSION "3.0" #include "client_priv.h" #include "mysql_version.h" +#include <my_getopt.h> static void db_error_with_table(MYSQL *mysql, char *table); static void db_error(MYSQL *mysql); @@ -37,55 +38,93 @@ static char *add_load_option(char *ptr,const char *object, const char *statement); static my_bool verbose=0,lock_tables=0,ignore_errors=0,opt_delete=0, - replace=0,silent=0,ignore=0,opt_compress=0,opt_local_file=0; - + replace=0,silent=0,ignore=0,opt_compress=0,opt_local_file=0, + opt_low_priority= 0, tty_password= 0; static MYSQL mysql_connection; static char *opt_password=0, *current_user=0, *current_host=0, *current_db=0, *fields_terminated=0, *lines_terminated=0, *enclosed=0, *opt_enclosed=0, - *escaped=0, opt_low_priority=0, *opt_columns=0, - *default_charset; + *escaped=0, *opt_columns=0, *default_charset; static uint opt_mysql_port=0; static my_string opt_mysql_unix_port=0; -static my_string opt_ignore_lines=0; #include "sslopt-vars.h" -static struct option long_options[] = +static struct my_option my_long_options[] = { - {"character-sets-dir", required_argument, 0, OPT_CHARSETS_DIR}, - {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET}, - {"columns", required_argument, 0, 'c'}, - {"compress", no_argument, 0, 'C'}, - {"debug", optional_argument, 0, '#'}, - {"delete", no_argument, 0, 'd'}, - {"fields-terminated-by", required_argument, 0, (int) OPT_FTB}, - {"fields-enclosed-by", required_argument, 0, (int) OPT_ENC}, - {"fields-optionally-enclosed-by", required_argument, 0, (int) OPT_O_ENC}, - {"fields-escaped-by", required_argument, 0, (int) OPT_ESC}, - {"force", no_argument, 0, 'f'}, - {"help", no_argument, 0, '?'}, - {"host", required_argument, 0, 'h'}, - {"ignore", no_argument, 0, 'i'}, - {"ignore-lines", required_argument, 0, OPT_IGN_LINES}, - {"lines-terminated-by", required_argument, 0, (int) OPT_LTB}, - {"local", no_argument, 0, 'L'}, - {"lock-tables", no_argument, 0, 'l'}, - {"low-priority", no_argument, 0, (int) OPT_LOW_PRIORITY}, - {"password", optional_argument, 0, 'p'}, + {"character-sets-dir", OPT_CHARSETS_DIR, + "Directory where character sets are", (gptr*) &charsets_dir, + (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"default-character-set", OPT_DEFAULT_CHARSET, + "Set the default character set.", (gptr*) &default_charset, + (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"columns", 'c', + "Use only these columns to import the data to. Give the column names in a comma separated list. This is same as giving columns to LOAD DATA INFILE.", + (gptr*) &opt_columns, (gptr*) &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, + 0, 0, 0}, + {"compress", 'C', "Use compression in server/client protocol.", + (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"debug",'#', "Output debug log. Often this is 'd:t:o,filename'", 0, 0, 0, + GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"delete", 'd', "First delete all rows from table.", (gptr*) &opt_delete, + (gptr*) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"fields-terminated-by", OPT_FTB, + "Fields in the textfile are terminated by ...", (gptr*) &fields_terminated, + (gptr*) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"fields-enclosed-by", OPT_ENC, + "Fields in the importfile are enclosed by ...", (gptr*) &enclosed, + (gptr*) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"fields-optionally-enclosed-by", OPT_O_ENC, + "Fields in the i.file are opt. enclosed by ...", (gptr*) &opt_enclosed, + (gptr*) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...", + (gptr*) &escaped, (gptr*) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, + 0, 0}, + {"force", 'f', "Continue even if we get an sql-error.", + (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0, + 0, 0, 0, 0}, + {"help", '?', "Displays this help and exits.", 0, 0, 0, GET_NO_ARG, NO_ARG, + 0, 0, 0, 0, 0, 0}, + {"host", 'h', "Connect to host.", (gptr*) ¤t_host, + (gptr*) ¤t_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"ignore", 'i', "If duplicate unique key was found, keep old row.", + (gptr*) &ignore, (gptr*) &ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...", + (gptr*) &lines_terminated, (gptr*) &lines_terminated, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"local", 'L', "Read all files through the client", (gptr*) &opt_local_file, + (gptr*) &opt_local_file, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"lock-tables", 'l', "Lock all tables for write.", (gptr*) &lock_tables, + (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"low-priority", OPT_LOW_PRIORITY, + "Use LOW_PRIORITY when updating the table", (gptr*) &opt_low_priority, + (gptr*) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"password", 'p', + "Password to use when connecting to server. If password is not given it's asked from the tty.", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __WIN__ - {"pipe", no_argument, 0, 'W'}, + {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"port", required_argument, 0, 'P'}, - {"replace", no_argument, 0, 'r'}, - {"silent", no_argument, 0, 's'}, - {"socket", required_argument, 0, 'S'}, + {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port, + (gptr*) &opt_mysql_port, 0, GET_LONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"replace", 'r', "If duplicate unique key was found, replace old row.", + (gptr*) &replace, (gptr*) &replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"silent", 's', "Be more silent.", (gptr*) &silent, (gptr*) &silent, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"socket", 'S', "Socket file to use for connection.", + (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #include "sslopt-longopts.h" #ifndef DONT_ALLOW_USER_CHANGE - {"user", required_argument, 0, 'u'}, + {"user", 'u', "User for login if not current user.", (gptr*) ¤t_user, + (gptr*) ¤t_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {0, 0, 0, 0} + {"verbose", 'v', "Print info about the various stages.", (gptr*) &verbose, + (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -112,158 +151,97 @@ read the text file directly. In other cases the client will open the text\n\ file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n"); printf("\nUsage: %s [OPTIONS] database textfile...",my_progname); - printf("\n\ - -#, --debug[=...] Output debug log. Often this is 'd:t:o,filename`\n\ - -?, --help Displays this help and exits.\n\ - --default-character-set=...\n\ - Set the default character set.\n\ - --character-sets-dir=...\n\ - Directory where character sets are\n\ - -c, --columns=... Use only these columns to import the data to.\n\ - Give the column names in a comma separated list.\n\ - This is same as giving columns to LOAD DATA INFILE.\n\ - -C, --compress Use compression in server/client protocol\n\ - -d, --delete First delete all rows from table.\n\ - -f, --force Continue even if we get an sql-error.\n\ - -h, --host=... Connect to host.\n\ - -i, --ignore If duplicate unique key was found, keep old row.\n\ - --ignore-lines=n Ignore first n lines of data file.\n\ - -l, --lock-tables Lock all tables for write.\n\ - -L, --local Read all files through the client\n\ - --low-priority Use LOW_PRIORITY when updating the table\n\ - -p, --password[=...] Password to use when connecting to server.\n\ - If password is not given it's asked from the tty.\n"); -#ifdef __WIN__ - puts("-W, --pipe Use named pipes to connect to server"); -#endif - printf("\ - -P, --port=... Port number to use for connection.\n\ - -r, --replace If duplicate unique key was found, replace old row.\n\ - -s, --silent Be more silent.\n\ - -S, --socket=... Socket file to use for connection.\n"); -#include "sslopt-usage.h" -#ifndef DONT_ALLOW_USER_CHANGE - printf("\ - -u, --user=# User for login if not current user.\n"); -#endif - printf("\ - -v, --verbose Print info about the various stages.\n\ - -V, --version Output version information and exit.\n\ - --fields-terminated-by=...\n\ - Fields in the textfile are terminated by ...\n\ - --fields-enclosed-by=...\n\ - Fields in the importfile are enclosed by ...\n\ - --fields-optionally-enclosed-by=...\n\ - Fields in the i.file are opt. enclosed by ...\n\ - --fields-escaped-by=...\n\ - Fields in the i.file are escaped by ...\n\ - --lines-terminated-by=...\n\ - Lines in the i.file are terminated by ...\n\ -"); print_defaults("my",load_default_groups); + my_print_help(my_long_options); + my_print_variables(my_long_options); } -static int get_options(int *argc, char ***argv) -{ - int c, option_index; - my_bool tty_password=0; - while ((c=getopt_long(*argc,*argv, - (char*) "#::p::c:h:u:P:S:CdfilLrsvV?IW", - long_options, &option_index)) != EOF) - { - switch(c) { - case 'c': - opt_columns= optarg; - break; - case 'C': - opt_compress=1; - break; - case OPT_DEFAULT_CHARSET: - default_charset= optarg; - break; - case OPT_CHARSETS_DIR: - charsets_dir= optarg; - break; - case 'd': - opt_delete= 1; - break; - case 'f': - ignore_errors= 1; - break; - case 'h': - current_host= optarg; - break; - case 'i': - ignore= 1; - break; +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument) +{ + switch(optid) { + case 'c': + opt_columns= argument; + break; + case OPT_DEFAULT_CHARSET: + default_charset= argument; + break; + case OPT_CHARSETS_DIR: + charsets_dir= argument; + break; + case 'h': + current_host= argument; + break; #ifndef DONT_ALLOW_USER_CHANGE - case 'u': - current_user= optarg; - break; + case 'u': + current_user= argument; + break; #endif - case 'p': - if (optarg) - { - char *start=optarg; - my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); - opt_password=my_strdup(optarg,MYF(MY_FAE)); - while (*optarg) *optarg++= 'x'; /* Destroy argument */ - if (*start) - start[1]=0; /* Cut length of argument */ - } - else - tty_password= 1; - break; - case 'P': - opt_mysql_port= (unsigned int) atoi(optarg); - break; - case 'r': - replace= 1; - break; - case 's': - silent= 1; - break; - case 'S': - opt_mysql_unix_port= optarg; - break; + case 'p': + if (argument) + { + char *start=argument; + my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); + opt_password=my_strdup(argument,MYF(MY_FAE)); + while (*argument) *argument++= 'x'; /* Destroy argument */ + if (*start) + start[1]=0; /* Cut length of argument */ + } + else + tty_password= 1; + break; + case 'P': + opt_mysql_port= (unsigned int) atoi(argument); + break; + case 'S': + opt_mysql_unix_port= argument; + break; #ifdef __WIN__ - case 'W': - opt_mysql_unix_port=MYSQL_NAMEDPIPE; - opt_local_file=1; - break; + case 'W': + opt_mysql_unix_port=MYSQL_NAMEDPIPE; + opt_local_file=1; + break; #endif - case '#': - DBUG_PUSH(optarg ? optarg : "d:t:o"); - break; - case 'l': lock_tables= 1; break; - case 'L': opt_local_file=1; break; - case 'v': verbose= 1; break; - case 'V': print_version(); exit(0); - case 'I': - case '?': - usage(); - exit(0); - case (int) OPT_FTB: - fields_terminated= optarg; - break; - case (int) OPT_LTB: - lines_terminated= optarg; - break; - case (int) OPT_ENC: - enclosed= optarg; - break; - case (int) OPT_O_ENC: - opt_enclosed= optarg; - break; - case (int) OPT_ESC: - escaped= optarg; - break; - case (int) OPT_IGN_LINES: - opt_ignore_lines= optarg; - break; + case '#': + DBUG_PUSH(argument ? argument : "d:t:o"); + break; + case 'V': print_version(); exit(0); + case 'I': + case '?': + usage(); + exit(0); + case (int) OPT_FTB: + fields_terminated= argument; + break; + case (int) OPT_LTB: + lines_terminated= argument; + break; + case (int) OPT_ENC: + enclosed= argument; + break; + case (int) OPT_O_ENC: + opt_enclosed= argument; + break; + case (int) OPT_ESC: + escaped= argument; + break; #include "sslopt-case.h" - } + } + return 0; +} + + +static int get_options(int *argc, char ***argv) +{ + int ho_error; + + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + { + printf("%s: handle_options() failed with error %d\n", my_progname, + ho_error); + exit(1); } if (enclosed && opt_enclosed) { @@ -280,8 +258,6 @@ static int get_options(int *argc, char ***argv) if (set_default_charset_by_name(default_charset, MYF(MY_WME))) exit(1); } - (*argc)-=optind; - (*argv)+=optind; if (*argc < 2) { usage(); @@ -351,8 +327,6 @@ static int write_to_table(char *filename, MYSQL *sock) " OPTIONALLY ENCLOSED BY"); end= add_load_option(end, escaped, " ESCAPED BY"); end= add_load_option(end, lines_terminated, " LINES TERMINATED BY"); - if (opt_ignore_lines) - end= strmov(strmov(strmov(end, " IGNORE "), opt_ignore_lines), " LINES"); if (opt_columns) end= strmov(strmov(strmov(end, " ("), opt_columns), ")"); *end= '\0'; @@ -405,9 +379,6 @@ static MYSQL *db_connect(char *host, char *database, char *user, char *passwd) mysql_init(&mysql_connection); if (opt_compress) mysql_options(&mysql_connection,MYSQL_OPT_COMPRESS,NullS); - if (opt_local_file) - mysql_options(&mysql_connection,MYSQL_OPT_LOCAL_INFILE, - (char*) &opt_local_file); #ifdef HAVE_OPENSSL if (opt_use_ssl) mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, diff --git a/client/mysqlshow.c b/client/mysqlshow.c index e5b7f239f97054a14698c2c406430514b21c9887..2326d72ea34ed0b4cfa1922dfdabb33c544814b4 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -16,9 +16,10 @@ /* Show databases, tables or columns */ -#define SHOW_VERSION "8.3" +#define SHOW_VERSION "9.0" #include <my_global.h> +#include "client_priv.h" #include <my_sys.h> #include <m_string.h> #include "mysql.h" @@ -26,10 +27,11 @@ #include "mysqld_error.h" #include <signal.h> #include <stdarg.h> -#include <getopt.h> +#include <my_getopt.h> +#include "sslopt-vars.h" static my_string host=0,opt_password=0,user=0; -static my_bool opt_show_keys=0,opt_compress=0,opt_status=0; +static my_bool opt_show_keys=0,opt_compress=0,opt_status=0, tty_password=0; static uint opt_verbose=0; static void get_options(int *argc,char ***argv); @@ -48,7 +50,6 @@ static void print_res_row(MYSQL_RES *result,MYSQL_ROW cur); static const char *load_default_groups[]= { "mysqlshow","client",0 }; static my_string opt_mysql_unix_port=0; -#include "sslopt-vars.h" int main(int argc, char **argv) { @@ -121,32 +122,51 @@ int main(int argc, char **argv) return 0; /* No compiler warnings */ } - -static struct option long_options[] = +static struct my_option my_long_options[] = { - {"character-sets-dir", required_argument, 0, 'c'}, - {"compress", no_argument, 0, 'C'}, - {"debug", optional_argument, 0, '#'}, - {"help", no_argument, 0, '?'}, - {"host", required_argument, 0, 'h'}, - {"status", no_argument, 0, 'i'}, - {"keys", no_argument, 0, 'k'}, - {"password", optional_argument, 0, 'p'}, - {"port", required_argument, 0, 'P'}, + {"character-sets-dir", 'c', "Directory where character sets are", + (gptr*) &charsets_dir, (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, + 0, 0, 0, 0, 0}, + {"compress", 'C', "Use compression in server/client protocol", + (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, + 0, 0, 0, 0, 0, 0}, + {"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"status", 'i', "Shows a lot of extra information about each table.", + (gptr*) &opt_status, (gptr*) &opt_status, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, + {"keys", 'k', "Show keys for table", (gptr*) &opt_show_keys, + (gptr*) &opt_show_keys, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"password", 'p', + "Password to use when connecting to server. If password is not given it's asked from the tty.", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"port", 'P', "Port number to use for connection.", 0, 0, 0, GET_LONG, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __WIN__ - {"pipe", no_argument, 0, 'W'}, + {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"socket", required_argument, 0, 'S'}, + {"socket", 'S', "Socket file to use for connection.", + (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #include "sslopt-longopts.h" #ifndef DONT_ALLOW_USER_CHANGE - {"user", required_argument, 0, 'u'}, + {"user", 'u', "User for login if not current user.", (gptr*) &user, + (gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {0, 0, 0, 0} + {"verbose", 'v', + "More verbose output; You can use this multiple times to get even more verbose output.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; - - + + static void print_version(void) { printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,SHOW_VERSION, @@ -160,33 +180,6 @@ static void usage(void) puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); puts("Shows the structure of a mysql database (databases,tables and columns)\n"); printf("Usage: %s [OPTIONS] [database [table [column]]]\n",my_progname); - printf("\n\ - -#, --debug=... output debug log. Often this is 'd:t:o,filename`\n\ - -?, --help display this help and exit\n\ - -c, --character-sets-dir=...\n\ - Directory where character sets are\n\ - -C, --compress Use compression in server/client protocol\n\ - -h, --host=... connect to host\n\ - -i, --status Shows a lot of extra information about each table\n\ - -k, --keys show keys for table\n\ - -p, --password[=...] password to use when connecting to server\n\ - If password is not given it's asked from the tty.\n"); -#ifdef __WIN__ - puts("-W, --pipe Use named pipes to connect to server"); -#endif - printf("\ - -P --port=... Port number to use for connection\n\ - -S --socket=... Socket file to use for connection\n"); -#include "sslopt-usage.h" -#ifndef DONT_ALLOW_USER_CHANGE - printf("\ - -u, --user=# user for login if not current user\n"); -#endif - printf("\ - -v, --verbose more verbose output; You can use this multiple times\n\ - to get even more verbose output.\n\ - -V, --version output version information and exit\n"); - puts("\n\ If last argument contains a shell or SQL wildcard (*,?,% or _) then only\n\ what\'s matched by the wildcard is shown.\n\ @@ -195,85 +188,82 @@ If no table is given then all matching tables in database are shown\n\ If no column is given then all matching columns and columntypes in table\n\ are shown"); print_defaults("my",load_default_groups); + my_print_help(my_long_options); + my_print_variables(my_long_options); } - -static void -get_options(int *argc,char ***argv) +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument) { - int c,option_index; - my_bool tty_password=0; - - while ((c=getopt_long(*argc,*argv,"c:h:p::u:#::P:S:Ck?vVWi",long_options, - &option_index)) != EOF) - { - switch(c) { - case 'C': - opt_compress=1; - break; - case 'c': - charsets_dir= optarg; - break; - case 'v': - opt_verbose++; - break; - case 'h': - host = optarg; - break; - case 'i': - opt_status=1; - break; - case 'k': - opt_show_keys=1; - break; - case 'p': - if (optarg) - { - char *start=optarg; - my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); - opt_password=my_strdup(optarg,MYF(MY_FAE)); - while (*optarg) *optarg++= 'x'; /* Destroy argument */ - if (*start) - start[1]=0; /* Cut length of argument */ - } - else - tty_password=1; - break; + switch(optid) { + case 'c': + charsets_dir= argument; + break; + case 'v': + opt_verbose++; + break; + case 'h': + host = argument; + break; + case 'p': + if (argument) + { + char *start=argument; + my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); + opt_password=my_strdup(argument,MYF(MY_FAE)); + while (*argument) *argument++= 'x'; /* Destroy argument */ + if (*start) + start[1]=0; /* Cut length of argument */ + } + else + tty_password=1; + break; #ifndef DONT_ALLOW_USER_CHANGE - case 'u': - user=optarg; - break; + case 'u': + user=argument; + break; #endif - case 'P': - opt_mysql_port= (unsigned int) atoi(optarg); - break; - case 'S': - opt_mysql_unix_port= optarg; - break; - case 'W': + case 'P': + opt_mysql_port= (unsigned int) atoi(argument); + break; + case 'S': + opt_mysql_unix_port= argument; + break; + case 'W': #ifdef __WIN__ - opt_mysql_unix_port=MYSQL_NAMEDPIPE; + opt_mysql_unix_port=MYSQL_NAMEDPIPE; #endif - break; + break; #include "sslopt-case.h" - case '#': - DBUG_PUSH(optarg ? optarg : "d:t:o"); - break; - case 'V': - print_version(); - exit(0); - break; - default: - fprintf(stderr,"Illegal option character '%c'\n",opterr); - /* Fall throught */ - case '?': - case 'I': /* Info */ - usage(); - exit(0); - } + case '#': + DBUG_PUSH(argument ? argument : "d:t:o"); + break; + case 'V': + print_version(); + exit(0); + break; + case '?': + case 'I': /* Info */ + usage(); + exit(0); + } + return 0; +} + + +static void +get_options(int *argc,char ***argv) +{ + int ho_error; + + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + { + printf("%s: handle_options() failed with error %d\n", my_progname, + ho_error); + exit(1); } - (*argc)-=optind; - (*argv)+=optind; + if (tty_password) opt_password=get_tty_password(NullS); return; diff --git a/include/my_getopt.h b/include/my_getopt.h index 2e40fb8ffaafc862dfb2908f0473934406d45655..b3b3ee2f785550e2410514b660e7115b79d10cf2 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -14,28 +14,21 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -struct my_optarg -{ - char *arg; /* option argument */ - int pos; /* next element in ARGV */ - int verbose; /* 0 = inhibit warnings of unrecognized options */ - int unrecognized; /* position of the unrecognized option */ -}; +C_MODE_START - -enum get_opt_var_type { GET_NO_ARG, GET_LONG, GET_LL, GET_STR }; +enum get_opt_var_type { GET_NO_ARG, GET_BOOL, GET_LONG, GET_LL, GET_STR }; enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG }; struct my_option { const char *name; /* Name of the option */ + int id; /* unique id or short option */ const char *comment; /* option comment, for autom. --help */ gptr *value; /* The variable value */ gptr *u_max_value; /* The user def. max variable value */ const char **str_values; /* Pointer to possible values */ enum get_opt_var_type var_type; enum get_opt_arg_type arg_type; - int id; /* unique id or short option */ longlong def_value; /* Default value */ longlong min_value; /* Min allowed value */ longlong max_value; /* Max allowed value */ @@ -44,6 +37,8 @@ struct my_option int app_type; /* To be used by an application */ }; +extern char *disabled_my_option; + extern int handle_options (int *argc, char ***argv, const struct my_option *longopts, my_bool (*get_one_option)(int, @@ -51,3 +46,5 @@ extern int handle_options (int *argc, char ***argv, char *)); extern void my_print_help(const struct my_option *options); extern void my_print_variables(const struct my_option *options); + +C_MODE_END diff --git a/include/sslopt-case.h b/include/sslopt-case.h index ae6026f9136e2db73afa0a295af6103214fc6e8c..e6e3a416bb0517721a4af8af71bbd1a1339f92a6 100644 --- a/include/sslopt-case.h +++ b/include/sslopt-case.h @@ -20,8 +20,8 @@ break; case OPT_SSL_KEY: opt_use_ssl = 1; /* true */ - my_free(opt_ssl_key, MYF(MY_ALLOW_ZERO_PTR)); - opt_ssl_key = my_strdup(optarg, MYF(0)); +//QQ to be removed??? my_free(opt_ssl_key, MYF(MY_ALLOW_ZERO_PTR)); +//QQ to be removed??? opt_ssl_key = my_strdup(optarg, MYF(0)); break; case OPT_SSL_CERT: opt_use_ssl = 1; /* true */ diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h index 2a0f27f3235980aa5feb6be942e84761db31da63..d82c833c439899cfc2bef43c08c5eaed6eda72a5 100644 --- a/include/sslopt-longopts.h +++ b/include/sslopt-longopts.h @@ -16,17 +16,26 @@ #ifdef HAVE_OPENSSL -#define OPT_SSL_SSL 200 -#define OPT_SSL_KEY 201 -#define OPT_SSL_CERT 202 -#define OPT_SSL_CA 203 -#define OPT_SSL_CAPATH 204 -#define OPT_SSL_CIPHER 205 - {"ssl", no_argument, 0, OPT_SSL_SSL}, - {"ssl-key", required_argument, 0, OPT_SSL_KEY}, - {"ssl-cert", required_argument, 0, OPT_SSL_CERT}, - {"ssl-ca", required_argument, 0, OPT_SSL_CA}, - {"ssl-capath", required_argument, 0, OPT_SSL_CAPATH}, - {"ssl-cipher", required_argument, 0, OPT_SSL_CIPHER}, + {"ssl", OPT_SSL_SSL, + "Use SSL for connection (automatically set with other flags)", + (gptr*) &opt_use_ssl, (gptr*) &opt_use_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"ssl-key", OPT_SSL_KEY, "X509 key in PEM format (implies --ssl)", + (gptr*) &opt_ssl_key, (gptr*) &opt_ssl_key, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, + {"ssl-cert", OPT_SSL_CERT, "X509 cert in PEM format (implies --ssl)", + (gptr*) &opt_ssl_cert, (gptr*) &opt_ssl_cert, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, + {"ssl-ca", OPT_SSL_CA, + "CA file in PEM format (check OpenSSL docs, implies --ssl)", + (gptr*) &opt_ssl_ca, (gptr*) &opt_ssl_ca, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, + {"ssl-capath", OPT_SSL_CAPATH, + "CA directory (check OpenSSL docs, implies --ssl)", + (gptr*) &opt_ssl_capath, (gptr*) &opt_ssl_capath, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, + {"ssl-cipher", OPT_SSL_CAPATH, "SSL cipher to use (implies --ssl)", + (gptr*) &opt_ssl_cipher, (gptr*) &opt_ssl_cipher, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, #endif /* HAVE_OPENSSL */ diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 20554b69393985f7375a202d9f1a4e44db96596e..63909018178b41488ae0964c07bed188d5990583 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -152,132 +152,140 @@ enum options { static struct my_option my_long_options[] = { - {"analyze", - "Analyze distribution of keys. Will make some joins in MySQL faster. You can check the calculated distribution.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'a', 0, 0, + {"analyze", 'a', + "Analyze distribution of keys. Will make some joins in MySQL faster. You can check the calculated distribution.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"block-search", "No help available.", 0, 0, 0, GET_LONG, REQUIRED_ARG, 'b', + {"block-search", 'b', "No help available.", 0, 0, 0, GET_LONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"backup", "Make a backup of the .MYD file as 'filename-time.BAK'", 0, 0, 0, - GET_NO_ARG, NO_ARG, 'B', 0, 0, 0, 0, 0, 0}, - {"character-sets-dir", "Directory where character sets are.", - (gptr*) &set_charset_name, 0, 0, GET_STR, REQUIRED_ARG, OPT_CHARSETS_DIR, 0, - 0, 0, 0, 0, 0}, - {"check", "Check table for errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'c', 0, 0, + {"backup", 'B', "Make a backup of the .MYD file as 'filename-time.BAK'", 0, + 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"character-sets-dir", OPT_CHARSETS_DIR, + "Directory where character sets are.", (gptr*) &set_charset_name, 0, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"check", 'c', "Check table for errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"check-only-changed", + {"check-only-changed", 'C', "Check only tables that has changed since last check.", 0, 0, 0, GET_NO_ARG, - NO_ARG, 'C', 0, 0, 0, 0, 0, 0}, - {"correct-checksum", "Correct checksum information for table.", 0, 0, 0, - GET_NO_ARG, NO_ARG, OPT_CORRECT_CHECKSUM, 0, 0, 0, 0, 0, 0}, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"correct-checksum", OPT_CORRECT_CHECKSUM, + "Correct checksum information for table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, + 0, 0, 0, 0, 0}, #ifndef DBUG_OFF - {"debug", "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, - GET_STR, OPT_ARG, '#', 0, 0, 0, 0, 0, 0}, + {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, + GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"description", "Prints some information about table.", 0, 0, 0, GET_NO_ARG, - NO_ARG, 'd', 0, 0, 0, 0, 0, 0}, - {"data-file-length", + {"description", 'd', "Prints some information about table.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"data-file-length", 'D', "Max length of data file (when recreating data-file when it's full).", (gptr*) &check_param.max_data_file_length, - (gptr*) &check_param.max_data_file_length, 0, GET_LONG, REQUIRED_ARG, 'D', + (gptr*) &check_param.max_data_file_length, 0, GET_LONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"extend-check", - "Try to recover every possible row from the data file. Normally this will also find a lot of garbage rows; Don't use this option if you are not totally desperate.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'e', 0, 0, 0, 0, 0, 0}, - {"fast", "Check only tables that hasn't been closed properly.", 0, 0, 0, - GET_NO_ARG, NO_ARG, 'F', 0, 0, 0, 0, 0, 0}, - {"force", - "Restart with -r if there are any errors in the table. States will be updated as with --update-state.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'f', 0, 0, 0, 0, 0, + {"extend-check", 'e', + "Try to recover every possible row from the data file. Normally this will also find a lot of garbage rows; Don't use this option if you are not totally desperate.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"fast", 'F', "Check only tables that hasn't been closed properly.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"force", 'f', + "Restart with -r if there are any errors in the table. States will be updated as with --update-state.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"help", "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, '?', 0, + {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"information", "Print statistics information about table that is checked.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 'i', 0, 0, 0, 0, 0, 0}, - {"keys-used", "Tell MyISAM to update only some specific keys. # is a bit mask of which keys to use. This can be used to get faster inserts!", + {"information", 'i', + "Print statistics information about table that is checked.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"keys-used", 'k', + "Tell MyISAM to update only some specific keys. # is a bit mask of which keys to use. This can be used to get faster inserts!", (gptr*) &check_param.keys_in_use, (gptr*) &check_param.keys_in_use, 0, - GET_LL, REQUIRED_ARG, 'k',-1, 0, 0, 0, 0, 0}, - {"medium-check", - "Faster than extended-check, but only finds 99.99% of all errors. Should be good enough for most cases.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'm', 0, 0, 0, 0, 0, + GET_LONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"medium-check", 'm', + "Faster than extended-check, but only finds 99.99% of all errors. Should be good enough for most cases.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"quick", "Faster repair by not modifying the data file.", 0, 0, 0, - GET_NO_ARG, NO_ARG, 'q', 0, 0, 0, 0, 0, 0}, - {"read-only", "Don't mark table as checked.", 0, 0, 0, GET_NO_ARG, NO_ARG, - 'T', 0, 0, 0, 0, 0, 0}, - {"recover", + {"quick", 'q', "Faster repair by not modifying the data file.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"read-only", 'T', "Don't mark table as checked.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"recover", 'r', "Can fix almost anything except unique keys that aren't unique.", 0, 0, 0, - GET_NO_ARG, NO_ARG, 'r', 0, 0, 0, 0, 0, 0}, - {"safe-recover", + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"safe-recover", 'o', "Uses old recovery method; Slower than '-r' but can handle a couple of cases where '-r' reports that it can't fix the data file.", 0, 0, 0, GET_NO_ARG, - NO_ARG, 'o', 0, 0, 0, 0, 0, 0}, - {"start-check-pos", "No help available.", 0, 0, 0, GET_LONG, REQUIRED_ARG, - OPT_START_CHECK_POS, 0, 0, 0, 0, 0, 0}, - {"set-auto-increment", + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"start-check-pos", OPT_START_CHECK_POS, "No help available.", 0, 0, 0, + GET_LONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"set-auto-increment", 'A', "Force auto_increment to start at this or higher value. If no value is given, then sets the next auto_increment value to the highest used value for the auto key + 1.", (gptr*) &check_param.auto_increment_value, - (gptr*) &check_param.auto_increment_value, 0, GET_LONG, OPT_ARG, 'A', 0, 0, - 0, 0, 0, 0}, - {"set-character-set", "Change the character set used by the index", 0, 0, 0, - GET_STR, REQUIRED_ARG, OPT_SET_CHARSET, 0, 0, 0, 0, 0, 0}, - {"set-variable", "Change the value of a variable. Please note that this option is depricated; you can set variables directly with --variable-name=value.", - 0, 0, 0, GET_STR, REQUIRED_ARG, 'O', 0, 0, 0, 0, 0, 0}, - {"silent", + (gptr*) &check_param.auto_increment_value, 0, GET_LONG, OPT_ARG, 0, 0, 0, + 0, 0, 0}, + {"set-character-set", OPT_SET_CHARSET, + "Change the character set used by the index", 0, 0, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"set-variable", 'O', + "Change the value of a variable. Please note that this option is depricated; you can set variables directly with --variable-name=value.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"silent", 's', "Only print errors. One can use two -s to make myisamchk very silent.", 0, - 0, 0, GET_NO_ARG, NO_ARG, 's', 0, 0, 0, 0, 0, 0}, - {"sort-index", + 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"sort-index", 'S', "Sort index blocks. This speeds up 'read-next' in applications.", 0, 0, 0, - GET_NO_ARG, NO_ARG, 'S', 0, 0, 0, 0, 0, 0}, - {"sort-records", + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"sort-records", 'R', "Sort records according to an index. This makes your data much more localized and may speed up things. (It may be VERY slow to do a sort the first time!)", (gptr*) &check_param.opt_sort_key, (gptr*) &check_param.opt_sort_key, 0, - GET_LONG, REQUIRED_ARG, 'R', 0, 0, 0, 0, 0, 0}, - {"sort-recover", + GET_LONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"sort-recover", 'n', "Force recovering with sorting even if the temporary file was very big.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 'n', 0, 0, 0, 0, 0, 0}, - {"tmpdir", "Path for temporary files.", (gptr*) &check_param.tmpdir, 0, 0, - GET_STR, REQUIRED_ARG, 't', 0, 0, 0, 0, 0, 0}, - {"update-state", "Mark tables as crashed if any errors were found.", 0, 0, - 0, GET_NO_ARG, NO_ARG, 'U', 0, 0, 0, 0, 0, 0}, - {"unpack", "Unpack file packed with myisampack.", 0, 0, 0, GET_NO_ARG, - NO_ARG, 'u', 0, 0, 0, 0, 0, 0}, - {"verbose", - "Print more information. This can be used with --describe and --check. Use many -v for more verbosity!", 0, 0, 0, GET_NO_ARG, NO_ARG, 'v', 0, 0, 0, 0, 0, + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"tmpdir", 't', "Path for temporary files.", + (gptr*) &check_param.tmpdir, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"update-state", 'U', "Mark tables as crashed if any errors were found.", 0, + 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"unpack", 'u', "Unpack file packed with myisampack.", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"verbose", 'v', + "Print more information. This can be used with --describe and --check. Use many -v for more verbosity!", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"version", "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'V', 0, + {"version", 'V', "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"wait", "Wait if table is locked.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'w', 0, 0, + {"wait", 'w', "Wait if table is locked.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - { "key_buffer_size", "", (gptr*) &check_param.use_buffers, - (gptr*) &check_param.use_buffers, 0, GET_LONG, REQUIRED_ARG, - OPT_KEY_BUFFER_SIZE, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD, + { "key_buffer_size", OPT_KEY_BUFFER_SIZE, "", + (gptr*) &check_param.use_buffers, (gptr*) &check_param.use_buffers, 0, + GET_LONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0}, - { "myisam_block_size", "", (gptr*) &opt_myisam_block_size, - (gptr*) &opt_myisam_block_size, 0, GET_LONG, REQUIRED_ARG, - OPT_MYISAM_BLOCK_SIZE, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, + { "myisam_block_size", OPT_MYISAM_BLOCK_SIZE, "", + (gptr*) &opt_myisam_block_size, (gptr*) &opt_myisam_block_size, 0, + GET_LONG, REQUIRED_ARG, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH, 0, MI_MIN_KEY_BLOCK_LENGTH, 0}, - { "read_buffer_size", "", (gptr*) &check_param.read_buffer_length, + { "read_buffer_size", OPT_READ_BUFFER_SIZE, "", + (gptr*) &check_param.read_buffer_length, (gptr*) &check_param.read_buffer_length, 0, GET_LONG, REQUIRED_ARG, - OPT_READ_BUFFER_SIZE, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, + (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0}, - { "write_buffer_size", "", (gptr*) &check_param.write_buffer_length, + { "write_buffer_size", OPT_WRITE_BUFFER_SIZE, "", + (gptr*) &check_param.write_buffer_length, (gptr*) &check_param.write_buffer_length, 0, GET_LONG, REQUIRED_ARG, - OPT_WRITE_BUFFER_SIZE, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, + (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0}, - { "sort_buffer_size", "", (gptr*) &check_param.sort_buffer_length, + { "sort_buffer_size", OPT_SORT_BUFFER_SIZE, "", + (gptr*) &check_param.sort_buffer_length, (gptr*) &check_param.sort_buffer_length, 0, GET_LONG, REQUIRED_ARG, - OPT_SORT_BUFFER_SIZE, (long) SORT_BUFFER_INIT, - (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), (long) ~0L, - (long) MALLOC_OVERHEAD, (long) 1L, 0}, - { "sort_key_blocks", "", (gptr*) &check_param.sort_key_blocks, + (long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), + (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0}, + { "sort_key_blocks", OPT_SORT_KEY_BLOCKS, "", + (gptr*) &check_param.sort_key_blocks, (gptr*) &check_param.sort_key_blocks, 0, GET_LONG, REQUIRED_ARG, - OPT_SORT_KEY_BLOCKS, BUFFERS_WHEN_SORTING, 4L, 100L, 0L, 1L, 0}, - { "decode_bits", "", (gptr*) &decode_bits, (gptr*) &decode_bits, 0, - GET_LONG, REQUIRED_ARG, OPT_DECODE_BITS, 9L, 4L, 17L, 0L, 1L, 0}, - { "ft_min_word_len", "", (gptr*) &ft_min_word_len, (gptr*) &ft_min_word_len, - 0, GET_LONG, REQUIRED_ARG, OPT_FT_MIN_WORD_LEN, 4, 1, HA_FT_MAXLEN, 0, 1, - 0}, - { "ft_max_word_len", "", (gptr*) &ft_max_word_len, (gptr*) &ft_max_word_len, - 0, GET_LONG, REQUIRED_ARG, OPT_FT_MAX_WORD_LEN, HA_FT_MAXLEN, 10, + BUFFERS_WHEN_SORTING, 4L, 100L, 0L, 1L, 0}, + { "decode_bits", OPT_DECODE_BITS, "", (gptr*) &decode_bits, + (gptr*) &decode_bits, 0, GET_LONG, REQUIRED_ARG, 9L, 4L, 17L, 0L, 1L, 0}, + { "ft_min_word_len", OPT_FT_MIN_WORD_LEN, "", (gptr*) &ft_min_word_len, + (gptr*) &ft_min_word_len, 0, GET_LONG, REQUIRED_ARG, 4, 1, HA_FT_MAXLEN, + 0, 1, 0}, + { "ft_max_word_len", OPT_FT_MAX_WORD_LEN, "", (gptr*) &ft_max_word_len, + (gptr*) &ft_max_word_len, 0, GET_LONG, REQUIRED_ARG, HA_FT_MAXLEN, 10, HA_FT_MAXLEN, 0, 1, 0}, - { "ft_max_word_len_for_sort", "", (gptr*) &ft_max_word_len_for_sort, - (gptr*) &ft_max_word_len_for_sort, 0, GET_LONG, REQUIRED_ARG, - OPT_FT_MAX_WORD_LEN_FOR_SORT, 20, 4, HA_FT_MAXLEN, 0, 1, 0}, + { "ft_max_word_len_for_sort", OPT_FT_MAX_WORD_LEN_FOR_SORT, "", + (gptr*) &ft_max_word_len_for_sort, (gptr*) &ft_max_word_len_for_sort, 0, + GET_LONG, REQUIRED_ARG, 20, 4, HA_FT_MAXLEN, 0, 1, 0}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; @@ -384,6 +392,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), char *argument) { + uint old_testflag; + switch (optid) { case 'a': if (argument && *argument == '0') @@ -415,7 +425,10 @@ get_one_option(int optid, break; case 'C': if (argument && *argument == '0') - check_param.testflag&= ~(T_CHECK | T_CHECK_ONLY_CHANGED); + { + check_param.testflag&= ~T_CHECK; + check_param.testflag&= ~T_CHECK_ONLY_CHANGED; + } else check_param.testflag|= T_CHECK | T_CHECK_ONLY_CHANGED; break; @@ -424,7 +437,11 @@ get_one_option(int optid, break; case 's': /* silent */ if (argument && *argument == '0') - check_param.testflag&= ~(T_SILENT | T_VERY_SILENT); + { + if (check_param.testflag & T_VERY_SILENT) + check_param.testflag&= ~T_VERY_SILENT; + check_param.testflag&= ~T_SILENT; + } else { if (check_param.testflag & T_SILENT) @@ -458,16 +475,8 @@ get_one_option(int optid, check_param.testflag|= T_INFO; break; case 'f': - if (argument && *argument == '0') - { - check_param.tmpfile_createflag= O_RDWR | O_TRUNC | O_EXCL; - check_param.testflag&= ~(T_FORCE_CREATE | T_UPDATE_STATE); - } - else - { - check_param.tmpfile_createflag= O_RDWR | O_TRUNC; - check_param.testflag|= T_FORCE_CREATE | T_UPDATE_STATE; - } + check_param.tmpfile_createflag= O_RDWR | O_TRUNC; + check_param.testflag|= T_FORCE_CREATE | T_UPDATE_STATE; break; case 'F': if (argument && *argument == '0') @@ -485,83 +494,61 @@ get_one_option(int optid, check_param.testflag|= T_MEDIUM; /* Medium check */ break; case 'r': /* Repair table */ - if (argument && *argument == '0') - check_param.testflag&= ~(T_REP | T_REP_BY_SORT); - else - check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT; + check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT; break; case 'o': - if (argument && *argument == '0') - { - check_param.testflag&= ~(T_REP | T_REP_BY_SORT); - check_param.force_sort= 0; - } - else - { - check_param.testflag= (check_param.testflag & ~T_REP_BY_SORT) | T_REP; - check_param.force_sort= 0; - my_disable_async_io= 1; /* More safety */ - } + check_param.testflag= (check_param.testflag & ~T_REP_BY_SORT) | T_REP; + check_param.force_sort=0; + my_disable_async_io=1; /* More safety */ break; case 'n': - if (argument && *argument == '0') - { - check_param.testflag&= ~(T_REP | T_REP_BY_SORT); - check_param.force_sort= 0; - } - else - { - check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT; - check_param.force_sort= 1; - } + check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT; + check_param.force_sort= 1; break; case 'q': if (argument && *argument == '0') - check_param.testflag&= ~(T_QUICK | T_FORCE_UNIQUENESS); + check_param.opt_rep_quick--; else - check_param.testflag|= - (check_param.testflag & T_QUICK) ? T_FORCE_UNIQUENESS : T_QUICK; + check_param.opt_rep_quick++; break; case 'u': - if (argument && *argument == '0') - check_param.testflag&= ~(T_UNPACK | T_REP_BY_SORT); + if (argument == disabled_my_option) + { + check_param.testflag&= ~T_UNPACK; + check_param.testflag&= ~T_REP_BY_SORT; + } else check_param.testflag|= T_UNPACK | T_REP_BY_SORT; break; case 'v': /* Verbose */ if (argument && *argument == '0') - { check_param.testflag&= ~T_VERBOSE; - check_param.verbose=0; - } else - { check_param.testflag|= T_VERBOSE; - check_param.verbose++; - } + check_param.verbose++; break; case 'R': /* Sort records */ - if (argument && *argument == '0') - check_param.testflag&= ~T_SORT_RECORDS; - else + old_testflag= check_param.testflag; + check_param.testflag|= T_SORT_RECORDS; + check_param.opt_sort_key= (uint) atoi(argument) - 1; + if (check_param.opt_sort_key >= MI_MAX_KEY) { - check_param.testflag|= T_SORT_RECORDS; - check_param.opt_sort_key= (uint) atoi(argument) - 1; - if (check_param.opt_sort_key >= MI_MAX_KEY) - { - fprintf(stderr, - "The value of the sort key is bigger than max key: %d.\n", - MI_MAX_KEY); - exit(1); - } + fprintf(stderr, + "The value of the sort key is bigger than max key: %d.\n", + MI_MAX_KEY); + exit(1); } break; case 'S': /* Sort index */ + old_testflag= check_param.testflag; if (argument && *argument == '0') check_param.testflag&= ~T_SORT_INDEX; else check_param.testflag|= T_SORT_INDEX; break; + case 't': + check_param.tmpdir= argument; + break; case 'T': if (argument && *argument == '0') check_param.testflag&= ~T_READONLY; @@ -575,14 +562,7 @@ get_one_option(int optid, check_param.testflag|= T_UPDATE_STATE; break; case '#': - if (argument && *argument == '0') - { - DBUG_POP(); - } - else - { - DBUG_PUSH(argument ? argument : "d:t:o,/tmp/myisamchk.trace"); - } + DBUG_PUSH(argument ? argument : "d:t:o,/tmp/myisamchk.trace"); break; case 'V': print_version(); @@ -628,7 +608,7 @@ static void get_options(register int *argc,register char ***argv) } if ((check_param.testflag & T_UNPACK) && - (check_param.testflag & (T_QUICK | T_SORT_RECORDS))) + (check_param.opt_rep_quick || (check_param.testflag & T_SORT_RECORDS))) { VOID(fprintf(stderr, "%s: --unpack can't be used with --quick or --sort-records\n", @@ -660,7 +640,7 @@ static void get_options(register int *argc,register char ***argv) static int myisamchk(MI_CHECK *param, my_string filename) { int error,lock_type,recreate; - int rep_quick= param->testflag & (T_QUICK | T_FORCE_UNIQUENESS); + int rep_quick= param->opt_rep_quick; uint raid_chunks; MI_INFO *info; File datafile; @@ -795,7 +775,8 @@ static int myisamchk(MI_CHECK *param, my_string filename) param->testflag|=T_REP_BY_SORT; /* if only STATISTICS */ if (!(param->testflag & T_SILENT)) printf("- '%s' has old table-format. Recreating index\n",filename); - rep_quick|=T_QUICK; + if (!rep_quick) + rep_quick=1; } share=info->s; share->r_locks=0; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 5ec26e3de3f604a59fd47d408836f137c0aa7ecc..0816303372b92207d2b020e3d261e2f048e77a49 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -34,6 +34,7 @@ static void init_variables(const struct my_option *options); static const char *special_opt_prefix[]= {"skip", "disable", "enable", "maximum", 0}; +char *disabled_my_option= (char*) "0"; /* Return error values from handle_options */ @@ -65,7 +66,7 @@ int handle_options(int *argc, char ***argv, char *)) { uint opt_found, argvpos= 0, length, spec_len, i; - int err; + int err= 0; my_bool end_of_options= 0, must_be_var, set_maximum_value, special_used; char *progname= *(*argv), **pos, *optend, *prev_found; const struct my_option *optp; @@ -176,7 +177,7 @@ int handle_options(int *argc, char ***argv, We were called with a special prefix, we can reuse opt_found */ special_used= 1; - cur_arg += (spec_len + 1); + cur_arg+= (spec_len + 1); if ((opt_found= findopt(cur_arg, length - (spec_len + 1), &optp, &prev_found))) { @@ -189,7 +190,7 @@ int handle_options(int *argc, char ***argv, return ERR_AMBIGUOUS_OPTION; } if (i < DISABLE_OPTION_COUNT) - optend= (char*) "0"; + optend= disabled_my_option; else if (!compare_strings(special_opt_prefix[i],"enable",6)) optend= (char*) "1"; else if (!compare_strings(special_opt_prefix[i],"maximum",7)) @@ -235,15 +236,44 @@ int handle_options(int *argc, char ***argv, } if (must_be_var && !optp->value) { - fprintf(stderr, "%s: the argument '%s' is not an variable\n", + fprintf(stderr, "%s: argument '%s' is not a variable\n", progname, *pos); return ERR_MUST_BE_VARIABLE; } - if (optp->arg_type == NO_ARG && optend && !special_used) + if (optp->arg_type == NO_ARG) { - fprintf(stderr, "%s: option '--%s' cannot take an argument\n", - progname, optp->name); - return ERR_NO_ARGUMENT_ALLOWED; + if (optend && !special_used) + { + fprintf(stderr, "%s: option '--%s' cannot take an argument\n", + progname, optp->name); + return ERR_NO_ARGUMENT_ALLOWED; + } + if (optp->var_type == GET_BOOL) + { + /* + Set bool to 1 if no argument or if the user has used + --enable-'option-name'. + *optend was set to '0' if one used --disable-option + */ + *((my_bool*) optp->value)= (my_bool) (!optend || *optend == '1'); + (*argc)--; + continue; + } + argument= optend; + } + else if (optp->arg_type == OPT_ARG && optp->var_type == GET_BOOL) + { + if (optend == disabled_my_option) + *((my_bool*) optp->value)= (my_bool) 0; + else + { + if (!optend) /* No argument -> enable option */ + *((my_bool*) optp->value)= (my_bool) 1; + else /* If argument differs from 0, enable option, else disable */ + *((my_bool*) optp->value)= (my_bool) atoi(optend) != 0; + } + (*argc)--; + continue; } else if (optp->arg_type == REQUIRED_ARG && !optend) { @@ -311,6 +341,7 @@ int handle_options(int *argc, char ***argv, { gptr *result_pos= (set_maximum_value) ? optp->u_max_value : optp->value; + if (!result_pos) { fprintf(stderr, @@ -320,14 +351,13 @@ int handle_options(int *argc, char ***argv, if (optp->var_type == GET_LONG) *((long*) result_pos)= (long) getopt_ll(argument, optp, &err); else if (optp->var_type == GET_LL) - *((longlong*) result_pos)= getopt_ll(argument, optp, &err); + *((longlong*) result_pos)= getopt_ll(argument, optp, &err); else if (optp->var_type == GET_STR) *((char**) result_pos)= argument; if (err) return ERR_UNKNOWN_SUFFIX; } - else - get_one_option(optp->id, optp, argument); + get_one_option(optp->id, optp, argument); (*argc)--; /* option handled (short or long), decrease argument count */ } @@ -488,17 +518,19 @@ void my_print_help(const struct my_option *options) col+= 2 + strlen(optp->name); if (optp->var_type == GET_STR) { - printf("=name "); + printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "", + optp->arg_type == OPT_ARG ? "]" : ""); col+= 6; } - else if (optp->var_type == GET_NO_ARG) + else if (optp->var_type == GET_NO_ARG || optp->var_type == GET_BOOL) { putchar(' '); col++; } else { - printf("=# "); + printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "", + optp->arg_type == OPT_ARG ? "]" : ""); col+= 3; } if (col > name_space) @@ -545,7 +577,7 @@ void my_print_variables(const struct my_option *options) printf("--------------------------------- -------------\n"); for (optp= options; optp->id; optp++) { - if (optp->value) + if (optp->value && optp->var_type != GET_BOOL) { printf("%s", optp->name); length= strlen(optp->name); @@ -553,10 +585,10 @@ void my_print_variables(const struct my_option *options) putchar(' '); if (optp->var_type == GET_STR) { - if (!optp->def_value && !*((char**) optp->value)) - printf("(No default value)\n"); - else + if (*((char**) optp->value)) printf("%s\n", *((char**) optp->value)); + else + printf("(No default value)\n"); } else if (optp->var_type == GET_LONG) { @@ -565,7 +597,7 @@ void my_print_variables(const struct my_option *options) else printf("%lu\n", *((long*) optp->value)); } - else + else { if (!optp->def_value && !*((longlong*) optp->value)) printf("(No default value)\n"); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 0dda582da59969b86be3db1b1a7090ad660d5370..f787181174a2b8688d4d81b43ab0d9bcbc5cc522 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2894,7 +2894,9 @@ static struct option long_options[] = { {"socket", required_argument, 0, (int) OPT_SOCKET}, {"sql-bin-update-same", no_argument, 0, (int) OPT_SQL_BIN_UPDATE_SAME}, {"sql-mode", required_argument, 0, (int) OPT_SQL_MODE}, +#ifdef TO_BE_DONE #include "sslopt-longopts.h" +#endif #ifdef __WIN__ {"standalone", no_argument, 0, (int) OPT_STANDALONE}, #endif @@ -4083,8 +4085,10 @@ static void get_options(int argc,char **argv) strmake(mysql_charsets_dir, optarg, sizeof(mysql_charsets_dir)-1); charsets_dir = mysql_charsets_dir; break; +#ifdef TO_BE_DONE #include "sslopt-case.h" case OPT_DES_KEY_FILE: +#endif #ifdef HAVE_OPENSSL des_key_file=optarg; #endif