34 #include <my_global.h>
37 #include "mysql/client_authentication.h"
40 #undef max_allowed_packet
41 #undef net_buffer_length
43 #ifdef EMBEDDED_LIBRARY
51 #define CLI_MYSQL_REAL_CONNECT STDCALL cli_mysql_real_connect
57 #define CLI_MYSQL_REAL_CONNECT STDCALL mysql_real_connect
61 #include "my_default.h"
62 #include <mysys_err.h>
65 #include "mysql_version.h"
66 #include "mysqld_error.h"
71 #include <my_pthread.h>
86 #ifdef HAVE_SYS_SELECT_H
87 # include <sys/select.h>
97 #define SOCKET_ERROR -1
100 #include "client_settings.h"
101 #include <sql_common.h>
104 #define native_password_plugin_name "mysql_native_password"
105 #define old_password_plugin_name "mysql_old_password"
109 char *mysql_unix_port= 0;
110 const char *unknown_sqlstate=
"HY000";
111 const char *not_error_sqlstate=
"00000";
112 const char *cant_connect_sqlstate=
"08001";
114 char *shared_memory_base_name= 0;
115 const char *def_shared_memory_base_name= default_shared_memory_base_name;
118 static void mysql_close_free_options(
MYSQL *mysql);
119 static void mysql_close_free(
MYSQL *mysql);
120 static void mysql_prune_stmt_list(
MYSQL *mysql);
122 CHARSET_INFO *default_client_charset_info = &my_charset_latin1;
125 unsigned int mysql_server_last_errno;
126 char mysql_server_last_error[MYSQL_ERRMSG_SIZE];
137 static int get_vio_connect_timeout(
MYSQL *mysql)
148 timeout_sec= mysql->options.connect_timeout;
150 if (!timeout_sec || (timeout_sec > INT_MAX/1000))
153 timeout_ms= (int) (timeout_sec * 1000);
173 static DWORD get_win32_connect_timeout(
MYSQL *mysql)
184 timeout_sec= mysql->options.connect_timeout;
186 if (!timeout_sec || (timeout_sec > INT_MAX/1000))
187 timeout_ms= INFINITE;
189 timeout_ms= (DWORD) (timeout_sec * 1000);
206 void set_mysql_error(
MYSQL *mysql,
int errcode,
const char *sqlstate)
209 DBUG_ENTER(
"set_mysql_error");
210 DBUG_PRINT(
"enter", (
"error :%d '%s'", errcode, ER(errcode)));
211 DBUG_ASSERT(mysql != 0);
216 net->last_errno= errcode;
222 mysql_server_last_errno= errcode;
223 strmov(mysql_server_last_error, ER(errcode));
233 my_bool my_net_is_inited(
NET *net)
235 return net->buff != NULL;
244 void net_clear_error(
NET *net)
248 strmov(net->
sqlstate, not_error_sqlstate);
262 void set_mysql_extended_error(
MYSQL *mysql,
int errcode,
263 const char *sqlstate,
264 const char *format, ...)
268 DBUG_ENTER(
"set_mysql_extended_error");
269 DBUG_PRINT(
"enter", (
"error :%d '%s'", errcode, format));
270 DBUG_ASSERT(mysql != 0);
273 net->last_errno= errcode;
274 va_start(args, format);
291 static HANDLE create_named_pipe(
MYSQL *mysql, DWORD connect_timeout,
292 const char **arg_host,
293 const char **arg_unix_socket)
295 HANDLE hPipe=INVALID_HANDLE_VALUE;
296 char pipe_name[1024];
299 my_bool testing_named_pipes=0;
300 const char *host= *arg_host, *unix_socket= *arg_unix_socket;
302 if ( ! unix_socket || (unix_socket)[0] == 0x00)
303 unix_socket = mysql_unix_port;
304 if (!host || !strcmp(host,LOCAL_HOST))
305 host=LOCAL_HOST_NAMEDPIPE;
308 pipe_name[
sizeof(pipe_name)-1]= 0;
309 strxnmov(pipe_name,
sizeof(pipe_name)-1,
"\\\\", host,
"\\pipe\\",
311 DBUG_PRINT(
"info",(
"Server name: '%s'. Named Pipe: %s", host, unix_socket));
313 for (i=0 ; i < 100 ; i++)
315 if ((hPipe = CreateFile(pipe_name,
316 GENERIC_READ | GENERIC_WRITE,
320 FILE_FLAG_OVERLAPPED,
321 NULL )) != INVALID_HANDLE_VALUE)
323 if (GetLastError() != ERROR_PIPE_BUSY)
325 set_mysql_extended_error(mysql, CR_NAMEDPIPEOPEN_ERROR,
326 unknown_sqlstate, ER(CR_NAMEDPIPEOPEN_ERROR),
327 host, unix_socket, (ulong) GetLastError());
328 return INVALID_HANDLE_VALUE;
331 if (!WaitNamedPipe(pipe_name, connect_timeout))
333 set_mysql_extended_error(mysql, CR_NAMEDPIPEWAIT_ERROR, unknown_sqlstate,
334 ER(CR_NAMEDPIPEWAIT_ERROR),
335 host, unix_socket, (ulong) GetLastError());
336 return INVALID_HANDLE_VALUE;
339 if (hPipe == INVALID_HANDLE_VALUE)
341 set_mysql_extended_error(mysql, CR_NAMEDPIPEOPEN_ERROR, unknown_sqlstate,
342 ER(CR_NAMEDPIPEOPEN_ERROR), host, unix_socket,
343 (ulong) GetLastError());
344 return INVALID_HANDLE_VALUE;
346 dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
347 if ( !SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL) )
349 CloseHandle( hPipe );
350 set_mysql_extended_error(mysql, CR_NAMEDPIPESETSTATE_ERROR,
351 unknown_sqlstate, ER(CR_NAMEDPIPESETSTATE_ERROR),
352 host, unix_socket, (ulong) GetLastError());
353 return INVALID_HANDLE_VALUE;
355 *arg_host=host ; *arg_unix_socket=unix_socket;
372 static HANDLE create_shared_memory(
MYSQL *mysql,
NET *net,
373 DWORD connect_timeout)
375 ulong smem_buffer_length = shared_memory_buffer_length + 4;
389 HANDLE event_connect_request = NULL;
390 HANDLE event_connect_answer = NULL;
391 HANDLE handle_connect_file_map = NULL;
392 char *handle_connect_map = NULL;
394 char *handle_map = NULL;
395 HANDLE event_server_wrote = NULL;
396 HANDLE event_server_read = NULL;
397 HANDLE event_client_wrote = NULL;
398 HANDLE event_client_read = NULL;
399 HANDLE event_conn_closed = NULL;
400 HANDLE handle_file_map = NULL;
401 ulong connect_number;
402 char connect_number_char[22], *p;
405 DWORD error_allow = 0;
406 DWORD error_code = 0;
407 DWORD event_access_rights= SYNCHRONIZE | EVENT_MODIFY_STATE;
408 char *shared_memory_base_name = mysql->options.shared_memory_base_name;
409 static const char *name_prefixes[] = {
"",
"Global\\"};
420 DBUG_ASSERT(shared_memory_base_name != NULL);
425 if (!(tmp= (
char *)my_malloc(strlen(shared_memory_base_name) + 32L, MYF(MY_FAE))))
435 for (i = 0; i< array_elements(name_prefixes); i++)
437 prefix= name_prefixes[
i];
438 suffix_pos = strxmov(tmp, prefix , shared_memory_base_name,
"_", NullS);
439 strmov(suffix_pos,
"CONNECT_REQUEST");
440 event_connect_request= OpenEvent(event_access_rights, FALSE, tmp);
441 if (event_connect_request)
446 if (!event_connect_request)
448 error_allow = CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR;
451 strmov(suffix_pos,
"CONNECT_ANSWER");
452 if (!(event_connect_answer= OpenEvent(event_access_rights,FALSE,tmp)))
454 error_allow = CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR;
457 strmov(suffix_pos,
"CONNECT_DATA");
458 if (!(handle_connect_file_map= OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)))
460 error_allow = CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR;
463 if (!(handle_connect_map= MapViewOfFile(handle_connect_file_map,
464 FILE_MAP_WRITE,0,0,
sizeof(DWORD))))
466 error_allow = CR_SHARED_MEMORY_CONNECT_MAP_ERROR;
471 if (!SetEvent(event_connect_request))
473 error_allow = CR_SHARED_MEMORY_CONNECT_SET_ERROR;
478 if (WaitForSingleObject(event_connect_answer, connect_timeout) !=
481 error_allow = CR_SHARED_MEMORY_CONNECT_ABANDONED_ERROR;
486 connect_number = uint4korr(handle_connect_map);
487 p= int10_to_str(connect_number, connect_number_char, 10);
498 suffix_pos = strxmov(tmp, prefix , shared_memory_base_name,
"_", connect_number_char,
500 strmov(suffix_pos,
"DATA");
501 if ((handle_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL)
503 error_allow = CR_SHARED_MEMORY_FILE_MAP_ERROR;
506 if ((handle_map = MapViewOfFile(handle_file_map,FILE_MAP_WRITE,0,0,
507 smem_buffer_length)) == NULL)
509 error_allow = CR_SHARED_MEMORY_MAP_ERROR;
513 strmov(suffix_pos,
"SERVER_WROTE");
514 if ((event_server_wrote = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
516 error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
520 strmov(suffix_pos,
"SERVER_READ");
521 if ((event_server_read = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
523 error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
527 strmov(suffix_pos,
"CLIENT_WROTE");
528 if ((event_client_wrote = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
530 error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
534 strmov(suffix_pos,
"CLIENT_READ");
535 if ((event_client_read = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
537 error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
541 strmov(suffix_pos,
"CONNECTION_CLOSED");
542 if ((event_conn_closed = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
544 error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
550 SetEvent(event_server_read);
553 if (error_allow == 0)
555 net->vio= vio_new_win32shared_memory(handle_file_map,handle_map,
557 event_server_read,event_client_wrote,
558 event_client_read,event_conn_closed);
562 error_code = GetLastError();
563 if (event_server_read)
564 CloseHandle(event_server_read);
565 if (event_server_wrote)
566 CloseHandle(event_server_wrote);
567 if (event_client_read)
568 CloseHandle(event_client_read);
569 if (event_client_wrote)
570 CloseHandle(event_client_wrote);
571 if (event_conn_closed)
572 CloseHandle(event_conn_closed);
574 UnmapViewOfFile(handle_map);
576 CloseHandle(handle_file_map);
581 error_code = GetLastError();
582 if (event_connect_request)
583 CloseHandle(event_connect_request);
584 if (event_connect_answer)
585 CloseHandle(event_connect_answer);
586 if (handle_connect_map)
587 UnmapViewOfFile(handle_connect_map);
588 if (handle_connect_file_map)
589 CloseHandle(handle_connect_file_map);
592 if (error_allow == CR_SHARED_MEMORY_EVENT_ERROR)
593 set_mysql_extended_error(mysql, error_allow, unknown_sqlstate,
594 ER(error_allow), suffix_pos, error_code);
596 set_mysql_extended_error(mysql, error_allow, unknown_sqlstate,
597 ER(error_allow), error_code);
598 return(INVALID_HANDLE_VALUE);
614 cli_safe_read(
MYSQL *mysql)
616 NET *net= &mysql->net;
622 if (len == packet_error || len == 0)
624 DBUG_PRINT(
"error",(
"Wrong connection or packet. fd: %s len: %lu",
625 vio_description(net->vio),len));
627 if (net->vio && (net->last_errno == ER_NET_READ_INTERRUPTED))
628 return (packet_error);
631 set_mysql_error(mysql, net->last_errno == ER_NET_PACKET_TOO_LARGE ?
632 CR_NET_PACKET_TOO_LARGE: CR_SERVER_LOST, unknown_sqlstate);
633 return (packet_error);
635 if (net->read_pos[0] == 255)
639 char *pos=(
char*) net->read_pos+1;
640 net->last_errno=uint2korr(pos);
643 if (protocol_41(mysql) && pos[0] ==
'#')
645 strmake(net->
sqlstate, pos+1, SQLSTATE_LENGTH);
646 pos+= SQLSTATE_LENGTH+1;
655 strmov(net->
sqlstate, unknown_sqlstate);
659 MY_MIN((uint) len,(uint)
sizeof(net->
last_error)-1));
662 set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
672 mysql->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
674 DBUG_PRINT(
"error",(
"Got error: %d/%s (%s)",
678 return(packet_error);
687 free_root(&cur->alloc,MYF(0));
693 cli_advanced_command(
MYSQL *mysql,
enum enum_server_command command,
694 const uchar *header, ulong header_length,
695 const uchar *arg, ulong arg_length, my_bool skip_check,
698 NET *net= &mysql->net;
700 my_bool stmt_skip= stmt ? stmt->state != MYSQL_STMT_INIT_DONE : FALSE;
701 DBUG_ENTER(
"cli_advanced_command");
703 if (mysql->net.vio == 0)
705 if (mysql_reconnect(mysql) || stmt_skip)
708 if (mysql->status != MYSQL_STATUS_READY ||
709 mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
711 DBUG_PRINT(
"error",(
"state: %d", mysql->status));
712 set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
716 net_clear_error(net);
718 mysql->affected_rows= ~(my_ulonglong) 0;
725 net_clear(&mysql->net, (command != COM_QUIT));
730 DBUG_PRINT(
"error",(
"Can't send command to server. Error: %d",
732 if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
734 set_mysql_error(mysql, CR_NET_PACKET_TOO_LARGE, unknown_sqlstate);
738 if (mysql_reconnect(mysql) || stmt_skip)
743 set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate);
749 result= ((mysql->packet_length=cli_safe_read(mysql)) == packet_error ?
752 DBUG_PRINT(
"exit",(
"result: %d", result));
756 void free_old_query(
MYSQL *mysql)
758 DBUG_ENTER(
"free_old_query");
760 free_root(&mysql->field_alloc,MYF(0));
761 init_alloc_root(&mysql->field_alloc,8192,0);
763 mysql->field_count= 0;
764 mysql->warning_count= 0;
779 my_bool flush_one_result(
MYSQL *mysql)
783 DBUG_ASSERT(mysql->status != MYSQL_STATUS_READY);
787 packet_length= cli_safe_read(mysql);
797 if (packet_length == packet_error)
800 while (packet_length > 8 || mysql->net.read_pos[0] != 254);
804 if (protocol_41(mysql))
806 char *pos= (
char*) mysql->net.read_pos + 1;
807 mysql->warning_count=uint2korr(pos);
809 mysql->server_status=uint2korr(pos);
824 my_bool opt_flush_ok_packet(
MYSQL *mysql, my_bool *is_ok_packet)
826 ulong packet_length= cli_safe_read(mysql);
828 if (packet_length == packet_error)
832 DBUG_ASSERT(packet_length);
834 *is_ok_packet= mysql->net.read_pos[0] == 0;
837 uchar *pos= mysql->net.read_pos + 1;
839 net_field_length_ll(&pos);
840 net_field_length_ll(&pos);
842 mysql->server_status=uint2korr(pos);
845 if (protocol_41(mysql))
847 mysql->warning_count=uint2korr(pos);
859 static void cli_flush_use_result(
MYSQL *mysql, my_bool flush_all_results)
862 DBUG_ENTER(
"cli_flush_use_result");
863 DBUG_PRINT(
"warning",(
"Not all packets read, clearing them"));
865 if (flush_one_result(mysql))
868 if (! flush_all_results)
871 while (mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
873 my_bool is_ok_packet;
874 if (opt_flush_ok_packet(mysql, &is_ok_packet))
891 if (flush_one_result(mysql) || flush_one_result(mysql))
900 static my_bool is_NT(
void)
902 char *os=getenv(
"OS");
903 return (os && !strcmp(os,
"Windows_NT")) ? 1 : 0;
920 static int check_license(
MYSQL *mysql)
924 NET *net= &mysql->net;
925 static const char query[]=
"SELECT @@license";
926 static const char required_license[]= STRINGIFY_ARG(LICENSE);
928 if (mysql_real_query(mysql, query,
sizeof(query)-1))
930 if (net->last_errno == ER_UNKNOWN_SYSTEM_VARIABLE)
932 set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
933 ER(CR_WRONG_LICENSE), required_license);
937 if (!(res= mysql_use_result(mysql)))
939 row= mysql_fetch_row(res);
945 if (!net->last_errno &&
947 strncmp(row[0], required_license,
sizeof(required_license))))
949 set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
950 ER(CR_WRONG_LICENSE), required_license);
952 mysql_free_result(res);
953 return net->last_errno;
962 void end_server(
MYSQL *mysql)
964 int save_errno= errno;
965 DBUG_ENTER(
"end_server");
966 if (mysql->net.vio != 0)
968 DBUG_PRINT(
"info",(
"Net: %s", vio_description(mysql->net.vio)));
970 slave_io_thread_detach_vio();
972 vio_delete(mysql->net.vio);
974 mysql_prune_stmt_list(mysql);
976 net_end(&mysql->net);
977 free_old_query(mysql);
986 DBUG_ENTER(
"mysql_free_result");
987 DBUG_PRINT(
"enter",(
"mysql_res: 0x%lx", (
long) result));
990 MYSQL *mysql= result->handle;
993 if (mysql->unbuffered_fetch_owner == &result->unbuffered_fetch_cancelled)
994 mysql->unbuffered_fetch_owner= 0;
995 if (mysql->status == MYSQL_STATUS_USE_RESULT)
997 (*mysql->methods->flush_use_result)(mysql, FALSE);
998 mysql->status=MYSQL_STATUS_READY;
999 if (mysql->unbuffered_fetch_owner)
1000 *mysql->unbuffered_fetch_owner= TRUE;
1003 free_rows(result->data);
1005 free_root(&result->field_alloc,MYF(0));
1006 my_free(result->row);
1016 static const char *default_options[]=
1018 "port",
"socket",
"compress",
"password",
"pipe",
"timeout",
"user",
1019 "init-command",
"host",
"database",
"debug",
"return-found-rows",
1020 "ssl-key" ,
"ssl-cert" ,
"ssl-ca" ,
"ssl-capath",
1021 "character-sets-dir",
"default-character-set",
"interactive-timeout",
1022 "connect-timeout",
"local-infile",
"disable-local-infile",
1023 "ssl-cipher",
"max-allowed-packet",
"protocol",
"shared-memory-base-name",
1024 "multi-results",
"multi-statements",
"multi-queries",
"secure-auth",
1025 "report-data-truncation",
"plugin-dir",
"default-auth",
1026 "bind-address",
"ssl-crl",
"ssl-crlpath",
"enable-cleartext-plugin",
1030 OPT_port=1, OPT_socket, OPT_compress, OPT_password, OPT_pipe, OPT_timeout, OPT_user,
1031 OPT_init_command, OPT_host, OPT_database, OPT_debug, OPT_return_found_rows,
1032 OPT_ssl_key, OPT_ssl_cert, OPT_ssl_ca, OPT_ssl_capath,
1033 OPT_character_sets_dir, OPT_default_character_set, OPT_interactive_timeout,
1034 OPT_connect_timeout, OPT_local_infile, OPT_disable_local_infile,
1035 OPT_ssl_cipher, OPT_max_allowed_packet, OPT_protocol, OPT_shared_memory_base_name,
1036 OPT_multi_results, OPT_multi_statements, OPT_multi_queries, OPT_secure_auth,
1037 OPT_report_data_truncation, OPT_plugin_dir, OPT_default_auth,
1038 OPT_bind_address, OPT_ssl_crl, OPT_ssl_crlpath, OPT_enable_cleartext_plugin,
1039 OPT_keep_this_one_last
1042 static TYPELIB option_types={array_elements(default_options)-1,
1043 "options",default_options, NULL};
1045 const char *sql_protocol_names_lib[] =
1046 {
"TCP",
"SOCKET",
"PIPE",
"MEMORY", NullS };
1047 TYPELIB sql_protocol_typelib = {array_elements(sql_protocol_names_lib)-1,
"",
1048 sql_protocol_names_lib, NULL};
1050 static int add_init_command(
struct st_mysql_options *options,
const char *cmd)
1054 if (!options->init_commands)
1058 init_dynamic_array(options->init_commands,
sizeof(
char*),0,5);
1061 if (!(tmp= my_strdup(cmd,MYF(MY_WME))) ||
1062 insert_dynamic(options->init_commands, &tmp))
1071 #define ALLOCATE_EXTENSIONS(OPTS) \
1072 (OPTS)->extension= (struct st_mysql_options_extention *) \
1073 my_malloc(sizeof(struct st_mysql_options_extention), \
1074 MYF(MY_WME | MY_ZEROFILL)) \
1076 #define ENSURE_EXTENSIONS_PRESENT(OPTS) \
1078 if (!(OPTS)->extension) \
1079 ALLOCATE_EXTENSIONS(OPTS); \
1083 #define EXTENSION_SET_STRING(OPTS, X, STR) \
1085 if ((OPTS)->extension) \
1086 my_free((OPTS)->extension->X); \
1088 ALLOCATE_EXTENSIONS(OPTS); \
1089 (OPTS)->extension->X= ((STR) != NULL) ? \
1090 my_strdup((STR), MYF(MY_WME)) : NULL; \
1093 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
1094 #define SET_SSL_OPTION(opt_var,arg) \
1095 if (mysql->options.opt_var) \
1096 my_free(mysql->options.opt_var); \
1097 mysql->options.opt_var= arg ? my_strdup(arg, MYF(MY_WME)) : NULL; \
1098 if (mysql->options.opt_var) \
1099 mysql->options.use_ssl= 1
1100 #define EXTENSION_SET_SSL_STRING(OPTS, X, STR) \
1101 EXTENSION_SET_STRING(OPTS, X, STR); \
1102 if ((OPTS)->extension->X) \
1107 #define SET_SSL_OPTION(opt_var,arg) \
1111 #define EXTENSION_SET_SSL_STRING(OPTS, X, STR) \
1118 const char *filename,
const char *
group)
1121 char *argv_buff[1],**argv;
1122 const char *groups[3];
1123 DBUG_ENTER(
"mysql_read_default_options");
1124 DBUG_PRINT(
"enter",(
"file: %s group: %s",filename,group ? group :
"NULL"));
1126 compile_time_assert(OPT_keep_this_one_last ==
1127 array_elements(default_options));
1129 argc=1; argv=argv_buff; argv_buff[0]= (
char*)
"client";
1130 groups[0]= (
char*)
"client"; groups[1]= (
char*) group; groups[2]=0;
1132 my_load_defaults(filename, groups, &argc, &argv, NULL);
1138 if (my_getopt_is_args_separator(option[0]))
1141 if (option[0][0] ==
'-' && option[0][1] ==
'-')
1143 char *end=strcend(*option,
'=');
1151 for (end= *option ; *(end= strcend(end,
'_')) ; )
1153 switch (find_type(*option + 2, &option_types, FIND_TYPE_BASIC)) {
1156 options->port=atoi(opt_arg);
1161 my_free(options->unix_socket);
1162 options->unix_socket=my_strdup(opt_arg,MYF(MY_WME));
1166 options->compress=1;
1167 options->client_flag|= CLIENT_COMPRESS;
1172 my_free(options->password);
1173 options->password=my_strdup(opt_arg,MYF(MY_WME));
1177 options->protocol = MYSQL_PROTOCOL_PIPE;
1178 case OPT_connect_timeout:
1181 options->connect_timeout=atoi(opt_arg);
1186 my_free(options->user);
1187 options->user=my_strdup(opt_arg,MYF(MY_WME));
1190 case OPT_init_command:
1191 add_init_command(options,opt_arg);
1196 my_free(options->host);
1197 options->host=my_strdup(opt_arg,MYF(MY_WME));
1203 my_free(options->db);
1204 options->db=my_strdup(opt_arg,MYF(MY_WME));
1209 mysql_debug(opt_arg ? opt_arg :
"d:t:o,/tmp/client.trace");
1212 case OPT_return_found_rows:
1213 options->client_flag|=CLIENT_FOUND_ROWS;
1215 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
1217 my_free(options->ssl_key);
1218 options->ssl_key = my_strdup(opt_arg, MYF(MY_WME));
1221 my_free(options->ssl_cert);
1222 options->ssl_cert = my_strdup(opt_arg, MYF(MY_WME));
1225 my_free(options->ssl_ca);
1226 options->ssl_ca = my_strdup(opt_arg, MYF(MY_WME));
1228 case OPT_ssl_capath:
1229 my_free(options->ssl_capath);
1230 options->ssl_capath = my_strdup(opt_arg, MYF(MY_WME));
1232 case OPT_ssl_cipher:
1233 my_free(options->ssl_cipher);
1234 options->ssl_cipher= my_strdup(opt_arg, MYF(MY_WME));
1237 EXTENSION_SET_SSL_STRING(options, ssl_crl, opt_arg);
1239 case OPT_ssl_crlpath:
1240 EXTENSION_SET_SSL_STRING(options, ssl_crlpath, opt_arg);
1246 case OPT_ssl_capath:
1247 case OPT_ssl_cipher:
1249 case OPT_ssl_crlpath:
1252 case OPT_character_sets_dir:
1253 my_free(options->charset_dir);
1254 options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
1256 case OPT_default_character_set:
1257 my_free(options->charset_name);
1258 options->charset_name = my_strdup(opt_arg, MYF(MY_WME));
1260 case OPT_interactive_timeout:
1261 options->client_flag|= CLIENT_INTERACTIVE;
1263 case OPT_local_infile:
1264 if (!opt_arg || atoi(opt_arg) != 0)
1265 options->client_flag|= CLIENT_LOCAL_FILES;
1267 options->client_flag&= ~CLIENT_LOCAL_FILES;
1269 case OPT_disable_local_infile:
1270 options->client_flag&= ~CLIENT_LOCAL_FILES;
1272 case OPT_max_allowed_packet:
1274 options->max_allowed_packet= atoi(opt_arg);
1277 if ((options->protocol= find_type(opt_arg, &sql_protocol_typelib,
1278 FIND_TYPE_BASIC)) <= 0)
1280 fprintf(stderr,
"Unknown option to protocol: %s\n", opt_arg);
1284 case OPT_shared_memory_base_name:
1286 if (options->shared_memory_base_name != def_shared_memory_base_name)
1287 my_free(options->shared_memory_base_name);
1288 options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
1291 case OPT_multi_results:
1292 options->client_flag|= CLIENT_MULTI_RESULTS;
1294 case OPT_multi_statements:
1295 case OPT_multi_queries:
1296 options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
1298 case OPT_secure_auth:
1299 options->secure_auth= TRUE;
1301 case OPT_report_data_truncation:
1302 options->report_data_truncation= opt_arg ?
test(atoi(opt_arg)) : 1;
1304 case OPT_plugin_dir:
1306 char buff[FN_REFLEN], buff2[FN_REFLEN];
1307 if (strlen(opt_arg) >= FN_REFLEN)
1308 opt_arg[FN_REFLEN]=
'\0';
1309 if (my_realpath(buff, opt_arg, 0))
1311 DBUG_PRINT(
"warning",(
"failed to normalize the plugin path: %s",
1315 convert_dirname(buff2, buff, NULL);
1316 EXTENSION_SET_STRING(options, plugin_dir, buff2);
1319 case OPT_default_auth:
1320 EXTENSION_SET_STRING(options, default_auth, opt_arg);
1322 case OPT_bind_address:
1323 my_free(options->ci.bind_address);
1324 options->ci.bind_address= my_strdup(opt_arg, MYF(MY_WME));
1326 case OPT_enable_cleartext_plugin:
1327 ENSURE_EXTENSIONS_PRESENT(options);
1328 options->extension->enable_cleartext_plugin=
1329 (!opt_arg || atoi(opt_arg) != 0) ? TRUE : FALSE;
1333 DBUG_PRINT(
"warning",(
"unknown option: %s",option[0]));
1338 free_defaults(argv);
1349 static void cli_fetch_lengths(ulong *
to, MYSQL_ROW column,
1350 unsigned int field_count)
1357 for (end=column + field_count + 1 ; column != end ; column++, to++)
1365 *prev_length= (ulong) (*column-start-1);
1377 my_bool default_value, uint server_capabilities)
1382 DBUG_ENTER(
"unpack_fields");
1385 (uint)
sizeof(*field)*fields);
1389 set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
1393 if (server_capabilities & CLIENT_PROTOCOL_41)
1396 for (row=data->data; row ; row = row->next,field++)
1400 DBUG_ASSERT((uint) (field - result) < fields);
1401 cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7);
1402 field->catalog= strmake_root(alloc,(
char*) row->data[0], lengths[0]);
1403 field->db= strmake_root(alloc,(
char*) row->data[1], lengths[1]);
1404 field->table= strmake_root(alloc,(
char*) row->data[2], lengths[2]);
1405 field->org_table= strmake_root(alloc,(
char*) row->data[3], lengths[3]);
1406 field->name= strmake_root(alloc,(
char*) row->data[4], lengths[4]);
1407 field->org_name= strmake_root(alloc,(
char*) row->data[5], lengths[5]);
1409 field->catalog_length= lengths[0];
1410 field->db_length= lengths[1];
1411 field->table_length= lengths[2];
1412 field->org_table_length= lengths[3];
1413 field->name_length= lengths[4];
1414 field->org_name_length= lengths[5];
1417 if (lengths[6] != 12)
1421 set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
1425 pos= (uchar*) row->data[6];
1426 field->charsetnr= uint2korr(pos);
1427 field->length= (uint) uint4korr(pos+2);
1428 field->type= (
enum enum_field_types) pos[6];
1429 field->flags= uint2korr(pos+7);
1430 field->decimals= (uint) pos[9];
1432 if (IS_NUM(field->type))
1433 field->flags|= NUM_FLAG;
1434 if (default_value && row->data[7])
1436 field->def=strmake_root(alloc,(
char*) row->data[7], lengths[7]);
1437 field->def_length= lengths[7];
1441 field->max_length= 0;
1444 #ifndef DELETE_SUPPORT_OF_4_0_PROTOCOL
1448 for (row=data->data; row ; row = row->next,field++)
1450 cli_fetch_lengths(&lengths[0], row->data, default_value ? 6 : 5);
1451 field->org_table= field->table= strdup_root(alloc,(
char*) row->data[0]);
1452 field->name= strdup_root(alloc,(
char*) row->data[1]);
1453 field->length= (uint) uint3korr(row->data[2]);
1454 field->type= (
enum enum_field_types) (uchar) row->data[3][0];
1456 field->catalog=(
char*)
"";
1457 field->db= (
char*)
"";
1458 field->catalog_length= 0;
1459 field->db_length= 0;
1460 field->org_table_length= field->table_length= lengths[0];
1461 field->name_length= lengths[1];
1463 if (server_capabilities & CLIENT_LONG_FLAG)
1465 field->flags= uint2korr(row->data[4]);
1466 field->decimals=(uint) (uchar) row->data[4][2];
1470 field->flags= (uint) (uchar) row->data[4][0];
1471 field->decimals=(uint) (uchar) row->data[4][1];
1473 if (IS_NUM(field->type))
1474 field->flags|= NUM_FLAG;
1475 if (default_value && row->data[5])
1477 field->def=strdup_root(alloc,(
char*) row->data[5]);
1478 field->def_length= lengths[5];
1482 field->max_length= 0;
1487 DBUG_RETURN(result);
1493 unsigned int fields)
1502 NET *net = &mysql->net;
1503 DBUG_ENTER(
"cli_read_rows");
1505 if ((pkt_len= cli_safe_read(mysql)) == packet_error)
1508 MYF(MY_WME | MY_ZEROFILL))))
1510 set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
1513 init_alloc_root(&result->alloc,8192,0);
1515 prev_ptr= &result->data;
1517 result->fields=fields;
1527 while (*(cp=net->read_pos) != 254 || pkt_len >= 8)
1530 if (!(cur= (
MYSQL_ROWS*) alloc_root(&result->alloc,
1532 !(cur->data= ((MYSQL_ROW)
1533 alloc_root(&result->alloc,
1534 (fields+1)*
sizeof(
char *)+pkt_len))))
1537 set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
1541 prev_ptr= &cur->next;
1542 to= (
char*) (cur->data+fields+1);
1543 end_to=to+pkt_len-1;
1544 for (field=0 ; field < fields ; field++)
1546 if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH)
1548 cur->data[field] = 0;
1552 cur->data[field] =
to;
1553 if (len > (ulong) (end_to -
to))
1556 set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
1559 memcpy(to,(
char*) cp,len); to[len]=0;
1564 if (mysql_fields[field].max_length < len)
1565 mysql_fields[field].max_length=len;
1569 cur->data[field]=
to;
1570 if ((pkt_len=cli_safe_read(mysql)) == packet_error)
1579 mysql->warning_count= uint2korr(cp+1);
1580 mysql->server_status= uint2korr(cp+3);
1581 DBUG_PRINT(
"info",(
"status: %u warning_count: %u",
1582 mysql->server_status, mysql->warning_count));
1584 DBUG_PRINT(
"exit", (
"Got %lu rows", (ulong) result->rows));
1585 DBUG_RETURN(result);
1595 read_one_row(
MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
1599 uchar *pos, *prev_pos, *end_pos;
1600 NET *net= &mysql->net;
1602 if ((pkt_len=cli_safe_read(mysql)) == packet_error)
1604 if (pkt_len <= 8 && net->read_pos[0] == 254)
1608 mysql->warning_count= uint2korr(net->read_pos+1);
1609 mysql->server_status= uint2korr(net->read_pos+3);
1615 end_pos=pos+pkt_len;
1616 for (field=0 ; field < fields ; field++)
1618 if ((len=(ulong) net_field_length(&pos)) == NULL_LENGTH)
1625 if (len > (ulong) (end_pos - pos))
1627 set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
1630 row[field] = (
char*) pos;
1638 row[field]=(
char*) prev_pos+1;
1649 mysql_init(
MYSQL *mysql)
1651 if (mysql_server_init(0, NULL, NULL))
1655 if (!(mysql=(
MYSQL*) my_malloc(
sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL))))
1657 set_mysql_error(NULL, CR_OUT_OF_MEMORY, unknown_sqlstate);
1663 memset(mysql, 0,
sizeof(*(mysql)));
1664 mysql->charset=default_client_charset_info;
1665 strmov(mysql->net.
sqlstate, not_error_sqlstate);
1672 #if defined(ENABLED_LOCAL_INFILE) && !defined(MYSQL_SERVER)
1673 mysql->options.client_flag|= CLIENT_LOCAL_FILES;
1677 mysql->options.shared_memory_base_name= (
char*) def_shared_memory_base_name;
1680 mysql->options.methods_to_use= MYSQL_OPT_GUESS_CONNECTION;
1681 mysql->options.report_data_truncation= TRUE;
1698 mysql->reconnect= 0;
1700 mysql->options.secure_auth= TRUE;
1711 #define strdup_if_not_null(A) (A) == 0 ? 0 : my_strdup((A),MYF(MY_WME))
1714 mysql_ssl_set(
MYSQL *mysql __attribute__((unused)) ,
1715 const char *key __attribute__((unused)),
1716 const char *cert __attribute__((unused)),
1717 const char *ca __attribute__((unused)),
1718 const char *capath __attribute__((unused)),
1719 const char *cipher __attribute__((unused)))
1722 DBUG_ENTER(
"mysql_ssl_set");
1723 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
1725 mysql_options(mysql, MYSQL_OPT_SSL_KEY, key) +
1726 mysql_options(mysql, MYSQL_OPT_SSL_CERT, cert) +
1727 mysql_options(mysql, MYSQL_OPT_SSL_CA, ca) +
1728 mysql_options(mysql, MYSQL_OPT_SSL_CAPATH, capath) +
1729 mysql_options(mysql, MYSQL_OPT_SSL_CIPHER, cipher)
1732 DBUG_RETURN(result);
1741 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
1744 mysql_ssl_free(
MYSQL *mysql __attribute__((unused)))
1746 struct st_VioSSLFd *ssl_fd= (
struct st_VioSSLFd*) mysql->connector_fd;
1747 DBUG_ENTER(
"mysql_ssl_free");
1749 my_free(mysql->options.ssl_key);
1750 my_free(mysql->options.ssl_cert);
1751 my_free(mysql->options.ssl_ca);
1752 my_free(mysql->options.ssl_capath);
1753 my_free(mysql->options.ssl_cipher);
1754 if (mysql->options.extension)
1756 my_free(mysql->options.extension->ssl_crl);
1757 my_free(mysql->options.extension->ssl_crlpath);
1760 SSL_CTX_free(ssl_fd->ssl_context);
1761 my_free(mysql->connector_fd);
1762 mysql->options.ssl_key = 0;
1763 mysql->options.ssl_cert = 0;
1764 mysql->options.ssl_ca = 0;
1765 mysql->options.ssl_capath = 0;
1766 mysql->options.ssl_cipher= 0;
1767 if (mysql->options.extension)
1769 mysql->options.extension->ssl_crl = 0;
1770 mysql->options.extension->ssl_crlpath = 0;
1772 mysql->options.use_ssl = FALSE;
1773 mysql->connector_fd = 0;
1789 const char * STDCALL
1790 mysql_get_ssl_cipher(
MYSQL *mysql __attribute__((unused)))
1792 DBUG_ENTER(
"mysql_get_ssl_cipher");
1793 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
1794 if (mysql->net.vio && mysql->net.vio->ssl_arg)
1795 DBUG_RETURN(SSL_get_cipher_name((SSL*)mysql->net.vio->ssl_arg));
1818 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
1820 static int ssl_verify_server_cert(
Vio *vio,
const char* server_hostname,
const char **errptr)
1826 DBUG_ENTER(
"ssl_verify_server_cert");
1827 DBUG_PRINT(
"enter", (
"server_hostname: %s", server_hostname));
1829 if (!(ssl= (SSL*)vio->ssl_arg))
1831 *errptr=
"No SSL pointer found";
1835 if (!server_hostname)
1837 *errptr=
"No server hostname supplied";
1841 if (!(server_cert= SSL_get_peer_certificate(ssl)))
1843 *errptr=
"Could not get server certificate";
1853 X509_NAME_oneline(X509_get_subject_name(server_cert), buf,
sizeof(buf));
1854 X509_free (server_cert);
1856 DBUG_PRINT(
"info", (
"hostname in cert: %s", buf));
1857 cp1= strstr(buf,
"/CN=");
1862 cp2= strchr(cp1,
'/');
1865 DBUG_PRINT(
"info", (
"Server hostname in cert: %s", cp1));
1866 if (!strcmp(cp1, server_hostname))
1872 *errptr=
"SSL certificate validation failure";
1884 static my_bool cli_read_query_result(
MYSQL *mysql);
1887 int cli_read_change_user_result(
MYSQL *mysql)
1889 return cli_safe_read(mysql);
1894 cli_read_query_result,
1895 cli_advanced_command,
1899 cli_flush_use_result,
1900 cli_read_change_user_result
1901 #ifndef MYSQL_SERVER
1903 cli_read_prepare_result,
1905 cli_read_binary_rows,
1906 cli_unbuffered_fetch,
1908 cli_read_statistics,
1909 cli_read_query_result,
1910 cli_read_binary_rows
1916 typedef enum my_cs_match_type_enum
1931 const char *os_name;
1932 const char *my_name;
1933 my_cs_match_type param;
1939 {
"cp437",
"cp850", my_cs_approx},
1940 {
"cp850",
"cp850", my_cs_exact},
1941 {
"cp852",
"cp852", my_cs_exact},
1942 {
"cp858",
"cp850", my_cs_approx},
1943 {
"cp866",
"cp866", my_cs_exact},
1944 {
"cp874",
"tis620", my_cs_approx},
1945 {
"cp932",
"cp932", my_cs_exact},
1946 {
"cp936",
"gbk", my_cs_approx},
1947 {
"cp949",
"euckr", my_cs_approx},
1948 {
"cp950",
"big5", my_cs_exact},
1949 {
"cp1200",
"utf16le", my_cs_unsupp},
1950 {
"cp1201",
"utf16", my_cs_unsupp},
1951 {
"cp1250",
"cp1250", my_cs_exact},
1952 {
"cp1251",
"cp1251", my_cs_exact},
1953 {
"cp1252",
"latin1", my_cs_exact},
1954 {
"cp1253",
"greek", my_cs_exact},
1955 {
"cp1254",
"latin5", my_cs_exact},
1956 {
"cp1255",
"hebrew", my_cs_approx},
1957 {
"cp1256",
"cp1256", my_cs_exact},
1958 {
"cp1257",
"cp1257", my_cs_exact},
1959 {
"cp10000",
"macroman", my_cs_exact},
1960 {
"cp10001",
"sjis", my_cs_approx},
1961 {
"cp10002",
"big5", my_cs_approx},
1962 {
"cp10008",
"gb2312", my_cs_approx},
1963 {
"cp10021",
"tis620", my_cs_approx},
1964 {
"cp10029",
"macce", my_cs_exact},
1965 {
"cp12001",
"utf32", my_cs_unsupp},
1966 {
"cp20107",
"swe7", my_cs_exact},
1967 {
"cp20127",
"latin1", my_cs_approx},
1968 {
"cp20866",
"koi8r", my_cs_exact},
1969 {
"cp20932",
"ujis", my_cs_exact},
1970 {
"cp20936",
"gb2312", my_cs_approx},
1971 {
"cp20949",
"euckr", my_cs_approx},
1972 {
"cp21866",
"koi8u", my_cs_exact},
1973 {
"cp28591",
"latin1", my_cs_approx},
1974 {
"cp28592",
"latin2", my_cs_exact},
1975 {
"cp28597",
"greek", my_cs_exact},
1976 {
"cp28598",
"hebrew", my_cs_exact},
1977 {
"cp28599",
"latin5", my_cs_exact},
1978 {
"cp28603",
"latin7", my_cs_exact},
1979 #ifdef UNCOMMENT_THIS_WHEN_WL_4579_IS_DONE
1980 {
"cp28605",
"latin9", my_cs_exact},
1982 {
"cp38598",
"hebrew", my_cs_exact},
1983 {
"cp51932",
"ujis", my_cs_exact},
1984 {
"cp51936",
"gb2312", my_cs_exact},
1985 {
"cp51949",
"euckr", my_cs_exact},
1986 {
"cp51950",
"big5", my_cs_exact},
1987 #ifdef UNCOMMENT_THIS_WHEN_WL_WL_4024_IS_DONE
1988 {
"cp54936",
"gb18030", my_cs_exact},
1990 {
"cp65001",
"utf8", my_cs_exact},
1994 {
"646",
"latin1", my_cs_approx},
1995 {
"ANSI_X3.4-1968",
"latin1", my_cs_approx},
1996 {
"ansi1251",
"cp1251", my_cs_exact},
1997 {
"armscii8",
"armscii8", my_cs_exact},
1998 {
"armscii-8",
"armscii8", my_cs_exact},
1999 {
"ASCII",
"latin1", my_cs_approx},
2000 {
"Big5",
"big5", my_cs_exact},
2001 {
"cp1251",
"cp1251", my_cs_exact},
2002 {
"cp1255",
"hebrew", my_cs_approx},
2003 {
"CP866",
"cp866", my_cs_exact},
2004 {
"eucCN",
"gb2312", my_cs_exact},
2005 {
"euc-CN",
"gb2312", my_cs_exact},
2006 {
"eucJP",
"ujis", my_cs_exact},
2007 {
"euc-JP",
"ujis", my_cs_exact},
2008 {
"eucKR",
"euckr", my_cs_exact},
2009 {
"euc-KR",
"euckr", my_cs_exact},
2010 #ifdef UNCOMMENT_THIS_WHEN_WL_WL_4024_IS_DONE
2011 {
"gb18030",
"gb18030", my_cs_exact},
2013 {
"gb2312",
"gb2312", my_cs_exact},
2014 {
"gbk",
"gbk", my_cs_exact},
2015 {
"georgianps",
"geostd8", my_cs_exact},
2016 {
"georgian-ps",
"geostd8", my_cs_exact},
2017 {
"IBM-1252",
"cp1252", my_cs_exact},
2019 {
"iso88591",
"latin1", my_cs_approx},
2020 {
"ISO_8859-1",
"latin1", my_cs_approx},
2021 {
"ISO8859-1",
"latin1", my_cs_approx},
2022 {
"ISO-8859-1",
"latin1", my_cs_approx},
2024 {
"iso885913",
"latin7", my_cs_exact},
2025 {
"ISO_8859-13",
"latin7", my_cs_exact},
2026 {
"ISO8859-13",
"latin7", my_cs_exact},
2027 {
"ISO-8859-13",
"latin7", my_cs_exact},
2029 #ifdef UNCOMMENT_THIS_WHEN_WL_4579_IS_DONE
2030 {
"iso885915",
"latin9", my_cs_exact},
2031 {
"ISO_8859-15",
"latin9", my_cs_exact},
2032 {
"ISO8859-15",
"latin9", my_cs_exact},
2033 {
"ISO-8859-15",
"latin9", my_cs_exact},
2036 {
"iso88592",
"latin2", my_cs_exact},
2037 {
"ISO_8859-2",
"latin2", my_cs_exact},
2038 {
"ISO8859-2",
"latin2", my_cs_exact},
2039 {
"ISO-8859-2",
"latin2", my_cs_exact},
2041 {
"iso88597",
"greek", my_cs_exact},
2042 {
"ISO_8859-7",
"greek", my_cs_exact},
2043 {
"ISO8859-7",
"greek", my_cs_exact},
2044 {
"ISO-8859-7",
"greek", my_cs_exact},
2046 {
"iso88598",
"hebrew", my_cs_exact},
2047 {
"ISO_8859-8",
"hebrew", my_cs_exact},
2048 {
"ISO8859-8",
"hebrew", my_cs_exact},
2049 {
"ISO-8859-8",
"hebrew", my_cs_exact},
2051 {
"iso88599",
"latin5", my_cs_exact},
2052 {
"ISO_8859-9",
"latin5", my_cs_exact},
2053 {
"ISO8859-9",
"latin5", my_cs_exact},
2054 {
"ISO-8859-9",
"latin5", my_cs_exact},
2056 {
"koi8r",
"koi8r", my_cs_exact},
2057 {
"KOI8-R",
"koi8r", my_cs_exact},
2058 {
"koi8u",
"koi8u", my_cs_exact},
2059 {
"KOI8-U",
"koi8u", my_cs_exact},
2061 {
"roman8",
"hp8", my_cs_exact},
2063 {
"Shift_JIS",
"sjis", my_cs_exact},
2064 {
"SJIS",
"sjis", my_cs_exact},
2065 {
"shiftjisx0213",
"sjis", my_cs_exact},
2067 {
"tis620",
"tis620", my_cs_exact},
2068 {
"tis-620",
"tis620", my_cs_exact},
2070 {
"ujis",
"ujis", my_cs_exact},
2072 {
"US-ASCII",
"latin1", my_cs_approx},
2074 {
"utf8",
"utf8", my_cs_exact},
2075 {
"utf-8",
"utf8", my_cs_exact},
2082 my_os_charset_to_mysql_charset(
const char *csname)
2085 for (csp= charsets; csp->os_name; csp++)
2087 if (!my_strcasecmp(&my_charset_latin1, csp->os_name, csname))
2092 return csp->my_name;
2099 return csp->my_name;
2102 my_printf_error(ER_UNKNOWN_ERROR,
2103 "OS character set '%s'"
2104 " is not supported by MySQL client",
2105 MYF(0), csp->my_name);
2111 my_printf_error(ER_UNKNOWN_ERROR,
2112 "Unknown OS character set '%s'.",
2116 csname= MYSQL_DEFAULT_CHARSET_NAME;
2117 my_printf_error(ER_UNKNOWN_ERROR,
2118 "Switching to the default character set '%s'.",
2126 #ifdef HAVE_LANGINFO_H
2127 #include <langinfo.h>
2129 #ifdef HAVE_LOCALE_H
2136 mysql_autodetect_character_set(
MYSQL *mysql)
2138 const char *csname= MYSQL_DEFAULT_CHARSET_NAME;
2143 my_snprintf(cpbuf,
sizeof(cpbuf),
"cp%d", (
int) GetConsoleCP());
2144 csname= my_os_charset_to_mysql_charset(cpbuf);
2146 #elif defined(HAVE_SETLOCALE) && defined(HAVE_NL_LANGINFO)
2148 if (setlocale(LC_CTYPE,
"") && (csname= nl_langinfo(CODESET)))
2149 csname= my_os_charset_to_mysql_charset(csname);
2153 if (mysql->options.charset_name)
2154 my_free(mysql->options.charset_name);
2155 if (!(mysql->options.charset_name= my_strdup(csname, MYF(MY_WME))))
2162 mysql_set_character_set_with_default_collation(
MYSQL *mysql)
2164 const char *save= charsets_dir;
2165 if (mysql->options.charset_dir)
2166 charsets_dir=mysql->options.charset_dir;
2168 if ((mysql->charset= get_charset_by_csname(mysql->options.charset_name,
2169 MY_CS_PRIMARY, MYF(MY_WME))))
2174 get_charset_by_name(MYSQL_DEFAULT_COLLATION_NAME, MYF(MY_WME))) &&
2175 my_charset_same(mysql->charset, collation))
2177 mysql->charset= collation;
2193 int mysql_init_character_set(
MYSQL *mysql)
2196 if (!mysql->options.charset_name)
2198 if (!(mysql->options.charset_name=
2199 my_strdup(MYSQL_DEFAULT_CHARSET_NAME,MYF(MY_WME))))
2202 else if (!strcmp(mysql->options.charset_name,
2203 MYSQL_AUTODETECT_CHARSET_NAME) &&
2204 mysql_autodetect_character_set(mysql))
2207 mysql_set_character_set_with_default_collation(mysql);
2209 if (!mysql->charset)
2211 if (mysql->options.charset_dir)
2212 set_mysql_extended_error(mysql, CR_CANT_READ_CHARSET, unknown_sqlstate,
2213 ER(CR_CANT_READ_CHARSET),
2214 mysql->options.charset_name,
2215 mysql->options.charset_dir);
2218 char cs_dir_name[FN_REFLEN];
2219 get_charsets_dir(cs_dir_name);
2220 set_mysql_extended_error(mysql, CR_CANT_READ_CHARSET, unknown_sqlstate,
2221 ER(CR_CANT_READ_CHARSET),
2222 mysql->options.charset_name,
2234 static int client_mpvio_write_packet(
struct st_plugin_vio*,
const uchar*,
int);
2239 static auth_plugin_t native_password_client_plugin=
2241 MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
2242 MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
2243 native_password_plugin_name,
2244 "R.J.Silk, Sergei Golubchik",
2245 "Native MySQL authentication",
2252 native_password_auth_client
2255 static auth_plugin_t old_password_client_plugin=
2257 MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
2258 MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
2259 old_password_plugin_name,
2260 "R.J.Silk, Sergei Golubchik",
2261 "Old MySQL-3.23 authentication",
2268 old_password_auth_client
2271 static auth_plugin_t clear_password_client_plugin=
2273 MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
2274 MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
2275 "mysql_clear_password",
2277 "Clear password authentication plugin",
2284 clear_password_auth_client
2287 #if defined(HAVE_OPENSSL)
2288 static auth_plugin_t sha256_password_client_plugin=
2290 MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
2291 MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
2294 "SHA256 based authentication with salt",
2298 sha256_password_init,
2299 sha256_password_deinit,
2301 sha256_password_auth_client
2304 #ifdef AUTHENTICATION_WIN
2305 extern auth_plugin_t win_auth_client_plugin;
2313 #
if defined(HAVE_OPENSSL)
2316 #ifdef AUTHENTICATION_WIN
2324 write_length_encoded_string3(uchar *buf,
char *
string,
size_t length)
2326 buf= net_store_length(buf, length);
2327 memcpy(buf,
string, length);
2334 send_client_connect_attrs(
MYSQL *mysql, uchar *buf)
2337 if (mysql->server_capabilities & CLIENT_CONNECT_ATTRS)
2341 buf= net_store_length(buf,
2342 mysql->options.extension ?
2343 mysql->options.extension->connection_attributes_length :
2347 if (mysql->options.extension &&
2348 my_hash_inited(&mysql->options.extension->connection_attributes))
2350 HASH *attrs= &mysql->options.extension->connection_attributes;
2354 for (idx= 0; idx < attrs->records; idx++)
2360 DBUG_ASSERT(key->length);
2362 buf= write_length_encoded_string3(buf, key->str, key->length);
2363 buf= write_length_encoded_string3(buf, value->str, value->length);
2371 static size_t get_length_store_length(
size_t length)
2374 #define MAX_VARIABLE_STRING_LENGTH 9
2375 uchar length_buffer[MAX_VARIABLE_STRING_LENGTH], *ptr;
2377 ptr= net_store_length(length_buffer, length);
2379 return ptr - &length_buffer[0];
2395 } cached_server_reply;
2414 char *write_length_encoded_string4(
char *dest,
char *dest_end,
char *src,
2417 size_t src_len= (size_t)(src_end - src);
2418 uchar *to= net_store_length((uchar*) dest, src_len);
2419 if ((
char*)(to + src_len) >= dest_end)
2421 memcpy(to, src, src_len);
2422 return (
char*)(to + src_len);
2430 char *write_string(
char *dest,
char *dest_end,
char *src,
char *src_end)
2432 size_t src_len= (size_t)(src_end - src);
2436 *dest=(uchar) src_len;
2437 to= (uchar*) dest+1;
2438 if ((
char*)(to + src_len) >= dest_end)
2440 memcpy(to, src, src_len);
2441 return (
char*)(to + src_len);
2462 static int send_change_user_packet(
MCPVIO_EXT *mpvio,
2463 const uchar *data,
int data_len)
2465 MYSQL *mysql= mpvio->mysql;
2468 size_t connect_attrs_len=
2469 (mysql->server_capabilities & CLIENT_CONNECT_ATTRS &&
2470 mysql->options.extension) ?
2471 mysql->options.extension->connection_attributes_length : 0;
2473 buff= my_alloca(USERNAME_LENGTH + data_len + 1 + NAME_LEN + 2 + NAME_LEN +
2474 connect_attrs_len + 9 );
2476 end= strmake(buff, mysql->user, USERNAME_LENGTH) + 1;
2482 if (mysql->client_flag & CLIENT_SECURE_CONNECTION)
2484 DBUG_ASSERT(data_len <= 255);
2487 set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
2494 DBUG_ASSERT(data_len == SCRAMBLE_LENGTH_323 + 1);
2495 DBUG_ASSERT(data[SCRAMBLE_LENGTH_323] == 0);
2497 memcpy(end, data, data_len);
2500 end= strmake(end, mpvio->db ? mpvio->db :
"", NAME_LEN) + 1;
2502 if (mysql->server_capabilities & CLIENT_PROTOCOL_41)
2504 int2store(end, (ushort) mysql->charset->number);
2508 if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
2509 end= strmake(end, mpvio->
plugin->name, NAME_LEN) + 1;
2511 end= (
char *) send_client_connect_attrs(mysql, (uchar *) end);
2513 res= simple_command(mysql, COM_CHANGE_USER,
2514 (uchar*)buff, (ulong)(end-buff), 1);
2522 #define MAX_CONNECTION_ATTR_STORAGE_LENGTH 65536
2554 static int send_client_reply_packet(
MCPVIO_EXT *mpvio,
2555 const uchar *data,
int data_len)
2557 MYSQL *mysql= mpvio->mysql;
2558 NET *net= &mysql->net;
2561 size_t connect_attrs_len=
2562 (mysql->server_capabilities & CLIENT_CONNECT_ATTRS &&
2563 mysql->options.extension) ?
2564 mysql->options.extension->connection_attributes_length : 0;
2566 DBUG_ASSERT(connect_attrs_len < MAX_CONNECTION_ATTR_STORAGE_LENGTH);
2573 buff_size= 33 + USERNAME_LENGTH + data_len + 9 + NAME_LEN + NAME_LEN + connect_attrs_len + 9;
2574 buff= my_alloca(buff_size);
2576 mysql->client_flag|= mysql->options.client_flag;
2577 mysql->client_flag|= CLIENT_CAPABILITIES;
2579 if (mysql->client_flag & CLIENT_MULTI_STATEMENTS)
2580 mysql->client_flag|= CLIENT_MULTI_RESULTS;
2582 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
2583 if (mysql->options.ssl_key || mysql->options.ssl_cert ||
2584 mysql->options.ssl_ca || mysql->options.ssl_capath ||
2585 mysql->options.ssl_cipher ||
2586 (mysql->options.extension && mysql->options.extension->ssl_crl) ||
2587 (mysql->options.extension && mysql->options.extension->ssl_crlpath))
2588 mysql->options.use_ssl= 1;
2589 if (mysql->options.use_ssl)
2590 mysql->client_flag|= CLIENT_SSL;
2593 mysql->client_flag|= CLIENT_CONNECT_WITH_DB;
2596 mysql->client_flag= mysql->client_flag &
2597 (~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)
2598 | mysql->server_capabilities);
2600 #ifndef HAVE_COMPRESS
2601 mysql->client_flag&= ~CLIENT_COMPRESS;
2604 if (mysql->client_flag & CLIENT_PROTOCOL_41)
2607 int4store(buff,mysql->client_flag);
2608 int4store(buff+4, net->max_packet_size);
2609 buff[8]= (char) mysql->charset->number;
2610 memset(buff+9, 0, 32-9);
2615 int2store(buff, mysql->client_flag);
2616 int3store(buff+2, net->max_packet_size);
2620 if (mysql->client_flag & CLIENT_SSL)
2624 struct st_VioSSLFd *ssl_fd;
2625 enum enum_ssl_init_error ssl_init_error;
2626 const char *cert_error;
2627 unsigned long ssl_error;
2635 set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2636 ER(CR_SERVER_LOST_EXTENDED),
2637 "sending connection information to server",
2643 if (!(ssl_fd= new_VioSSLConnectorFd(options->ssl_key,
2646 options->ssl_capath,
2647 options->ssl_cipher,
2649 options->extension ?
2650 options->extension->ssl_crl : NULL,
2651 options->extension ?
2652 options->extension->ssl_crlpath : NULL)))
2654 set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate,
2655 ER(CR_SSL_CONNECTION_ERROR), sslGetErrString(ssl_init_error));
2658 mysql->connector_fd= (
unsigned char *) ssl_fd;
2661 DBUG_PRINT(
"info", (
"IO layer change in progress..."));
2662 if (sslconnect(ssl_fd, net->vio,
2663 (
long) (mysql->options.connect_timeout), &ssl_error))
2666 ERR_error_string_n(ssl_error, buf, 512);
2668 set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate,
2669 ER(CR_SSL_CONNECTION_ERROR),
2673 DBUG_PRINT(
"info", (
"IO layer change done!"));
2676 if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
2677 ssl_verify_server_cert(net->vio, mysql->host, &cert_error))
2679 set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate,
2680 ER(CR_SSL_CONNECTION_ERROR), cert_error);
2686 DBUG_PRINT(
"info",(
"Server version = '%s' capabilites: %lu status: %u client_flag: %lu",
2687 mysql->server_version, mysql->server_capabilities,
2688 mysql->server_status, mysql->client_flag));
2694 strmake(end, mysql->user, USERNAME_LENGTH);
2696 read_user_name(end);
2699 DBUG_PRINT(
"info",(
"user: %s",end));
2700 end= strend(end) + 1;
2703 if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
2713 if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA)
2714 end= write_length_encoded_string4(end, (
char *)(buff + buff_size),
2716 (
char *)(data + data_len));
2718 end= write_string(end, (
char *)(buff + buff_size),
2720 (
char *)(data + data_len));
2726 DBUG_ASSERT(data_len == SCRAMBLE_LENGTH_323 + 1);
2727 memcpy(end, data, data_len);
2735 if (mpvio->db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
2737 end= strmake(end, mpvio->db, NAME_LEN) + 1;
2738 mysql->db= my_strdup(mpvio->db, MYF(MY_WME));
2741 if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
2742 end= strmake(end, mpvio->
plugin->name, NAME_LEN) + 1;
2744 end= (
char *) send_client_connect_attrs(mysql, (uchar *) end);
2749 set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2750 ER(CR_SERVER_LOST_EXTENDED),
2751 "sending authentication information",
2769 static int client_mpvio_read_packet(
struct st_plugin_vio *mpv, uchar **buf)
2772 MYSQL *mysql= mpvio->mysql;
2776 if (mpvio->cached_server_reply.
pkt)
2778 *buf= mpvio->cached_server_reply.
pkt;
2779 mpvio->cached_server_reply.
pkt= 0;
2780 mpvio->packets_read++;
2781 return mpvio->cached_server_reply.pkt_len;
2784 if (mpvio->packets_read == 0)
2792 if (client_mpvio_write_packet(mpv, 0, 0))
2793 return (
int)packet_error;
2797 pkt_len= (*mysql->methods->read_change_user_result)(mysql);
2799 *buf= mysql->net.read_pos;
2803 return (
int)packet_error;
2812 if (pkt_len && **buf == 1)
2817 mpvio->packets_read++;
2830 static int client_mpvio_write_packet(
struct st_plugin_vio *mpv,
2831 const uchar *pkt,
int pkt_len)
2839 res= send_change_user_packet(mpvio, pkt, pkt_len);
2841 res= send_client_reply_packet(mpvio, pkt, pkt_len);
2845 NET *net= &mpvio->mysql->net;
2846 if (mpvio->mysql->thd)
2851 set_mysql_extended_error(mpvio->mysql, CR_SERVER_LOST, unknown_sqlstate,
2852 ER(CR_SERVER_LOST_EXTENDED),
2853 "sending authentication information",
2866 memset(info, 0,
sizeof(*info));
2867 switch (vio->type) {
2868 case VIO_TYPE_TCPIP:
2869 info->protocol= MYSQL_VIO_TCP;
2870 info->
socket= vio_fd(vio);
2872 case VIO_TYPE_SOCKET:
2873 info->protocol= MYSQL_VIO_SOCKET;
2874 info->
socket= vio_fd(vio);
2878 struct sockaddr addr;
2879 socklen_t addrlen=
sizeof(addr);
2880 if (getsockname(vio_fd(vio), &addr, &addrlen))
2882 info->protocol= addr.sa_family == AF_UNIX ?
2883 MYSQL_VIO_SOCKET : MYSQL_VIO_TCP;
2884 info->
socket= vio_fd(vio);
2888 case VIO_TYPE_NAMEDPIPE:
2889 info->protocol= MYSQL_VIO_PIPE;
2890 info->handle= vio->hPipe;
2893 case VIO_TYPE_SHARED_MEMORY:
2894 info->protocol= MYSQL_VIO_MEMORY;
2895 info->handle= vio->handle_file_map;
2899 default: DBUG_ASSERT(0);
2907 mpvio_info(mpvio->mysql->net.vio, info);
2911 my_bool libmysql_cleartext_plugin_enabled= 0;
2913 static my_bool check_plugin_enabled(
MYSQL *mysql, auth_plugin_t *plugin)
2915 if (plugin == &clear_password_client_plugin &&
2916 (!libmysql_cleartext_plugin_enabled &&
2917 (!mysql->options.extension ||
2918 !mysql->options.extension->enable_cleartext_plugin)))
2920 set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD,
2922 ER(CR_AUTH_PLUGIN_CANNOT_LOAD),
2923 clear_password_client_plugin.name,
2924 "plugin not enabled");
2947 int run_plugin_auth(
MYSQL *mysql,
char *data, uint data_len,
2948 const char *data_plugin,
const char *db)
2950 const char *auth_plugin_name;
2951 auth_plugin_t *auth_plugin;
2956 DBUG_ENTER (
"run_plugin_auth");
2958 if (mysql->options.extension && mysql->options.extension->default_auth &&
2959 mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
2961 auth_plugin_name= mysql->options.extension->default_auth;
2963 auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
2968 auth_plugin= mysql->server_capabilities & CLIENT_PROTOCOL_41 ?
2969 &native_password_client_plugin : &old_password_client_plugin;
2970 auth_plugin_name= auth_plugin->name;
2973 if (check_plugin_enabled(mysql, auth_plugin))
2976 DBUG_PRINT (
"info", (
"using plugin %s", auth_plugin_name));
2978 mysql->net.last_errno= 0;
2980 if (data_plugin && strcmp(data_plugin, auth_plugin_name))
2988 mpvio.cached_server_reply.
pkt= (uchar*)data;
2989 mpvio.cached_server_reply.pkt_len= data_len;
2990 mpvio.read_packet= client_mpvio_read_packet;
2991 mpvio.write_packet= client_mpvio_write_packet;
2992 mpvio.info= client_mpvio_info;
2996 mpvio.
plugin= auth_plugin;
2998 res= auth_plugin->authenticate_user((
struct st_plugin_vio *)&mpvio, mysql);
2999 DBUG_PRINT (
"info", (
"authenticate_user returned %s",
3000 res ==
CR_OK ?
"CR_OK" :
3003 "CR_OK_HANDSHAKE_COMPLETE" :
"error"));
3005 compile_time_assert(
CR_OK == -1);
3006 compile_time_assert(
CR_ERROR == 0);
3012 (!my_net_is_inited(&mysql->net) || mysql->net.read_pos[0] != 254))
3019 DBUG_PRINT (
"info", (
"res=%d", res));
3021 set_mysql_error(mysql, res, unknown_sqlstate);
3023 if (!mysql->net.last_errno)
3024 set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
3030 pkt_length= (*mysql->methods->read_change_user_result)(mysql);
3034 DBUG_PRINT (
"info", (
"OK packet length=%lu", pkt_length));
3035 if (pkt_length == packet_error)
3037 if (mysql->net.last_errno == CR_SERVER_LOST)
3038 set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
3039 ER(CR_SERVER_LOST_EXTENDED),
3040 "reading authorization packet",
3045 if (mysql->net.read_pos[0] == 254)
3048 if (pkt_length == 1)
3051 DBUG_PRINT (
"info", (
"old use short scramble packet from server"));
3052 auth_plugin_name= old_password_plugin_name;
3053 mpvio.cached_server_reply.
pkt= (uchar*)mysql->scramble;
3054 mpvio.cached_server_reply.pkt_len= SCRAMBLE_LENGTH + 1;
3060 auth_plugin_name= (
char*)mysql->net.read_pos + 1;
3061 len= strlen(auth_plugin_name);
3062 mpvio.cached_server_reply.pkt_len= pkt_length - len - 2;
3063 mpvio.cached_server_reply.
pkt= mysql->net.read_pos + len + 2;
3064 DBUG_PRINT (
"info", (
"change plugin packet from server for plugin %s",
3069 auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
3072 if (check_plugin_enabled(mysql, auth_plugin))
3075 mpvio.
plugin= auth_plugin;
3076 res= auth_plugin->authenticate_user((
struct st_plugin_vio *)&mpvio, mysql);
3078 DBUG_PRINT (
"info", (
"second authenticate_user returned %s",
3079 res ==
CR_OK ?
"CR_OK" :
3082 "CR_OK_HANDSHAKE_COMPLETE" :
"error"));
3086 set_mysql_error(mysql, res, unknown_sqlstate);
3088 if (!mysql->net.last_errno)
3089 set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
3096 if (cli_safe_read(mysql) == packet_error)
3098 if (mysql->net.last_errno == CR_SERVER_LOST)
3099 set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
3100 ER(CR_SERVER_LOST_EXTENDED),
3101 "reading final connect information",
3111 DBUG_RETURN (mysql->net.read_pos[0] != 0);
3117 set_connect_attributes(
MYSQL *mysql,
char *buff,
size_t buf_len)
3125 rc+= mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_DELETE,
"_client_name");
3126 rc+= mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_DELETE,
"_os");
3127 rc+= mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_DELETE,
"_platform");
3128 rc+= mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_DELETE,
"_pid");
3129 rc+= mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_DELETE,
"_thread");
3130 rc+= mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_DELETE,
"_client_version");
3135 rc+= mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
3136 "_client_name",
"libmysql");
3137 rc+= mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
3138 "_client_version", PACKAGE_VERSION);
3139 rc+= mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
3140 "_os", SYSTEM_TYPE);
3141 rc+= mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
3142 "_platform", MACHINE_TYPE);
3144 snprintf(buff, buf_len,
"%lu", (ulong) GetCurrentProcessId());
3146 snprintf(buff, buf_len,
"%lu", (ulong) getpid());
3148 rc+= mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
"_pid", buff);
3151 snprintf(buff, buf_len,
"%lu", (ulong) GetCurrentThreadId());
3152 rc+= mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
"_thread", buff);
3155 return rc > 0 ? 1 : 0;
3160 CLI_MYSQL_REAL_CONNECT(
MYSQL *mysql,
const char *host,
const char *user,
3161 const char *passwd,
const char *db,
3162 uint port,
const char *unix_socket,ulong client_flag)
3164 char buff[NAME_LEN+USERNAME_LENGTH+100];
3165 int scramble_data_len, pkt_scramble_len= 0;
3166 char *end,*host_info= 0, *server_version_end, *pkt_end;
3167 char *scramble_data;
3168 const char *scramble_plugin;
3170 NET *net= &mysql->net;
3172 HANDLE hPipe=INVALID_HANDLE_VALUE;
3174 #ifdef HAVE_SYS_UN_H
3175 struct sockaddr_un UNIXaddr;
3177 DBUG_ENTER(
"mysql_real_connect");
3179 DBUG_PRINT(
"enter",(
"host: %s db: %s user: %s (client)",
3180 host ? host :
"(Null)",
3182 user ? user :
"(Null)"));
3187 set_mysql_error(mysql, CR_ALREADY_CONNECTED, unknown_sqlstate);
3191 if (set_connect_attributes(mysql, buff,
sizeof(buff)))
3194 mysql->methods= &client_methods;
3196 mysql->client_flag=0;
3199 if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
3201 mysql_read_default_options(&mysql->options,
3202 (mysql->options.my_cnf_file ?
3203 mysql->options.my_cnf_file :
"my"),
3204 mysql->options.my_cnf_group);
3205 my_free(mysql->options.my_cnf_file);
3206 my_free(mysql->options.my_cnf_group);
3207 mysql->options.my_cnf_file=mysql->options.my_cnf_group=0;
3211 if (!host || !host[0])
3212 host=mysql->options.host;
3213 if (!user || !user[0])
3215 user=mysql->options.user;
3221 passwd=mysql->options.password;
3222 #if !defined(DONT_USE_MYSQL_PWD) && !defined(MYSQL_SERVER)
3224 passwd=getenv(
"MYSQL_PWD");
3230 db=mysql->options.db;
3232 port=mysql->options.port;
3234 unix_socket=mysql->options.unix_socket;
3236 mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
3237 DBUG_PRINT(
"info", (
"Connecting"));
3242 #if defined(HAVE_SMEM)
3243 if ((!mysql->options.protocol ||
3244 mysql->options.protocol == MYSQL_PROTOCOL_MEMORY) &&
3245 (!host || !strcmp(host,LOCAL_HOST)))
3248 DBUG_PRINT(
"info", (
"Using shared memory"));
3250 handle_map= create_shared_memory(mysql, net,
3251 get_win32_connect_timeout(mysql));
3253 if (handle_map == INVALID_HANDLE_VALUE)
3256 (
"host: '%s' socket: '%s' shared memory: %s have_tcpip: %d",
3257 host ? host :
"<null>",
3258 unix_socket ? unix_socket :
"<null>",
3259 (
int) mysql->options.shared_memory_base_name,
3261 if (mysql->options.protocol == MYSQL_PROTOCOL_MEMORY)
3269 net_clear_error(net);
3273 mysql->options.protocol=MYSQL_PROTOCOL_MEMORY;
3275 host=mysql->options.shared_memory_base_name;
3276 my_snprintf(host_info=buff,
sizeof(buff)-1,
3277 ER(CR_SHARED_MEMORY_CONNECTION), host);
3281 #if defined(HAVE_SYS_UN_H)
3283 (!mysql->options.protocol ||
3284 mysql->options.protocol == MYSQL_PROTOCOL_SOCKET) &&
3285 (unix_socket || mysql_unix_port) &&
3286 (!host || !strcmp(host,LOCAL_HOST)))
3288 my_socket sock= socket(AF_UNIX, SOCK_STREAM, 0);
3289 DBUG_PRINT(
"info", (
"Using socket"));
3290 if (sock == SOCKET_ERROR)
3292 set_mysql_extended_error(mysql, CR_SOCKET_CREATE_ERROR,
3294 ER(CR_SOCKET_CREATE_ERROR),
3299 net->vio= vio_new(sock, VIO_TYPE_SOCKET,
3300 VIO_LOCALHOST | VIO_BUFFERED_READ);
3303 DBUG_PRINT(
"error",(
"Unknow protocol %d ", mysql->options.protocol));
3304 set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
3311 unix_socket= mysql_unix_port;
3312 host_info= (
char*) ER(CR_LOCALHOST_CONNECTION);
3313 DBUG_PRINT(
"info", (
"Using UNIX sock '%s'", unix_socket));
3315 memset(&UNIXaddr, 0,
sizeof(UNIXaddr));
3316 UNIXaddr.sun_family= AF_UNIX;
3317 strmake(UNIXaddr.sun_path, unix_socket,
sizeof(UNIXaddr.sun_path)-1);
3319 if (vio_socket_connect(net->vio, (
struct sockaddr *) &UNIXaddr,
3320 sizeof(UNIXaddr), get_vio_connect_timeout(mysql)))
3322 DBUG_PRINT(
"error",(
"Got error %d on connect to local server",
3324 set_mysql_extended_error(mysql, CR_CONNECTION_ERROR,
3326 ER(CR_CONNECTION_ERROR),
3327 unix_socket, socket_errno);
3328 vio_delete(net->vio);
3332 mysql->options.protocol=MYSQL_PROTOCOL_SOCKET;
3334 #elif defined(_WIN32)
3336 (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
3337 (host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
3338 (! have_tcpip && (unix_socket || !host && is_NT()))))
3340 hPipe= create_named_pipe(mysql, get_win32_connect_timeout(mysql),
3341 &host, &unix_socket);
3343 if (hPipe == INVALID_HANDLE_VALUE)
3346 (
"host: '%s' socket: '%s' have_tcpip: %d",
3347 host ? host :
"<null>",
3348 unix_socket ? unix_socket :
"<null>",
3350 if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
3351 (host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
3352 (unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE)))
3358 net->vio= vio_new_win32pipe(hPipe);
3359 my_snprintf(host_info=buff,
sizeof(buff)-1,
3360 ER(CR_NAMEDPIPE_CONNECTION), unix_socket);
3364 DBUG_PRINT(
"info", (
"net->vio: %p protocol: %d",
3365 net->vio, mysql->options.protocol));
3367 (!mysql->options.protocol ||
3368 mysql->options.protocol == MYSQL_PROTOCOL_TCP))
3370 struct addrinfo *res_lst, *client_bind_ai_lst= NULL, hints, *t_res;
3371 char port_buf[NI_MAXSERV];
3372 my_socket sock= SOCKET_ERROR;
3373 int gai_errno, saved_error= 0, status= -1, bind_result= 0;
3374 uint
flags= VIO_BUFFERED_READ;
3384 my_snprintf(host_info=buff,
sizeof(buff)-1, ER(CR_TCP_CONNECTION), host);
3385 DBUG_PRINT(
"info",(
"Server name: '%s'. TCP sock: %d", host, port));
3387 memset(&hints, 0,
sizeof(hints));
3388 hints.ai_socktype= SOCK_STREAM;
3389 hints.ai_protocol= IPPROTO_TCP;
3390 hints.ai_family= AF_UNSPEC;
3392 DBUG_PRINT(
"info",(
"IPV6 getaddrinfo %s", host));
3393 my_snprintf(port_buf, NI_MAXSERV,
"%d", port);
3394 gai_errno= getaddrinfo(host, port_buf, &hints, &res_lst);
3402 DBUG_PRINT(
"info",(
"IPV6 getaddrinfo error %d", gai_errno));
3403 set_mysql_extended_error(mysql, CR_UNKNOWN_HOST, unknown_sqlstate,
3404 ER(CR_UNKNOWN_HOST), host, errno);
3410 if (mysql->options.ci.bind_address)
3412 int bind_gai_errno= 0;
3414 DBUG_PRINT(
"info",(
"Resolving addresses for client bind: '%s'",
3415 mysql->options.ci.bind_address));
3417 bind_gai_errno= getaddrinfo(mysql->options.ci.bind_address, 0,
3418 &hints, &client_bind_ai_lst);
3421 DBUG_PRINT(
"info",(
"client bind getaddrinfo error %d", bind_gai_errno));
3422 set_mysql_extended_error(mysql, CR_UNKNOWN_HOST, unknown_sqlstate,
3423 ER(CR_UNKNOWN_HOST),
3424 mysql->options.ci.bind_address,
3427 freeaddrinfo(res_lst);
3430 DBUG_PRINT(
"info", (
" got address info for client bind name"));
3439 DBUG_PRINT(
"info", (
"Try connect on all addresses for host."));
3440 for (t_res= res_lst; t_res; t_res= t_res->ai_next)
3442 DBUG_PRINT(
"info", (
"Create socket, family: %d type: %d proto: %d",
3443 t_res->ai_family, t_res->ai_socktype,
3444 t_res->ai_protocol));
3446 sock= socket(t_res->ai_family, t_res->ai_socktype, t_res->ai_protocol);
3447 if (sock == SOCKET_ERROR)
3449 DBUG_PRINT(
"info", (
"Socket created was invalid"));
3451 saved_error= socket_errno;
3455 if (client_bind_ai_lst)
3457 struct addrinfo* curr_bind_ai= NULL;
3458 DBUG_PRINT(
"info", (
"Attempting to bind socket to bind address(es)"));
3466 curr_bind_ai= client_bind_ai_lst;
3468 while (curr_bind_ai != NULL)
3471 bind_result= bind(sock,
3472 curr_bind_ai->ai_addr,
3473 curr_bind_ai->ai_addrlen);
3477 DBUG_PRINT(
"info", (
"bind failed, attempting another bind address"));
3479 curr_bind_ai= curr_bind_ai->ai_next;
3488 DBUG_PRINT(
"info", (
"All bind attempts with this address failed"));
3489 saved_error= socket_errno;
3493 DBUG_PRINT(
"info", (
"Successfully bound client side of socket"));
3499 if (!(net->vio= vio_new(sock, VIO_TYPE_TCPIP, flags)))
3501 set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
3503 freeaddrinfo(res_lst);
3504 if (client_bind_ai_lst)
3505 freeaddrinfo(client_bind_ai_lst);
3510 else if (vio_reset(net->vio, VIO_TYPE_TCPIP, sock, NULL, flags))
3512 set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
3514 freeaddrinfo(res_lst);
3515 if (client_bind_ai_lst)
3516 freeaddrinfo(client_bind_ai_lst);
3520 DBUG_PRINT(
"info", (
"Connect socket"));
3521 status= vio_socket_connect(net->vio, t_res->ai_addr, t_res->ai_addrlen,
3522 get_vio_connect_timeout(mysql));
3536 saved_error= socket_errno;
3538 DBUG_PRINT(
"info", (
"No success, close socket, try next address."));
3542 (
"End of connect attempts, sock: %d status: %d error: %d",
3543 sock, status, saved_error));
3545 freeaddrinfo(res_lst);
3546 if (client_bind_ai_lst)
3547 freeaddrinfo(client_bind_ai_lst);
3549 if (sock == SOCKET_ERROR)
3551 set_mysql_extended_error(mysql, CR_IPSOCK_ERROR, unknown_sqlstate,
3552 ER(CR_IPSOCK_ERROR), saved_error);
3558 DBUG_PRINT(
"error",(
"Got error %d on connect to '%s'", saved_error, host));
3559 set_mysql_extended_error(mysql, CR_CONN_HOST_ERROR, unknown_sqlstate,
3560 ER(CR_CONN_HOST_ERROR), host, saved_error);
3565 DBUG_PRINT(
"info", (
"net->vio: %p", net->vio));
3568 DBUG_PRINT(
"error",(
"Unknow protocol %d ",mysql->options.protocol));
3569 set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
3575 vio_delete(net->vio);
3577 set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
3580 vio_keepalive(net->vio,TRUE);
3583 if (mysql->options.read_timeout)
3584 my_net_set_read_timeout(net, mysql->options.read_timeout);
3587 if (mysql->options.write_timeout)
3588 my_net_set_write_timeout(net, mysql->options.write_timeout);
3590 if (mysql->options.max_allowed_packet)
3591 net->max_packet_size= mysql->options.max_allowed_packet;
3594 mysql->protocol_version= PROTOCOL_VERSION;
3595 if (mysql->options.connect_timeout &&
3596 (vio_io_wait(net->vio, VIO_IO_EVENT_READ,
3597 get_vio_connect_timeout(mysql)) < 1))
3599 set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
3600 ER(CR_SERVER_LOST_EXTENDED),
3601 "waiting for initial communication packet",
3609 DBUG_PRINT(
"info", (
"Read first packet."));
3611 if ((pkt_length=cli_safe_read(mysql)) == packet_error)
3613 if (mysql->net.last_errno == CR_SERVER_LOST)
3614 set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
3615 ER(CR_SERVER_LOST_EXTENDED),
3616 "reading initial communication packet",
3620 pkt_end= (
char*)net->read_pos + pkt_length;
3622 mysql->protocol_version= net->read_pos[0];
3623 DBUG_DUMP(
"packet",(uchar*) net->read_pos,10);
3624 DBUG_PRINT(
"info",(
"mysql protocol version %d, server=%d",
3625 PROTOCOL_VERSION, mysql->protocol_version));
3626 if (mysql->protocol_version != PROTOCOL_VERSION)
3628 set_mysql_extended_error(mysql, CR_VERSION_ERROR, unknown_sqlstate,
3629 ER(CR_VERSION_ERROR), mysql->protocol_version,
3633 server_version_end= end= strend((
char*) net->read_pos+1);
3634 mysql->thread_id=uint4korr(end+1);
3641 scramble_data_len= SCRAMBLE_LENGTH_323 + 1;
3642 scramble_plugin= old_password_plugin_name;
3643 end+= scramble_data_len;
3645 if (pkt_end >= end + 1)
3646 mysql->server_capabilities=uint2korr(end);
3647 if (pkt_end >= end + 18)
3650 mysql->server_language=end[2];
3651 mysql->server_status=uint2korr(end+3);
3652 mysql->server_capabilities|= uint2korr(end+5) << 16;
3653 pkt_scramble_len= end[7];
3654 if (pkt_scramble_len < 0)
3656 set_mysql_error(mysql, CR_MALFORMED_PACKET,
3663 if (mysql->options.secure_auth && passwd[0] &&
3664 !(mysql->server_capabilities & CLIENT_SECURE_CONNECTION))
3666 set_mysql_error(mysql, CR_SECURE_AUTH, unknown_sqlstate);
3670 if (mysql_init_character_set(mysql))
3674 if (!my_multi_malloc(MYF(0),
3675 &mysql->host_info, (uint) strlen(host_info)+1,
3676 &mysql->host, (uint) strlen(host)+1,
3677 &mysql->unix_socket,unix_socket ?
3678 (uint) strlen(unix_socket)+1 : (uint) 1,
3679 &mysql->server_version,
3680 (uint) (server_version_end - (
char*) net->read_pos + 1),
3682 !(mysql->user=my_strdup(user,MYF(0))) ||
3683 !(mysql->passwd=my_strdup(passwd,MYF(0))))
3685 set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
3688 strmov(mysql->host_info,host_info);
3689 strmov(mysql->host,host);
3691 strmov(mysql->unix_socket,unix_socket);
3693 mysql->unix_socket=0;
3694 strmov(mysql->server_version,(
char*) net->read_pos+1);
3697 if (pkt_end >= end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1)
3704 memmove(end - SCRAMBLE_LENGTH_323, scramble_data,
3705 SCRAMBLE_LENGTH_323);
3706 scramble_data= end - SCRAMBLE_LENGTH_323;
3707 if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
3709 scramble_data_len= pkt_scramble_len;
3710 scramble_plugin= scramble_data + scramble_data_len;
3711 if (scramble_data + scramble_data_len > pkt_end)
3712 scramble_data_len= pkt_end - scramble_data;
3716 scramble_data_len= pkt_end - scramble_data;
3717 scramble_plugin= native_password_plugin_name;
3721 mysql->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
3723 mysql->client_flag= client_flag;
3729 if (run_plugin_auth(mysql, scramble_data, scramble_data_len,
3730 scramble_plugin, db))
3737 if (mysql->client_flag & CLIENT_COMPRESS)
3740 #ifdef CHECK_LICENSE
3741 if (check_license(mysql))
3745 if (db && !mysql->db && mysql_select_db(mysql, db))
3747 if (mysql->net.last_errno == CR_SERVER_LOST)
3748 set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
3749 ER(CR_SERVER_LOST_EXTENDED),
3750 "Setting intital database",
3759 #ifndef MYSQL_SERVER
3760 if (mysql->options.init_commands)
3763 char **ptr= (
char**)init_commands->buffer;
3764 char **end_command= ptr + init_commands->elements;
3766 my_bool reconnect=mysql->reconnect;
3769 for (; ptr < end_command; ptr++)
3773 if (mysql_real_query(mysql,*ptr, (ulong) strlen(*ptr)))
3780 if (!(res= cli_use_result(mysql)))
3782 mysql_free_result(res);
3784 if ((status= mysql_next_result(mysql)) > 0)
3786 }
while (status == 0);
3788 mysql->reconnect=reconnect;
3792 DBUG_PRINT(
"exit", (
"Mysql handler: 0x%lx", (
long) mysql));
3796 DBUG_PRINT(
"error",(
"message: %u/%s (%s)",
3803 mysql_close_free(mysql);
3804 if (!(client_flag & CLIENT_REMEMBER_OPTIONS))
3805 mysql_close_free_options(mysql);
3811 my_bool mysql_reconnect(
MYSQL *mysql)
3814 DBUG_ENTER(
"mysql_reconnect");
3816 DBUG_PRINT(
"enter", (
"mysql->reconnect: %d", mysql->reconnect));
3818 if (!mysql->reconnect ||
3819 (mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info)
3822 mysql->server_status&= ~SERVER_STATUS_IN_TRANS;
3823 set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate);
3826 mysql_init(&tmp_mysql);
3827 tmp_mysql.options= mysql->options;
3828 tmp_mysql.options.my_cnf_file= tmp_mysql.options.my_cnf_group= 0;
3830 if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
3831 mysql->db, mysql->port, mysql->unix_socket,
3832 mysql->client_flag | CLIENT_REMEMBER_OPTIONS))
3834 memset(&tmp_mysql.options, 0,
sizeof(tmp_mysql.options));
3835 mysql_close(&tmp_mysql);
3836 mysql->net.last_errno= tmp_mysql.net.last_errno;
3841 if (mysql_set_character_set(&tmp_mysql, mysql->charset->csname))
3843 DBUG_PRINT(
"error", (
"mysql_set_character_set() failed"));
3844 memset(&tmp_mysql.options, 0,
sizeof(tmp_mysql.options));
3845 mysql_close(&tmp_mysql);
3846 mysql->net.last_errno= tmp_mysql.net.last_errno;
3852 DBUG_PRINT(
"info", (
"reconnect succeded"));
3853 tmp_mysql.reconnect= 1;
3854 tmp_mysql.free_me= mysql->free_me;
3857 tmp_mysql.stmts= mysql->stmts;
3861 memset(&mysql->options, 0,
sizeof(mysql->options));
3866 mysql->affected_rows= ~(my_ulonglong) 0;
3876 mysql_select_db(
MYSQL *mysql,
const char *db)
3879 DBUG_ENTER(
"mysql_select_db");
3880 DBUG_PRINT(
"enter",(
"db: '%s'",db));
3882 if ((error=simple_command(mysql,COM_INIT_DB, (
const uchar*) db,
3883 (ulong) strlen(db),0)))
3886 mysql->db=my_strdup(db,MYF(MY_WME));
3896 static void mysql_close_free_options(
MYSQL *mysql)
3898 DBUG_ENTER(
"mysql_close_free_options");
3900 my_free(mysql->options.user);
3901 my_free(mysql->options.host);
3902 my_free(mysql->options.password);
3903 my_free(mysql->options.unix_socket);
3904 my_free(mysql->options.db);
3905 my_free(mysql->options.my_cnf_file);
3906 my_free(mysql->options.my_cnf_group);
3907 my_free(mysql->options.charset_dir);
3908 my_free(mysql->options.charset_name);
3909 my_free(mysql->options.ci.client_ip);
3911 if (mysql->options.init_commands)
3914 char **ptr= (
char**)init_commands->buffer;
3915 char **end= ptr + init_commands->elements;
3916 for (; ptr<end; ptr++)
3918 delete_dynamic(init_commands);
3919 my_free(init_commands);
3921 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
3922 mysql_ssl_free(mysql);
3925 if (mysql->options.shared_memory_base_name != def_shared_memory_base_name)
3926 my_free(mysql->options.shared_memory_base_name);
3928 if (mysql->options.extension)
3930 my_free(mysql->options.extension->plugin_dir);
3931 my_free(mysql->options.extension->default_auth);
3932 my_hash_free(&mysql->options.extension->connection_attributes);
3933 my_free(mysql->options.extension);
3935 memset(&mysql->options, 0,
sizeof(mysql->options));
3940 static void mysql_close_free(
MYSQL *mysql)
3942 my_free(mysql->host_info);
3943 my_free(mysql->user);
3944 my_free(mysql->passwd);
3946 #if defined(EMBEDDED_LIBRARY) || MYSQL_VERSION_ID >= 50100
3947 my_free(mysql->info_buffer);
3948 mysql->info_buffer= 0;
3951 mysql->host_info= mysql->user= mysql->passwd= mysql->db= 0;
3970 static void mysql_prune_stmt_list(
MYSQL *mysql)
3972 LIST *element= mysql->stmts;
3973 LIST *pruned_list= 0;
3975 for (; element; element= element->next)
3978 if (stmt->state != MYSQL_STMT_INIT_DONE)
3981 stmt->last_errno= CR_SERVER_LOST;
3982 strmov(stmt->last_error, ER(CR_SERVER_LOST));
3983 strmov(stmt->sqlstate, unknown_sqlstate);
3987 pruned_list= list_add(pruned_list, element);
3991 mysql->stmts= pruned_list;
4010 void mysql_detach_stmt_list(
LIST **stmt_list __attribute__((unused)),
4011 const char *func_name __attribute__((unused)))
4015 LIST *element= *stmt_list;
4016 char buff[MYSQL_ERRMSG_SIZE];
4017 DBUG_ENTER(
"mysql_detach_stmt_list");
4019 my_snprintf(buff,
sizeof(buff)-1, ER(CR_STMT_CLOSED), func_name);
4020 for (; element; element= element->next)
4023 set_stmt_error(stmt, CR_STMT_CLOSED, unknown_sqlstate, buff);
4033 void STDCALL mysql_close(
MYSQL *mysql)
4035 DBUG_ENTER(
"mysql_close");
4039 if (mysql->net.vio != 0)
4041 free_old_query(mysql);
4042 mysql->status=MYSQL_STATUS_READY;
4044 simple_command(mysql,COM_QUIT,(uchar*) 0,0,1);
4047 mysql_close_free_options(mysql);
4048 mysql_close_free(mysql);
4049 mysql_detach_stmt_list(&mysql->stmts,
"mysql_close");
4050 #ifndef MYSQL_SERVER
4052 (*mysql->methods->free_embedded_thd)(mysql);
4061 static my_bool cli_read_query_result(
MYSQL *mysql)
4067 DBUG_ENTER(
"cli_read_query_result");
4069 if ((length = cli_safe_read(mysql)) == packet_error)
4071 free_old_query(mysql);
4075 pos=(uchar*) mysql->net.read_pos;
4076 if ((field_count= net_field_length(&pos)) == 0)
4078 mysql->affected_rows= net_field_length_ll(&pos);
4079 mysql->insert_id= net_field_length_ll(&pos);
4080 DBUG_PRINT(
"info",(
"affected_rows: %lu insert_id: %lu",
4081 (ulong) mysql->affected_rows,
4082 (ulong) mysql->insert_id));
4083 if (protocol_41(mysql))
4085 mysql->server_status=uint2korr(pos); pos+=2;
4086 mysql->warning_count=uint2korr(pos); pos+=2;
4088 else if (mysql->server_capabilities & CLIENT_TRANSACTIONS)
4091 mysql->server_status=uint2korr(pos); pos+=2;
4092 mysql->warning_count= 0;
4094 DBUG_PRINT(
"info",(
"status: %u warning_count: %u",
4095 mysql->server_status, mysql->warning_count));
4096 if (pos < mysql->net.read_pos+length && net_field_length(&pos))
4097 mysql->info=(
char*) pos;
4101 if (field_count == NULL_LENGTH)
4105 if (!(mysql->options.client_flag & CLIENT_LOCAL_FILES))
4107 set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
4111 error= handle_local_infile(mysql,(
char*) pos);
4112 if ((length= cli_safe_read(mysql)) == packet_error || error)
4117 if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
4118 mysql->server_status|= SERVER_STATUS_IN_TRANS;
4120 if (!(fields=cli_read_rows(mysql,(
MYSQL_FIELD*)0, protocol_41(mysql) ? 7:5)))
4122 if (!(mysql->fields=unpack_fields(mysql, fields,&mysql->field_alloc,
4123 (uint) field_count,0,
4124 mysql->server_capabilities)))
4126 mysql->status= MYSQL_STATUS_GET_RESULT;
4127 mysql->field_count= (uint) field_count;
4128 DBUG_PRINT(
"exit",(
"ok"));
4140 mysql_send_query(
MYSQL* mysql,
const char* query, ulong length)
4142 DBUG_ENTER(
"mysql_send_query");
4143 DBUG_RETURN(simple_command(mysql, COM_QUERY, (uchar*) query, length, 1));
4148 mysql_real_query(
MYSQL *mysql,
const char *query, ulong length)
4151 DBUG_ENTER(
"mysql_real_query");
4152 DBUG_PRINT(
"enter",(
"handle: %p", mysql));
4153 DBUG_PRINT(
"query",(
"Query = '%-.*s'", (
int) length, query));
4155 if (mysql_send_query(mysql,query,length))
4157 retval= (int) (*mysql->methods->read_query_result)(mysql);
4158 DBUG_RETURN(retval);
4170 DBUG_ENTER(
"mysql_store_result");
4174 if (mysql->status != MYSQL_STATUS_GET_RESULT)
4176 set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
4179 mysql->status=MYSQL_STATUS_READY;
4182 mysql->field_count),
4183 MYF(MY_WME | MY_ZEROFILL))))
4185 set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
4188 result->methods= mysql->methods;
4190 result->lengths=(ulong*) (result+1);
4192 (*mysql->methods->read_rows)(mysql,mysql->fields,mysql->field_count)))
4197 mysql->affected_rows= result->row_count= result->data->rows;
4198 result->data_cursor= result->data->data;
4199 result->fields= mysql->fields;
4200 result->field_alloc= mysql->field_alloc;
4201 result->field_count= mysql->field_count;
4204 clear_alloc_root(&mysql->field_alloc);
4206 mysql->unbuffered_fetch_owner= 0;
4207 DBUG_RETURN(result);
4224 DBUG_ENTER(
"cli_use_result");
4228 if (mysql->status != MYSQL_STATUS_GET_RESULT)
4230 set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
4233 if (!(result=(
MYSQL_RES*) my_malloc(
sizeof(*result)+
4234 sizeof(ulong)*mysql->field_count,
4235 MYF(MY_WME | MY_ZEROFILL))))
4237 result->lengths=(ulong*) (result+1);
4238 result->methods= mysql->methods;
4239 if (!(result->row=(MYSQL_ROW)
4240 my_malloc(
sizeof(result->row[0])*(mysql->field_count+1), MYF(MY_WME))))
4245 result->fields= mysql->fields;
4246 result->field_alloc= mysql->field_alloc;
4247 result->field_count= mysql->field_count;
4248 result->current_field=0;
4249 result->handle= mysql;
4250 result->current_row= 0;
4252 clear_alloc_root(&mysql->field_alloc);
4253 mysql->status=MYSQL_STATUS_USE_RESULT;
4254 mysql->unbuffered_fetch_owner= &result->unbuffered_fetch_cancelled;
4255 DBUG_RETURN(result);
4266 DBUG_ENTER(
"mysql_fetch_row");
4271 MYSQL *mysql= res->handle;
4272 if (mysql->status != MYSQL_STATUS_USE_RESULT)
4274 set_mysql_error(mysql,
4275 res->unbuffered_fetch_cancelled ?
4276 CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC,
4279 else if (!(read_one_row(mysql, res->field_count, res->row, res->lengths)))
4282 DBUG_RETURN(res->current_row=res->row);
4284 DBUG_PRINT(
"info",(
"end of data"));
4286 mysql->status=MYSQL_STATUS_READY;
4291 if (mysql->unbuffered_fetch_owner == &res->unbuffered_fetch_cancelled)
4292 mysql->unbuffered_fetch_owner= 0;
4296 DBUG_RETURN((MYSQL_ROW) NULL);
4300 if (!res->data_cursor)
4302 DBUG_PRINT(
"info",(
"end of data"));
4303 DBUG_RETURN(res->current_row=(MYSQL_ROW) NULL);
4305 tmp = res->data_cursor->data;
4306 res->data_cursor = res->data_cursor->next;
4307 DBUG_RETURN(res->current_row=tmp);
4323 if (!(column=res->current_row))
4326 (*res->methods->fetch_lengths)(res->lengths, column, res->field_count);
4327 return res->lengths;
4331 mysql_options(
MYSQL *mysql,
enum mysql_option option,
const void *arg)
4333 DBUG_ENTER(
"mysql_option");
4334 DBUG_PRINT(
"enter",(
"option: %d",(
int) option));
4336 case MYSQL_OPT_CONNECT_TIMEOUT:
4337 mysql->options.connect_timeout= *(uint*) arg;
4339 case MYSQL_OPT_READ_TIMEOUT:
4340 mysql->options.read_timeout= *(uint*) arg;
4342 case MYSQL_OPT_WRITE_TIMEOUT:
4343 mysql->options.write_timeout= *(uint*) arg;
4345 case MYSQL_OPT_COMPRESS:
4346 mysql->options.compress= 1;
4347 mysql->options.client_flag|= CLIENT_COMPRESS;
4349 case MYSQL_OPT_NAMED_PIPE:
4350 mysql->options.protocol=MYSQL_PROTOCOL_PIPE;
4352 case MYSQL_OPT_LOCAL_INFILE:
4353 if (!arg || test(*(uint*) arg))
4354 mysql->options.client_flag|= CLIENT_LOCAL_FILES;
4356 mysql->options.client_flag&= ~CLIENT_LOCAL_FILES;
4358 case MYSQL_INIT_COMMAND:
4359 add_init_command(&mysql->options,arg);
4361 case MYSQL_READ_DEFAULT_FILE:
4362 my_free(mysql->options.my_cnf_file);
4363 mysql->options.my_cnf_file=my_strdup(arg,MYF(MY_WME));
4365 case MYSQL_READ_DEFAULT_GROUP:
4366 my_free(mysql->options.my_cnf_group);
4367 mysql->options.my_cnf_group=my_strdup(arg,MYF(MY_WME));
4369 case MYSQL_SET_CHARSET_DIR:
4370 my_free(mysql->options.charset_dir);
4371 mysql->options.charset_dir=my_strdup(arg,MYF(MY_WME));
4373 case MYSQL_SET_CHARSET_NAME:
4374 my_free(mysql->options.charset_name);
4375 mysql->options.charset_name=my_strdup(arg,MYF(MY_WME));
4377 case MYSQL_OPT_PROTOCOL:
4378 mysql->options.protocol= *(uint*) arg;
4380 case MYSQL_SHARED_MEMORY_BASE_NAME:
4382 if (mysql->options.shared_memory_base_name != def_shared_memory_base_name)
4383 my_free(mysql->options.shared_memory_base_name);
4384 mysql->options.shared_memory_base_name=my_strdup(arg,MYF(MY_WME));
4387 case MYSQL_OPT_USE_REMOTE_CONNECTION:
4388 case MYSQL_OPT_USE_EMBEDDED_CONNECTION:
4389 case MYSQL_OPT_GUESS_CONNECTION:
4390 mysql->options.methods_to_use= option;
4392 case MYSQL_SET_CLIENT_IP:
4393 mysql->options.ci.client_ip= my_strdup(arg, MYF(MY_WME));
4395 case MYSQL_SECURE_AUTH:
4396 mysql->options.secure_auth= *(my_bool *) arg;
4398 case MYSQL_REPORT_DATA_TRUNCATION:
4399 mysql->options.report_data_truncation= test(*(my_bool *) arg);
4401 case MYSQL_OPT_RECONNECT:
4402 mysql->reconnect= *(my_bool *) arg;
4404 case MYSQL_OPT_BIND:
4405 my_free(mysql->options.ci.bind_address);
4406 mysql->options.ci.bind_address= my_strdup(arg, MYF(MY_WME));
4408 case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
4409 if (*(my_bool*) arg)
4410 mysql->options.client_flag|= CLIENT_SSL_VERIFY_SERVER_CERT;
4412 mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT;
4414 case MYSQL_PLUGIN_DIR:
4415 EXTENSION_SET_STRING(&mysql->options, plugin_dir, arg);
4417 case MYSQL_DEFAULT_AUTH:
4418 EXTENSION_SET_STRING(&mysql->options, default_auth, arg);
4420 case MYSQL_OPT_SSL_KEY: SET_SSL_OPTION(ssl_key, arg);
break;
4421 case MYSQL_OPT_SSL_CERT: SET_SSL_OPTION(ssl_cert, arg);
break;
4422 case MYSQL_OPT_SSL_CA: SET_SSL_OPTION(ssl_ca, arg);
break;
4423 case MYSQL_OPT_SSL_CAPATH: SET_SSL_OPTION(ssl_capath, arg);
break;
4424 case MYSQL_OPT_SSL_CIPHER: SET_SSL_OPTION(ssl_cipher, arg);
break;
4425 case MYSQL_OPT_SSL_CRL: EXTENSION_SET_SSL_STRING(&mysql->options,
4428 case MYSQL_OPT_SSL_CRLPATH: EXTENSION_SET_SSL_STRING(&mysql->options,
4431 case MYSQL_SERVER_PUBLIC_KEY:
4432 EXTENSION_SET_STRING(&mysql->options, server_public_key_path, arg);
4435 case MYSQL_OPT_CONNECT_ATTR_RESET:
4436 ENSURE_EXTENSIONS_PRESENT(&mysql->options);
4437 if (my_hash_inited(&mysql->options.extension->connection_attributes))
4439 my_hash_free(&mysql->options.extension->connection_attributes);
4440 mysql->options.extension->connection_attributes_length= 0;
4443 case MYSQL_OPT_CONNECT_ATTR_DELETE:
4444 ENSURE_EXTENSIONS_PRESENT(&mysql->options);
4445 if (my_hash_inited(&mysql->options.extension->connection_attributes))
4450 len= arg ? strlen(arg) : 0;
4454 elt= my_hash_search(&mysql->options.extension->connection_attributes,
4461 mysql->options.extension->connection_attributes_length-=
4462 get_length_store_length(key->length) + key->length +
4463 get_length_store_length(value->length) + value->length;
4465 my_hash_delete(&mysql->options.extension->connection_attributes,
4472 case MYSQL_ENABLE_CLEARTEXT_PLUGIN:
4473 ENSURE_EXTENSIONS_PRESENT(&mysql->options);
4474 mysql->options.extension->enable_cleartext_plugin=
4475 (*(my_bool*) arg) ? TRUE : FALSE;
4477 case MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS:
4478 if (*(my_bool*) arg)
4479 mysql->options.client_flag|= CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS;
4481 mysql->options.client_flag&= ~CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS;
4495 get_attr_key(
LEX_STRING *part,
size_t *length,
4496 my_bool not_used __attribute__((unused)))
4498 *length= part[0].length;
4499 return (uchar *) part[0].str;
4503 mysql_options4(
MYSQL *mysql,
enum mysql_option option,
4504 const void *arg1,
const void *arg2)
4506 DBUG_ENTER(
"mysql_option");
4507 DBUG_PRINT(
"enter",(
"option: %d",(
int) option));
4511 case MYSQL_OPT_CONNECT_ATTR_ADD:
4515 size_t key_len= arg1 ? strlen(arg1) : 0,
4516 value_len= arg2 ? strlen(arg2) : 0;
4517 size_t attr_storage_length= key_len + value_len;
4522 set_mysql_error(mysql, CR_INVALID_PARAMETER_NO, unknown_sqlstate);
4527 attr_storage_length+= get_length_store_length(key_len);
4528 attr_storage_length+= get_length_store_length(value_len);
4530 ENSURE_EXTENSIONS_PRESENT(&mysql->options);
4536 if (attr_storage_length +
4537 mysql->options.extension->connection_attributes_length >
4538 MAX_CONNECTION_ATTR_STORAGE_LENGTH)
4540 set_mysql_error(mysql, CR_INVALID_PARAMETER_NO, unknown_sqlstate);
4544 if (!my_hash_inited(&mysql->options.extension->connection_attributes))
4546 if (my_hash_init(&mysql->options.extension->connection_attributes,
4547 &my_charset_bin, 0, 0, 0, (my_hash_get_key) get_attr_key,
4548 my_free, HASH_UNIQUE))
4550 set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
4554 if (!my_multi_malloc(MY_WME,
4557 &value, value_len + 1,
4560 set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
4563 elt[0].str= key; elt[0].length= key_len;
4564 elt[1].str= value; elt[1].length= value_len;
4566 memcpy(key, arg1, key_len);
4569 memcpy(value, arg2, value_len);
4570 value[value_len]= 0;
4571 if (my_hash_insert(&mysql->options.extension->connection_attributes,
4576 set_mysql_error(mysql, CR_DUPLICATE_CONNECTION_ATTR,
4581 mysql->options.extension->connection_attributes_length+=
4582 attr_storage_length;
4600 my_ulonglong STDCALL mysql_num_rows(
MYSQL_RES *res)
4602 return res->row_count;
4605 unsigned int STDCALL mysql_num_fields(
MYSQL_RES *res)
4607 return res->field_count;
4610 uint STDCALL mysql_errno(
MYSQL *mysql)
4612 return mysql ? mysql->net.last_errno : mysql_server_last_errno;
4616 const char * STDCALL mysql_error(
MYSQL *mysql)
4618 return mysql ? mysql->net.
last_error : mysql_server_last_error;
4640 mysql_get_server_version(
MYSQL *mysql)
4642 uint major, minor, version;
4643 char *pos= mysql->server_version, *end_pos;
4644 major= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1;
4645 minor= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1;
4646 version= (uint) strtoul(pos, &end_pos, 10);
4647 return (ulong) major*10000L+(ulong) (minor*100+version);
4657 int STDCALL mysql_set_character_set(
MYSQL *mysql,
const char *cs_name)
4660 const char *save_csdir= charsets_dir;
4662 if (mysql->options.charset_dir)
4663 charsets_dir= mysql->options.charset_dir;
4665 if (!mysql->net.vio)
4668 mysql_options(mysql, MYSQL_SET_CHARSET_NAME, cs_name);
4669 mysql_init_character_set(mysql);
4676 cs_name= mysql->options.charset_name;
4679 if (strlen(cs_name) < MY_CS_NAME_SIZE &&
4680 (cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY, MYF(0))))
4682 char buff[MY_CS_NAME_SIZE + 10];
4683 charsets_dir= save_csdir;
4684 if (!mysql->net.vio)
4691 if (mysql_get_server_version(mysql) < 40100)
4693 sprintf(buff,
"SET NAMES %s", cs_name);
4694 if (!mysql_real_query(mysql, buff, (uint) strlen(buff)))
4701 char cs_dir_name[FN_REFLEN];
4702 get_charsets_dir(cs_dir_name);
4703 set_mysql_extended_error(mysql, CR_CANT_READ_CHARSET, unknown_sqlstate,
4704 ER(CR_CANT_READ_CHARSET), cs_name, cs_dir_name);
4706 charsets_dir= save_csdir;
4707 return mysql->net.last_errno;
4719 DBUG_ENTER(
"native_password_auth_client");
4728 pkt= (uchar*)mysql->scramble;
4729 pkt_len= SCRAMBLE_LENGTH + 1;
4737 if (pkt_len != SCRAMBLE_LENGTH + 1)
4738 DBUG_RETURN(CR_SERVER_HANDSHAKE_ERR);
4741 memcpy(mysql->scramble, pkt, SCRAMBLE_LENGTH);
4742 mysql->scramble[SCRAMBLE_LENGTH] = 0;
4745 if (mysql->passwd[0])
4747 char scrambled[SCRAMBLE_LENGTH + 1];
4748 DBUG_PRINT(
"info", (
"sending scramble"));
4749 scramble(scrambled, (
char*)pkt, mysql->passwd);
4750 if (vio->
write_packet(vio, (uchar*)scrambled, SCRAMBLE_LENGTH))
4755 DBUG_PRINT(
"info", (
"no password"));
4772 DBUG_ENTER(
"old_password_auth_client");
4780 pkt= (uchar*)mysql->scramble;
4781 pkt_len= SCRAMBLE_LENGTH_323 + 1;
4789 if (pkt_len != SCRAMBLE_LENGTH_323 + 1 &&
4790 pkt_len != SCRAMBLE_LENGTH + 1)
4791 DBUG_RETURN(CR_SERVER_HANDSHAKE_ERR);
4798 memcpy(mysql->scramble, pkt, (pkt_len - 1));
4799 mysql->scramble[pkt_len-1] = 0;
4802 if (mysql->passwd[0])
4813 if (mysql->options.secure_auth)
4815 set_mysql_error(mysql, CR_SECURE_AUTH, unknown_sqlstate);
4820 char scrambled[SCRAMBLE_LENGTH_323 + 1];
4821 scramble_323(scrambled, (
char*)pkt, mysql->passwd);
4822 if (vio->
write_packet(vio, (uchar*)scrambled, SCRAMBLE_LENGTH_323 + 1))
4842 res= vio->
write_packet(vio, (
const unsigned char *) mysql->passwd,
4843 strlen(mysql->passwd) + 1);