1
/* Copyright (C) 2000-2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
This file is included by both libmysql.c (the MySQL client C API)
18
and the mysqld server to connect to another MYSQL server.
20
The differences for the two cases are:
22
- Things that only works for the client:
23
- Trying to automaticly determinate user name if not supplied to
25
- Support for reading local file with LOAD DATA LOCAL
26
- SHARED memory handling
27
- Protection against sigpipe
30
- Things that only works for the server
31
- Alarm handling on connect
33
In all other cases, the code should be idential for the client and
37
#include <my_global.h>
41
/* Windows lacks a netdb.h */
48
/* Remove client convenience wrappers */
49
#undef max_allowed_packet
50
#undef net_buffer_length
52
#ifdef EMBEDDED_LIBRARY
60
#define CLI_MYSQL_REAL_CONNECT STDCALL cli_mysql_real_connect
63
my_bool net_flush(NET *net);
65
#else /*EMBEDDED_LIBRARY*/
66
#define CLI_MYSQL_REAL_CONNECT STDCALL mysql_real_connect
67
#endif /*EMBEDDED_LIBRARY*/
69
#include <mysys_err.h>
72
#include "mysql_version.h"
73
#include "mysqld_error.h"
76
#if defined(THREAD) && !defined(__WIN__)
77
#include <my_pthread.h> /* because of signal() */
78
#endif /* defined(THREAD) && !defined(__WIN__) */
86
#if !defined(MSDOS) && !defined(__WIN__)
87
#include <sys/socket.h>
88
#include <netinet/in.h>
89
#include <arpa/inet.h>
94
#ifdef HAVE_SYS_SELECT_H
95
#include <sys/select.h>
97
#endif /*!defined(MSDOS) && !defined(__WIN__) */
102
#if defined(MSDOS) || defined(__WIN__)
106
#define SOCKET_ERROR -1
110
#define CONNECT_TIMEOUT 20
112
#define CONNECT_TIMEOUT 0
115
#include "client_settings.h"
116
#include <sql_common.h>
119
char *mysql_unix_port= 0;
120
const char *unknown_sqlstate= "HY000";
121
const char *not_error_sqlstate= "00000";
122
const char *cant_connect_sqlstate= "08001";
124
char *shared_memory_base_name= 0;
125
const char *def_shared_memory_base_name= default_shared_memory_base_name;
128
static void mysql_close_free_options(MYSQL *mysql);
129
static void mysql_close_free(MYSQL *mysql);
131
#if !(defined(__WIN__) || defined(__NETWARE__))
132
static int wait_for_data(my_socket fd, uint timeout);
135
CHARSET_INFO *default_client_charset_info = &my_charset_latin1;
137
/* Server error code and message */
138
unsigned int mysql_server_last_errno;
139
char mysql_server_last_error[MYSQL_ERRMSG_SIZE];
141
/****************************************************************************
142
A modified version of connect(). my_connect() allows you to specify
143
a timeout value, in seconds, that we should wait until we
144
derermine we can't connect to a particular host. If timeout is 0,
145
my_connect() will behave exactly like connect().
147
Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
148
*****************************************************************************/
150
int my_connect(my_socket fd, const struct sockaddr *name, uint namelen,
153
#if defined(__WIN__) || defined(__NETWARE__)
154
return connect(fd, (struct sockaddr*) name, namelen);
156
int flags, res, s_err;
159
If they passed us a timeout of zero, we should behave
160
exactly like the normal connect() call does.
164
return connect(fd, (struct sockaddr*) name, namelen);
166
flags = fcntl(fd, F_GETFL, 0); /* Set socket to not block */
168
fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
171
res= connect(fd, (struct sockaddr*) name, namelen);
172
s_err= errno; /* Save the error... */
173
fcntl(fd, F_SETFL, flags);
174
if ((res != 0) && (s_err != EINPROGRESS))
176
errno= s_err; /* Restore it */
179
if (res == 0) /* Connected quickly! */
181
return wait_for_data(fd, timeout);
187
Wait up to timeout seconds for a connection to be established.
189
We prefer to do this with poll() as there is no limitations with this.
190
If not, we will use select()
193
#if !(defined(__WIN__) || defined(__NETWARE__))
195
static int wait_for_data(my_socket fd, uint timeout)
202
ufds.events= POLLIN | POLLPRI;
203
if (!(res= poll(&ufds, 1, (int) timeout*1000)))
208
if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
212
SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
215
time_t start_time, now_time;
218
if (fd >= FD_SETSIZE) /* Check if wrong error */
219
return 0; /* Can't use timeout */
222
Our connection is "in progress." We can use the select() call to wait
223
up to a specified period of time for the connection to suceed.
224
If select() returns 0 (after waiting howevermany seconds), our socket
225
never became writable (host is probably unreachable.) Otherwise, if
226
select() returns 1, then one of two conditions exist:
228
1. An error occured. We use getsockopt() to check for this.
229
2. The connection was set up sucessfully: getsockopt() will
230
return 0 as an error.
232
Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
233
who posted this method of timing out a connect() in
234
comp.unix.programmer on August 15th, 1997.
240
select could be interrupted by a signal, and if it is,
241
the timeout should be adjusted and the select restarted
242
to work around OSes that don't restart select and
243
implementations of select that don't adjust tv upon
244
failure to reflect the time remaining
246
start_time= my_time(0);
249
tv.tv_sec = (long) timeout;
251
#if defined(HPUX10) && defined(THREAD)
252
if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
255
if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0)
258
if (res == 0) /* timeout */
260
now_time= my_time(0);
261
timeout-= (uint) (now_time - start_time);
262
if (errno != EINTR || (int) timeout <= 0)
267
select() returned something more interesting than zero, let's
268
see if we have any errors. If the next two statements pass,
269
we've got an open socket!
273
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
277
{ /* getsockopt could succeed */
279
return(-1); /* but return an error... */
282
#endif /* HAVE_POLL */
284
#endif /* defined(__WIN__) || defined(__NETWARE__) */
287
Set the internal error message to mysql handler
289
@param mysql connection handle (client side)
290
@param errcode CR_ error code, passed to ER macro to get
292
@parma sqlstate SQL standard sqlstate
295
void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate)
298
DBUG_ENTER("set_mysql_error");
299
DBUG_PRINT("enter", ("error :%d '%s'", errcode, ER(errcode)));
300
DBUG_ASSERT(mysql != 0);
305
net->last_errno= errcode;
306
strmov(net->last_error, ER(errcode));
307
strmov(net->sqlstate, sqlstate);
311
mysql_server_last_errno= errcode;
312
strmov(mysql_server_last_error, ER(errcode));
318
Clear possible error state of struct NET
320
@param net clear the state of the argument
323
void net_clear_error(NET *net)
326
net->last_error[0]= '\0';
327
strmov(net->sqlstate, not_error_sqlstate);
331
Set an error message on the client.
333
@param mysql connection handle
334
@param errcode CR_* errcode, for client errors
335
@param sqlstate SQL standard sql state, unknown_sqlstate for the
336
majority of client errors.
337
@param format error message template, in sprintf format
338
@param ... variable number of arguments
341
static void set_mysql_extended_error(MYSQL *mysql, int errcode,
342
const char *sqlstate,
343
const char *format, ...)
347
DBUG_ENTER("set_mysql_extended_error");
348
DBUG_PRINT("enter", ("error :%d '%s'", errcode, format));
349
DBUG_ASSERT(mysql != 0);
352
net->last_errno= errcode;
353
va_start(args, format);
354
my_vsnprintf(net->last_error, sizeof(net->last_error)-1,
357
strmov(net->sqlstate, sqlstate);
365
Create a named pipe connection
370
HANDLE create_named_pipe(MYSQL *mysql, uint connect_timeout, char **arg_host,
371
char **arg_unix_socket)
373
HANDLE hPipe=INVALID_HANDLE_VALUE;
374
char pipe_name[1024];
377
my_bool testing_named_pipes=0;
378
char *host= *arg_host, *unix_socket= *arg_unix_socket;
380
if ( ! unix_socket || (unix_socket)[0] == 0x00)
381
unix_socket = mysql_unix_port;
382
if (!host || !strcmp(host,LOCAL_HOST))
383
host=LOCAL_HOST_NAMEDPIPE;
386
pipe_name[sizeof(pipe_name)-1]= 0; /* Safety if too long string */
387
strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\", host, "\\pipe\\",
389
DBUG_PRINT("info",("Server name: '%s'. Named Pipe: %s", host, unix_socket));
391
for (i=0 ; i < 100 ; i++) /* Don't retry forever */
393
if ((hPipe = CreateFile(pipe_name,
394
GENERIC_READ | GENERIC_WRITE,
399
NULL )) != INVALID_HANDLE_VALUE)
401
if (GetLastError() != ERROR_PIPE_BUSY)
403
set_mysql_extended_error(mysql, CR_NAMEDPIPEOPEN_ERROR,
404
unknown_sqlstate, ER(CR_NAMEDPIPEOPEN_ERROR),
405
host, unix_socket, (ulong) GetLastError());
406
return INVALID_HANDLE_VALUE;
408
/* wait for for an other instance */
409
if (! WaitNamedPipe(pipe_name, connect_timeout*1000) )
411
set_mysql_extended_error(mysql, CR_NAMEDPIPEWAIT_ERROR, unknown_sqlstate,
412
ER(CR_NAMEDPIPEWAIT_ERROR),
413
host, unix_socket, (ulong) GetLastError());
414
return INVALID_HANDLE_VALUE;
417
if (hPipe == INVALID_HANDLE_VALUE)
419
set_mysql_extended_error(mysql, CR_NAMEDPIPEOPEN_ERROR, unknown_sqlstate,
420
ER(CR_NAMEDPIPEOPEN_ERROR), host, unix_socket,
421
(ulong) GetLastError());
422
return INVALID_HANDLE_VALUE;
424
dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
425
if ( !SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL) )
427
CloseHandle( hPipe );
428
set_mysql_extended_error(mysql, CR_NAMEDPIPESETSTATE_ERROR,
429
unknown_sqlstate, ER(CR_NAMEDPIPESETSTATE_ERROR),
430
host, unix_socket, (ulong) GetLastError());
431
return INVALID_HANDLE_VALUE;
433
*arg_host=host ; *arg_unix_socket=unix_socket; /* connect arg */
440
Create new shared memory connection, return handler of connection
443
create_shared_memory()
444
mysql Pointer of mysql structure
445
net Pointer of net structure
446
connect_timeout Timeout of connection
450
HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
452
ulong smem_buffer_length = shared_memory_buffer_length + 4;
454
event_connect_request is event object for start connection actions
455
event_connect_answer is event object for confirm, that server put data
456
handle_connect_file_map is file-mapping object, use for create shared
458
handle_connect_map is pointer on shared memory
459
handle_map is pointer on shared memory for client
463
event_client_read are events for transfer data between server and client
464
handle_file_map is file-mapping object, use for create shared memory
466
HANDLE event_connect_request = NULL;
467
HANDLE event_connect_answer = NULL;
468
HANDLE handle_connect_file_map = NULL;
469
char *handle_connect_map = NULL;
471
char *handle_map = NULL;
472
HANDLE event_server_wrote = NULL;
473
HANDLE event_server_read = NULL;
474
HANDLE event_client_wrote = NULL;
475
HANDLE event_client_read = NULL;
476
HANDLE event_conn_closed = NULL;
477
HANDLE handle_file_map = NULL;
478
ulong connect_number;
479
char connect_number_char[22], *p;
482
DWORD error_allow = 0;
483
DWORD error_code = 0;
484
DWORD event_access_rights= SYNCHRONIZE | EVENT_MODIFY_STATE;
485
char *shared_memory_base_name = mysql->options.shared_memory_base_name;
488
get enough space base-name + '_' + longest suffix we might ever send
490
if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L, MYF(MY_FAE))))
494
The name of event and file-mapping events create agree next rule:
495
shared_memory_base_name+unique_part
497
shared_memory_base_name is unique value for each server
498
unique_part is uniquel value for each object (events and file-mapping)
500
suffix_pos = strxmov(tmp, "Global\\", shared_memory_base_name, "_", NullS);
501
strmov(suffix_pos, "CONNECT_REQUEST");
502
if (!(event_connect_request= OpenEvent(event_access_rights, FALSE, tmp)))
504
error_allow = CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR;
507
strmov(suffix_pos, "CONNECT_ANSWER");
508
if (!(event_connect_answer= OpenEvent(event_access_rights,FALSE,tmp)))
510
error_allow = CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR;
513
strmov(suffix_pos, "CONNECT_DATA");
514
if (!(handle_connect_file_map= OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)))
516
error_allow = CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR;
519
if (!(handle_connect_map= MapViewOfFile(handle_connect_file_map,
520
FILE_MAP_WRITE,0,0,sizeof(DWORD))))
522
error_allow = CR_SHARED_MEMORY_CONNECT_MAP_ERROR;
526
/* Send to server request of connection */
527
if (!SetEvent(event_connect_request))
529
error_allow = CR_SHARED_MEMORY_CONNECT_SET_ERROR;
533
/* Wait of answer from server */
534
if (WaitForSingleObject(event_connect_answer,connect_timeout*1000) !=
537
error_allow = CR_SHARED_MEMORY_CONNECT_ABANDONED_ERROR;
541
/* Get number of connection */
542
connect_number = uint4korr(handle_connect_map);/*WAX2*/
543
p= int10_to_str(connect_number, connect_number_char, 10);
546
The name of event and file-mapping events create agree next rule:
547
shared_memory_base_name+unique_part+number_of_connection
550
shared_memory_base_name is uniquel value for each server
551
unique_part is uniquel value for each object (events and file-mapping)
552
number_of_connection is number of connection between server and client
554
suffix_pos = strxmov(tmp, "Global\\", shared_memory_base_name, "_", connect_number_char,
556
strmov(suffix_pos, "DATA");
557
if ((handle_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL)
559
error_allow = CR_SHARED_MEMORY_FILE_MAP_ERROR;
562
if ((handle_map = MapViewOfFile(handle_file_map,FILE_MAP_WRITE,0,0,
563
smem_buffer_length)) == NULL)
565
error_allow = CR_SHARED_MEMORY_MAP_ERROR;
569
strmov(suffix_pos, "SERVER_WROTE");
570
if ((event_server_wrote = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
572
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
576
strmov(suffix_pos, "SERVER_READ");
577
if ((event_server_read = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
579
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
583
strmov(suffix_pos, "CLIENT_WROTE");
584
if ((event_client_wrote = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
586
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
590
strmov(suffix_pos, "CLIENT_READ");
591
if ((event_client_read = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
593
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
597
strmov(suffix_pos, "CONNECTION_CLOSED");
598
if ((event_conn_closed = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
600
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
604
Set event that server should send data
606
SetEvent(event_server_read);
609
if (error_allow == 0)
611
net->vio= vio_new_win32shared_memory(net,handle_file_map,handle_map,
613
event_server_read,event_client_wrote,
614
event_client_read,event_conn_closed);
618
error_code = GetLastError();
619
if (event_server_read)
620
CloseHandle(event_server_read);
621
if (event_server_wrote)
622
CloseHandle(event_server_wrote);
623
if (event_client_read)
624
CloseHandle(event_client_read);
625
if (event_client_wrote)
626
CloseHandle(event_client_wrote);
627
if (event_conn_closed)
628
CloseHandle(event_conn_closed);
630
UnmapViewOfFile(handle_map);
632
CloseHandle(handle_file_map);
636
my_free(tmp, MYF(0));
638
error_code = GetLastError();
639
if (event_connect_request)
640
CloseHandle(event_connect_request);
641
if (event_connect_answer)
642
CloseHandle(event_connect_answer);
643
if (handle_connect_map)
644
UnmapViewOfFile(handle_connect_map);
645
if (handle_connect_file_map)
646
CloseHandle(handle_connect_file_map);
649
if (error_allow == CR_SHARED_MEMORY_EVENT_ERROR)
650
set_mysql_extended_error(mysql, error_allow, unknown_sqlstate,
651
ER(error_allow), suffix_pos, error_code);
653
set_mysql_extended_error(mysql, error_allow, unknown_sqlstate,
654
ER(error_allow), error_code);
655
return(INVALID_HANDLE_VALUE);
661
/*****************************************************************************
662
Read a packet from server. Give error message if socket was down
663
or packet is an error message
664
*****************************************************************************/
667
cli_safe_read(MYSQL *mysql)
669
NET *net= &mysql->net;
671
init_sigpipe_variables
673
/* Don't give sigpipe errors if the client doesn't want them */
676
len=my_net_read(net);
677
reset_sigpipe(mysql);
679
if (len == packet_error || len == 0)
681
DBUG_PRINT("error",("Wrong connection or packet. fd: %s len: %lu",
682
vio_description(net->vio),len));
684
if (net->vio && vio_was_interrupted(net->vio))
685
return (packet_error);
686
#endif /*MYSQL_SERVER*/
688
set_mysql_error(mysql, net->last_errno == ER_NET_PACKET_TOO_LARGE ?
689
CR_NET_PACKET_TOO_LARGE: CR_SERVER_LOST, unknown_sqlstate);
690
return (packet_error);
692
if (net->read_pos[0] == 255)
696
char *pos=(char*) net->read_pos+1;
697
net->last_errno=uint2korr(pos);
700
if (protocol_41(mysql) && pos[0] == '#')
702
strmake(net->sqlstate, pos+1, SQLSTATE_LENGTH);
703
pos+= SQLSTATE_LENGTH+1;
708
The SQL state hasn't been received -- it should be reset to HY000
709
(unknown error sql state).
712
strmov(net->sqlstate, unknown_sqlstate);
715
(void) strmake(net->last_error,(char*) pos,
716
min((uint) len,(uint) sizeof(net->last_error)-1));
719
set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
721
Cover a protocol design error: error packet does not
722
contain the server status. Therefore, the client has no way
723
to find out whether there are more result sets of
724
a multiple-result-set statement pending. Luckily, in 5.0 an
725
error always aborts execution of a statement, wherever it is
726
a multi-statement or a stored procedure, so it should be
727
safe to unconditionally turn off the flag here.
729
mysql->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
731
DBUG_PRINT("error",("Got error: %d/%s (%s)",
735
return(packet_error);
740
void free_rows(MYSQL_DATA *cur)
744
free_root(&cur->alloc,MYF(0));
745
my_free((uchar*) cur,MYF(0));
750
cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
751
const uchar *header, ulong header_length,
752
const uchar *arg, ulong arg_length, my_bool skip_check,
755
NET *net= &mysql->net;
757
init_sigpipe_variables
758
my_bool stmt_skip= stmt ? stmt->state != MYSQL_STMT_INIT_DONE : FALSE;
759
DBUG_ENTER("cli_advanced_command");
761
/* Don't give sigpipe errors if the client doesn't want them */
764
if (mysql->net.vio == 0)
765
{ /* Do reconnect if possible */
766
if (mysql_reconnect(mysql) || stmt_skip)
769
if (mysql->status != MYSQL_STATUS_READY ||
770
mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
772
DBUG_PRINT("error",("state: %d", mysql->status));
773
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
777
net_clear_error(net);
779
mysql->affected_rows= ~(my_ulonglong) 0;
781
We don't want to clear the protocol buffer on COM_QUIT, because if
782
the previous command was a shutdown command, we may have the
783
response for the COM_QUIT already in the communication buffer
785
net_clear(&mysql->net, (command != COM_QUIT));
787
if (net_write_command(net,(uchar) command, header, header_length,
790
DBUG_PRINT("error",("Can't send command to server. Error: %d",
792
if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
794
set_mysql_error(mysql, CR_NET_PACKET_TOO_LARGE, unknown_sqlstate);
798
if (mysql_reconnect(mysql) || stmt_skip)
800
if (net_write_command(net,(uchar) command, header, header_length,
803
set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate);
809
result= ((mysql->packet_length=cli_safe_read(mysql)) == packet_error ?
812
reset_sigpipe(mysql);
813
DBUG_PRINT("exit",("result: %d", result));
817
void free_old_query(MYSQL *mysql)
819
DBUG_ENTER("free_old_query");
821
free_root(&mysql->field_alloc,MYF(0));
822
init_alloc_root(&mysql->field_alloc,8192,0); /* Assume rowlength < 8192 */
824
mysql->field_count= 0; /* For API */
825
mysql->warning_count= 0;
831
Flush result set sent from server
834
static void cli_flush_use_result(MYSQL *mysql)
836
/* Clear the current execution status */
837
DBUG_ENTER("cli_flush_use_result");
838
DBUG_PRINT("warning",("Not all packets read, clearing them"));
842
if ((pkt_len=cli_safe_read(mysql)) == packet_error)
844
if (pkt_len <= 8 && mysql->net.read_pos[0] == 254)
846
if (protocol_41(mysql))
848
char *pos= (char*) mysql->net.read_pos + 1;
849
mysql->warning_count=uint2korr(pos); pos+=2;
850
mysql->server_status=uint2korr(pos); pos+=2;
852
break; /* End of data */
860
static my_bool is_NT(void)
862
char *os=getenv("OS");
863
return (os && !strcmp(os, "Windows_NT")) ? 1 : 0;
870
Check server side variable 'license'.
872
If the variable does not exist or does not contain 'Commercial',
873
we're talking to non-commercial server from commercial client.
876
@retval !0 network error or the server is not commercial.
877
Error code is saved in mysql->net.last_errno.
880
static int check_license(MYSQL *mysql)
884
NET *net= &mysql->net;
885
static const char query[]= "SELECT @@license";
886
static const char required_license[]= STRINGIFY_ARG(LICENSE);
888
if (mysql_real_query(mysql, query, sizeof(query)-1))
890
if (net->last_errno == ER_UNKNOWN_SYSTEM_VARIABLE)
892
set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
893
ER(CR_WRONG_LICENSE), required_license);
897
if (!(res= mysql_use_result(mysql)))
899
row= mysql_fetch_row(res);
901
If no rows in result set, or column value is NULL (none of these
902
two is ever true for server variables now), or column value
903
mismatch, set wrong license error.
905
if (!net->last_errno &&
907
strncmp(row[0], required_license, sizeof(required_license))))
909
set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
910
ER(CR_WRONG_LICENSE), required_license);
912
mysql_free_result(res);
913
return net->last_errno;
915
#endif /* CHECK_LICENSE */
918
/**************************************************************************
920
**************************************************************************/
922
void end_server(MYSQL *mysql)
924
int save_errno= errno;
925
DBUG_ENTER("end_server");
926
if (mysql->net.vio != 0)
928
init_sigpipe_variables
929
DBUG_PRINT("info",("Net: %s", vio_description(mysql->net.vio)));
931
vio_delete(mysql->net.vio);
932
reset_sigpipe(mysql);
933
mysql->net.vio= 0; /* Marker */
935
net_end(&mysql->net);
936
free_old_query(mysql);
943
mysql_free_result(MYSQL_RES *result)
945
DBUG_ENTER("mysql_free_result");
946
DBUG_PRINT("enter",("mysql_res: 0x%lx", (long) result));
949
MYSQL *mysql= result->handle;
952
if (mysql->unbuffered_fetch_owner == &result->unbuffered_fetch_cancelled)
953
mysql->unbuffered_fetch_owner= 0;
954
if (mysql->status == MYSQL_STATUS_USE_RESULT)
956
(*mysql->methods->flush_use_result)(mysql);
957
mysql->status=MYSQL_STATUS_READY;
958
if (mysql->unbuffered_fetch_owner)
959
*mysql->unbuffered_fetch_owner= TRUE;
962
free_rows(result->data);
964
free_root(&result->field_alloc,MYF(0));
966
my_free((uchar*) result->row,MYF(0));
967
my_free((uchar*) result,MYF(0));
972
/****************************************************************************
973
Get options from my.cnf
974
****************************************************************************/
976
static const char *default_options[]=
978
"port","socket","compress","password","pipe", "timeout", "user",
979
"init-command", "host", "database", "debug", "return-found-rows",
980
"ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
981
"character-sets-dir", "default-character-set", "interactive-timeout",
982
"connect-timeout", "local-infile", "disable-local-infile",
983
"ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
984
"multi-results", "multi-statements", "multi-queries", "secure-auth",
985
"report-data-truncation",
989
static TYPELIB option_types={array_elements(default_options)-1,
990
"options",default_options, NULL};
992
const char *sql_protocol_names_lib[] =
993
{ "TCP", "SOCKET", "PIPE", "MEMORY", NullS };
994
TYPELIB sql_protocol_typelib = {array_elements(sql_protocol_names_lib)-1,"",
995
sql_protocol_names_lib, NULL};
997
static int add_init_command(struct st_mysql_options *options, const char *cmd)
1001
if (!options->init_commands)
1003
options->init_commands= (DYNAMIC_ARRAY*)my_malloc(sizeof(DYNAMIC_ARRAY),
1005
init_dynamic_array(options->init_commands,sizeof(char*),0,5 CALLER_INFO);
1008
if (!(tmp= my_strdup(cmd,MYF(MY_WME))) ||
1009
insert_dynamic(options->init_commands, (uchar*)&tmp))
1011
my_free(tmp, MYF(MY_ALLOW_ZERO_PTR));
1018
void mysql_read_default_options(struct st_mysql_options *options,
1019
const char *filename,const char *group)
1022
char *argv_buff[1],**argv;
1023
const char *groups[3];
1024
DBUG_ENTER("mysql_read_default_options");
1025
DBUG_PRINT("enter",("file: %s group: %s",filename,group ? group :"NULL"));
1027
argc=1; argv=argv_buff; argv_buff[0]= (char*) "client";
1028
groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0;
1030
load_defaults(filename, groups, &argc, &argv);
1031
if (argc != 1) /* If some default option */
1036
/* DBUG_PRINT("info",("option: %s",option[0])); */
1037
if (option[0][0] == '-' && option[0][1] == '-')
1039
char *end=strcend(*option,'=');
1044
*end=0; /* Remove '=' */
1046
/* Change all '_' in variable name to '-' */
1047
for (end= *option ; *(end= strcend(end,'_')) ; )
1049
switch (find_type(*option+2,&option_types,2)) {
1052
options->port=atoi(opt_arg);
1054
case 2: /* socket */
1057
my_free(options->unix_socket,MYF(MY_ALLOW_ZERO_PTR));
1058
options->unix_socket=my_strdup(opt_arg,MYF(MY_WME));
1061
case 3: /* compress */
1062
options->compress=1;
1063
options->client_flag|= CLIENT_COMPRESS;
1065
case 4: /* password */
1068
my_free(options->password,MYF(MY_ALLOW_ZERO_PTR));
1069
options->password=my_strdup(opt_arg,MYF(MY_WME));
1073
options->protocol = MYSQL_PROTOCOL_PIPE;
1074
case 20: /* connect_timeout */
1075
case 6: /* timeout */
1077
options->connect_timeout=atoi(opt_arg);
1082
my_free(options->user,MYF(MY_ALLOW_ZERO_PTR));
1083
options->user=my_strdup(opt_arg,MYF(MY_WME));
1086
case 8: /* init-command */
1087
add_init_command(options,opt_arg);
1092
my_free(options->host,MYF(MY_ALLOW_ZERO_PTR));
1093
options->host=my_strdup(opt_arg,MYF(MY_WME));
1096
case 10: /* database */
1099
my_free(options->db,MYF(MY_ALLOW_ZERO_PTR));
1100
options->db=my_strdup(opt_arg,MYF(MY_WME));
1103
case 11: /* debug */
1105
mysql_debug(opt_arg ? opt_arg : "d:t:o,/tmp/client.trace");
1108
case 12: /* return-found-rows */
1109
options->client_flag|=CLIENT_FOUND_ROWS;
1111
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
1112
case 13: /* ssl_key */
1113
my_free(options->ssl_key, MYF(MY_ALLOW_ZERO_PTR));
1114
options->ssl_key = my_strdup(opt_arg, MYF(MY_WME));
1116
case 14: /* ssl_cert */
1117
my_free(options->ssl_cert, MYF(MY_ALLOW_ZERO_PTR));
1118
options->ssl_cert = my_strdup(opt_arg, MYF(MY_WME));
1120
case 15: /* ssl_ca */
1121
my_free(options->ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
1122
options->ssl_ca = my_strdup(opt_arg, MYF(MY_WME));
1124
case 16: /* ssl_capath */
1125
my_free(options->ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
1126
options->ssl_capath = my_strdup(opt_arg, MYF(MY_WME));
1128
case 23: /* ssl_cipher */
1129
my_free(options->ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
1130
options->ssl_cipher= my_strdup(opt_arg, MYF(MY_WME));
1133
case 13: /* Ignore SSL options */
1139
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
1140
case 17: /* charset-lib */
1141
my_free(options->charset_dir,MYF(MY_ALLOW_ZERO_PTR));
1142
options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
1145
my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR));
1146
options->charset_name = my_strdup(opt_arg, MYF(MY_WME));
1148
case 19: /* Interactive-timeout */
1149
options->client_flag|= CLIENT_INTERACTIVE;
1152
if (!opt_arg || atoi(opt_arg) != 0)
1153
options->client_flag|= CLIENT_LOCAL_FILES;
1155
options->client_flag&= ~CLIENT_LOCAL_FILES;
1158
options->client_flag&= ~CLIENT_LOCAL_FILES;
1160
case 24: /* max-allowed-packet */
1162
options->max_allowed_packet= atoi(opt_arg);
1164
case 25: /* protocol */
1165
if ((options->protocol= find_type(opt_arg,
1166
&sql_protocol_typelib,0)) <= 0)
1168
fprintf(stderr, "Unknown option to protocol: %s\n", opt_arg);
1172
case 26: /* shared_memory_base_name */
1174
if (options->shared_memory_base_name != def_shared_memory_base_name)
1175
my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
1176
options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
1179
case 27: /* multi-results */
1180
options->client_flag|= CLIENT_MULTI_RESULTS;
1182
case 28: /* multi-statements */
1183
case 29: /* multi-queries */
1184
options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
1186
case 30: /* secure-auth */
1187
options->secure_auth= TRUE;
1189
case 31: /* report-data-truncation */
1190
options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
1193
DBUG_PRINT("warning",("unknown option: %s",option[0]));
1198
free_defaults(argv);
1203
/**************************************************************************
1204
Get column lengths of the current row
1205
If one uses mysql_use_result, res->lengths contains the length information,
1206
else the lengths are calculated from the offset between pointers.
1207
**************************************************************************/
1209
static void cli_fetch_lengths(ulong *to, MYSQL_ROW column,
1210
unsigned int field_count)
1216
prev_length=0; /* Keep gcc happy */
1217
for (end=column + field_count + 1 ; column != end ; column++, to++)
1224
if (start) /* Found end of prev string */
1225
*prev_length= (ulong) (*column-start-1);
1231
/***************************************************************************
1232
Change field rows to field structs
1233
***************************************************************************/
1236
unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
1237
my_bool default_value, uint server_capabilities)
1240
MYSQL_FIELD *field,*result;
1241
ulong lengths[9]; /* Max of fields */
1242
DBUG_ENTER("unpack_fields");
1244
field= result= (MYSQL_FIELD*) alloc_root(alloc,
1245
(uint) sizeof(*field)*fields);
1248
free_rows(data); /* Free old data */
1251
bzero((char*) field, (uint) sizeof(MYSQL_FIELD)*fields);
1252
if (server_capabilities & CLIENT_PROTOCOL_41)
1254
/* server is 4.1, and returns the new field result format */
1255
for (row=data->data; row ; row = row->next,field++)
1258
/* fields count may be wrong */
1259
DBUG_ASSERT((uint) (field - result) < fields);
1260
cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7);
1261
field->catalog= strmake_root(alloc,(char*) row->data[0], lengths[0]);
1262
field->db= strmake_root(alloc,(char*) row->data[1], lengths[1]);
1263
field->table= strmake_root(alloc,(char*) row->data[2], lengths[2]);
1264
field->org_table= strmake_root(alloc,(char*) row->data[3], lengths[3]);
1265
field->name= strmake_root(alloc,(char*) row->data[4], lengths[4]);
1266
field->org_name= strmake_root(alloc,(char*) row->data[5], lengths[5]);
1268
field->catalog_length= lengths[0];
1269
field->db_length= lengths[1];
1270
field->table_length= lengths[2];
1271
field->org_table_length= lengths[3];
1272
field->name_length= lengths[4];
1273
field->org_name_length= lengths[5];
1275
/* Unpack fixed length parts */
1276
pos= (uchar*) row->data[6];
1277
field->charsetnr= uint2korr(pos);
1278
field->length= (uint) uint4korr(pos+2);
1279
field->type= (enum enum_field_types) pos[6];
1280
field->flags= uint2korr(pos+7);
1281
field->decimals= (uint) pos[9];
1283
if (INTERNAL_NUM_FIELD(field))
1284
field->flags|= NUM_FLAG;
1285
if (default_value && row->data[7])
1287
field->def=strmake_root(alloc,(char*) row->data[7], lengths[7]);
1288
field->def_length= lengths[7];
1292
field->max_length= 0;
1295
#ifndef DELETE_SUPPORT_OF_4_0_PROTOCOL
1298
/* old protocol, for backward compatibility */
1299
for (row=data->data; row ; row = row->next,field++)
1301
cli_fetch_lengths(&lengths[0], row->data, default_value ? 6 : 5);
1302
field->org_table= field->table= strdup_root(alloc,(char*) row->data[0]);
1303
field->name= strdup_root(alloc,(char*) row->data[1]);
1304
field->length= (uint) uint3korr(row->data[2]);
1305
field->type= (enum enum_field_types) (uchar) row->data[3][0];
1307
field->catalog=(char*) "";
1308
field->db= (char*) "";
1309
field->catalog_length= 0;
1310
field->db_length= 0;
1311
field->org_table_length= field->table_length= lengths[0];
1312
field->name_length= lengths[1];
1314
if (server_capabilities & CLIENT_LONG_FLAG)
1316
field->flags= uint2korr(row->data[4]);
1317
field->decimals=(uint) (uchar) row->data[4][2];
1321
field->flags= (uint) (uchar) row->data[4][0];
1322
field->decimals=(uint) (uchar) row->data[4][1];
1324
if (INTERNAL_NUM_FIELD(field))
1325
field->flags|= NUM_FLAG;
1326
if (default_value && row->data[5])
1328
field->def=strdup_root(alloc,(char*) row->data[5]);
1329
field->def_length= lengths[5];
1333
field->max_length= 0;
1336
#endif /* DELETE_SUPPORT_OF_4_0_PROTOCOL */
1337
free_rows(data); /* Free old data */
1338
DBUG_RETURN(result);
1341
/* Read all rows (fields or data) from server */
1343
MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
1344
unsigned int fields)
1352
MYSQL_ROWS **prev_ptr,*cur;
1353
NET *net = &mysql->net;
1354
DBUG_ENTER("cli_read_rows");
1356
if ((pkt_len= cli_safe_read(mysql)) == packet_error)
1358
if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
1359
MYF(MY_WME | MY_ZEROFILL))))
1361
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
1364
init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */
1365
result->alloc.min_malloc=sizeof(MYSQL_ROWS);
1366
prev_ptr= &result->data;
1368
result->fields=fields;
1371
The last EOF packet is either a single 254 character or (in MySQL 4.1)
1372
254 followed by 1-7 status bytes.
1374
This doesn't conflict with normal usage of 254 which stands for a
1375
string where the length of the string is 8 bytes. (see net_field_length())
1378
while (*(cp=net->read_pos) != 254 || pkt_len >= 8)
1381
if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc,
1382
sizeof(MYSQL_ROWS))) ||
1383
!(cur->data= ((MYSQL_ROW)
1384
alloc_root(&result->alloc,
1385
(fields+1)*sizeof(char *)+pkt_len))))
1388
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
1392
prev_ptr= &cur->next;
1393
to= (char*) (cur->data+fields+1);
1394
end_to=to+pkt_len-1;
1395
for (field=0 ; field < fields ; field++)
1397
if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH)
1399
cur->data[field] = 0;
1403
cur->data[field] = to;
1404
if (len > (ulong) (end_to - to))
1407
set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
1410
memcpy(to,(char*) cp,len); to[len]=0;
1415
if (mysql_fields[field].max_length < len)
1416
mysql_fields[field].max_length=len;
1420
cur->data[field]=to; /* End of last field */
1421
if ((pkt_len=cli_safe_read(mysql)) == packet_error)
1427
*prev_ptr=0; /* last pointer is null */
1428
if (pkt_len > 1) /* MySQL 4.1 protocol */
1430
mysql->warning_count= uint2korr(cp+1);
1431
mysql->server_status= uint2korr(cp+3);
1432
DBUG_PRINT("info",("status: %u warning_count: %u",
1433
mysql->server_status, mysql->warning_count));
1435
DBUG_PRINT("exit", ("Got %lu rows", (ulong) result->rows));
1436
DBUG_RETURN(result);
1440
Read one row. Uses packet buffer as storage for fields.
1441
When next packet is read, the previous field values are destroyed
1446
read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
1450
uchar *pos, *prev_pos, *end_pos;
1451
NET *net= &mysql->net;
1453
if ((pkt_len=cli_safe_read(mysql)) == packet_error)
1455
if (pkt_len <= 8 && net->read_pos[0] == 254)
1457
if (pkt_len > 1) /* MySQL 4.1 protocol */
1459
mysql->warning_count= uint2korr(net->read_pos+1);
1460
mysql->server_status= uint2korr(net->read_pos+3);
1462
return 1; /* End of data */
1464
prev_pos= 0; /* allowed to write at packet[-1] */
1466
end_pos=pos+pkt_len;
1467
for (field=0 ; field < fields ; field++)
1469
if ((len=(ulong) net_field_length(&pos)) == NULL_LENGTH)
1476
if (len > (ulong) (end_pos - pos))
1478
set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
1481
row[field] = (char*) pos;
1486
*prev_pos=0; /* Terminate prev field */
1489
row[field]=(char*) prev_pos+1; /* End of last field */
1490
*prev_pos=0; /* Terminate last field */
1495
/****************************************************************************
1496
Init MySQL structure or allocate one
1497
****************************************************************************/
1500
mysql_init(MYSQL *mysql)
1502
if (mysql_server_init(0, NULL, NULL))
1506
if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL))))
1508
set_mysql_error(NULL, CR_OUT_OF_MEMORY, unknown_sqlstate);
1514
bzero((char*) (mysql), sizeof(*(mysql)));
1515
mysql->options.connect_timeout= CONNECT_TIMEOUT;
1516
mysql->charset=default_client_charset_info;
1517
strmov(mysql->net.sqlstate, not_error_sqlstate);
1520
Only enable LOAD DATA INFILE by default if configured with
1521
--enable-local-infile
1524
#if defined(ENABLED_LOCAL_INFILE) && !defined(MYSQL_SERVER)
1525
mysql->options.client_flag|= CLIENT_LOCAL_FILES;
1529
mysql->options.shared_memory_base_name= (char*) def_shared_memory_base_name;
1532
mysql->options.methods_to_use= MYSQL_OPT_GUESS_CONNECTION;
1533
mysql->options.report_data_truncation= TRUE; /* default */
1536
By default we don't reconnect because it could silently corrupt data (after
1537
reconnection you potentially lose table locks, user variables, session
1538
variables (transactions but they are specifically dealt with in
1540
This is a change: < 5.0.3 mysql->reconnect was set to 1 by default.
1541
How this change impacts existing apps:
1542
- existing apps which relyed on the default will see a behaviour change;
1543
they will have to set reconnect=1 after mysql_real_connect().
1544
- existing apps which explicitely asked for reconnection (the only way they
1545
could do it was by setting mysql.reconnect to 1 after mysql_real_connect())
1546
will not see a behaviour change.
1547
- existing apps which explicitely asked for no reconnection
1548
(mysql.reconnect=0) will not see a behaviour change.
1550
mysql->reconnect= 0;
1557
Fill in SSL part of MYSQL structure and set 'use_ssl' flag.
1558
NB! Errors are not reported until you do mysql_real_connect.
1561
#define strdup_if_not_null(A) (A) == 0 ? 0 : my_strdup((A),MYF(MY_WME))
1564
mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
1565
const char *key __attribute__((unused)),
1566
const char *cert __attribute__((unused)),
1567
const char *ca __attribute__((unused)),
1568
const char *capath __attribute__((unused)),
1569
const char *cipher __attribute__((unused)))
1571
DBUG_ENTER("mysql_ssl_set");
1572
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
1573
mysql->options.ssl_key= strdup_if_not_null(key);
1574
mysql->options.ssl_cert= strdup_if_not_null(cert);
1575
mysql->options.ssl_ca= strdup_if_not_null(ca);
1576
mysql->options.ssl_capath= strdup_if_not_null(capath);
1577
mysql->options.ssl_cipher= strdup_if_not_null(cipher);
1578
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
1584
Free strings in the SSL structure and clear 'use_ssl' flag.
1585
NB! Errors are not reported until you do mysql_real_connect.
1588
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
1591
mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
1593
struct st_VioSSLFd *ssl_fd= (struct st_VioSSLFd*) mysql->connector_fd;
1594
DBUG_ENTER("mysql_ssl_free");
1596
my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR));
1597
my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR));
1598
my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
1599
my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
1600
my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
1602
SSL_CTX_free(ssl_fd->ssl_context);
1603
my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR));
1604
mysql->options.ssl_key = 0;
1605
mysql->options.ssl_cert = 0;
1606
mysql->options.ssl_ca = 0;
1607
mysql->options.ssl_capath = 0;
1608
mysql->options.ssl_cipher= 0;
1609
mysql->options.use_ssl = FALSE;
1610
mysql->connector_fd = 0;
1614
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
1617
Return the SSL cipher (if any) used for current
1618
connection to the server.
1621
mysql_get_ssl_cipher()
1622
mysql pointer to the mysql connection
1626
const char * STDCALL
1627
mysql_get_ssl_cipher(MYSQL *mysql __attribute__((unused)))
1629
DBUG_ENTER("mysql_get_ssl_cipher");
1630
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
1631
if (mysql->net.vio && mysql->net.vio->ssl_arg)
1632
DBUG_RETURN(SSL_get_cipher_name((SSL*)mysql->net.vio->ssl_arg));
1633
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
1639
Check the server's (subject) Common Name against the
1640
hostname we connected to
1643
ssl_verify_server_cert()
1644
vio pointer to a SSL connected vio
1645
server_hostname name of the server that we connected to
1649
1 Failed to validate server
1653
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
1655
static int ssl_verify_server_cert(Vio *vio, const char* server_hostname)
1661
DBUG_ENTER("ssl_verify_server_cert");
1662
DBUG_PRINT("enter", ("server_hostname: %s", server_hostname));
1664
if (!(ssl= (SSL*)vio->ssl_arg))
1666
DBUG_PRINT("error", ("No SSL pointer found"));
1670
if (!server_hostname)
1672
DBUG_PRINT("error", ("No server hostname supplied"));
1676
if (!(server_cert= SSL_get_peer_certificate(ssl)))
1678
DBUG_PRINT("error", ("Could not get server certificate"));
1683
We already know that the certificate exchanged was valid; the SSL library
1684
handled that. Now we need to verify that the contents of the certificate
1688
X509_NAME_oneline(X509_get_subject_name(server_cert), buf, sizeof(buf));
1689
X509_free (server_cert);
1691
DBUG_PRINT("info", ("hostname in cert: %s", buf));
1692
cp1= strstr(buf, "/CN=");
1695
cp1+= 4; /* Skip the "/CN=" that we found */
1696
/* Search for next / which might be the delimiter for email */
1697
cp2= strchr(cp1, '/');
1700
DBUG_PRINT("info", ("Server hostname in cert: %s", cp1));
1701
if (!strcmp(cp1, server_hostname))
1707
DBUG_PRINT("error", ("SSL certificate validation failure"));
1711
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
1715
Note that the mysql argument must be initialized with mysql_init()
1716
before calling mysql_real_connect !
1719
static my_bool cli_read_query_result(MYSQL *mysql);
1720
static MYSQL_RES *cli_use_result(MYSQL *mysql);
1722
static MYSQL_METHODS client_methods=
1724
cli_read_query_result, /* read_query_result */
1725
cli_advanced_command, /* advanced_command */
1726
cli_read_rows, /* read_rows */
1727
cli_use_result, /* use_result */
1728
cli_fetch_lengths, /* fetch_lengths */
1729
cli_flush_use_result /* flush_use_result */
1730
#ifndef MYSQL_SERVER
1731
,cli_list_fields, /* list_fields */
1732
cli_read_prepare_result, /* read_prepare_result */
1733
cli_stmt_execute, /* stmt_execute */
1734
cli_read_binary_rows, /* read_binary_rows */
1735
cli_unbuffered_fetch, /* unbuffered_fetch */
1736
NULL, /* free_embedded_thd */
1737
cli_read_statistics, /* read_statistics */
1738
cli_read_query_result, /* next_result */
1739
cli_read_change_user_result, /* read_change_user_result */
1740
cli_read_binary_rows /* read_rows_from_cursor */
1745
int mysql_init_character_set(MYSQL *mysql)
1747
const char *default_collation_name;
1749
/* Set character set */
1750
if (!mysql->options.charset_name)
1752
default_collation_name= MYSQL_DEFAULT_COLLATION_NAME;
1753
if (!(mysql->options.charset_name=
1754
my_strdup(MYSQL_DEFAULT_CHARSET_NAME,MYF(MY_WME))))
1758
default_collation_name= NULL;
1761
const char *save= charsets_dir;
1762
if (mysql->options.charset_dir)
1763
charsets_dir=mysql->options.charset_dir;
1764
mysql->charset=get_charset_by_csname(mysql->options.charset_name,
1765
MY_CS_PRIMARY, MYF(MY_WME));
1766
if (mysql->charset && default_collation_name)
1768
CHARSET_INFO *collation;
1770
get_charset_by_name(default_collation_name, MYF(MY_WME))))
1772
if (!my_charset_same(mysql->charset, collation))
1774
my_printf_error(ER_UNKNOWN_ERROR,
1775
"COLLATION %s is not valid for CHARACTER SET %s",
1777
default_collation_name, mysql->options.charset_name);
1778
mysql->charset= NULL;
1782
mysql->charset= collation;
1786
mysql->charset= NULL;
1791
if (!mysql->charset)
1793
if (mysql->options.charset_dir)
1794
set_mysql_extended_error(mysql, CR_CANT_READ_CHARSET, unknown_sqlstate,
1795
ER(CR_CANT_READ_CHARSET),
1796
mysql->options.charset_name,
1797
mysql->options.charset_dir);
1800
char cs_dir_name[FN_REFLEN];
1801
get_charsets_dir(cs_dir_name);
1802
set_mysql_extended_error(mysql, CR_CANT_READ_CHARSET, unknown_sqlstate,
1803
ER(CR_CANT_READ_CHARSET),
1804
mysql->options.charset_name,
1815
CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
1816
const char *passwd, const char *db,
1817
uint port, const char *unix_socket,ulong client_flag)
1819
char buff[NAME_LEN+USERNAME_LENGTH+100];
1820
char *end,*host_info;
1822
NET *net= &mysql->net;
1824
thr_alarm_t alarmed;
1828
HANDLE hPipe=INVALID_HANDLE_VALUE;
1830
#ifdef HAVE_SYS_UN_H
1831
struct sockaddr_un UNIXaddr;
1833
init_sigpipe_variables
1834
DBUG_ENTER("mysql_real_connect");
1836
DBUG_PRINT("enter",("host: %s db: %s user: %s",
1837
host ? host : "(Null)",
1839
user ? user : "(Null)"));
1841
/* Don't give sigpipe errors if the client doesn't want them */
1843
mysql->methods= &client_methods;
1844
net->vio = 0; /* If something goes wrong */
1845
mysql->client_flag=0; /* For handshake */
1847
/* use default options */
1848
if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
1850
mysql_read_default_options(&mysql->options,
1851
(mysql->options.my_cnf_file ?
1852
mysql->options.my_cnf_file : "my"),
1853
mysql->options.my_cnf_group);
1854
my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
1855
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
1856
mysql->options.my_cnf_file=mysql->options.my_cnf_group=0;
1859
/* Some empty-string-tests are done because of ODBC */
1860
if (!host || !host[0])
1861
host=mysql->options.host;
1862
if (!user || !user[0])
1864
user=mysql->options.user;
1870
passwd=mysql->options.password;
1871
#if !defined(DONT_USE_MYSQL_PWD) && !defined(MYSQL_SERVER)
1873
passwd=getenv("MYSQL_PWD"); /* get it from environment */
1879
db=mysql->options.db;
1881
port=mysql->options.port;
1883
unix_socket=mysql->options.unix_socket;
1885
mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
1888
Part 0: Grab a socket and connect it to the server
1890
#if defined(HAVE_SMEM)
1891
if ((!mysql->options.protocol ||
1892
mysql->options.protocol == MYSQL_PROTOCOL_MEMORY) &&
1893
(!host || !strcmp(host,LOCAL_HOST)))
1895
if ((create_shared_memory(mysql,net, mysql->options.connect_timeout)) ==
1896
INVALID_HANDLE_VALUE)
1899
("host: '%s' socket: '%s' shared memory: %s have_tcpip: %d",
1900
host ? host : "<null>",
1901
unix_socket ? unix_socket : "<null>",
1902
(int) mysql->options.shared_memory_base_name,
1904
if (mysql->options.protocol == MYSQL_PROTOCOL_MEMORY)
1908
Try also with PIPE or TCP/IP. Clear the error from
1909
create_shared_memory().
1912
net_clear_error(net);
1916
mysql->options.protocol=MYSQL_PROTOCOL_MEMORY;
1918
host=mysql->options.shared_memory_base_name;
1919
my_snprintf(host_info=buff, sizeof(buff)-1,
1920
ER(CR_SHARED_MEMORY_CONNECTION), host);
1923
#endif /* HAVE_SMEM */
1924
#if defined(HAVE_SYS_UN_H)
1926
(!mysql->options.protocol ||
1927
mysql->options.protocol == MYSQL_PROTOCOL_SOCKET) &&
1928
(unix_socket || mysql_unix_port) &&
1929
(!host || !strcmp(host,LOCAL_HOST)))
1931
my_socket sock= socket(AF_UNIX, SOCK_STREAM, 0);
1932
if (sock == SOCKET_ERROR)
1934
set_mysql_extended_error(mysql, CR_SOCKET_CREATE_ERROR,
1936
ER(CR_SOCKET_CREATE_ERROR),
1941
net->vio= vio_new(sock, VIO_TYPE_SOCKET,
1942
VIO_LOCALHOST | VIO_BUFFERED_READ);
1945
DBUG_PRINT("error",("Unknow protocol %d ", mysql->options.protocol));
1946
set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
1953
unix_socket= mysql_unix_port;
1954
host_info= (char*) ER(CR_LOCALHOST_CONNECTION);
1955
DBUG_PRINT("info", ("Using UNIX sock '%s'", unix_socket));
1957
bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
1958
UNIXaddr.sun_family= AF_UNIX;
1959
strmake(UNIXaddr.sun_path, unix_socket, sizeof(UNIXaddr.sun_path)-1);
1961
if (my_connect(sock, (struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr),
1962
mysql->options.connect_timeout))
1964
DBUG_PRINT("error",("Got error %d on connect to local server",
1966
set_mysql_extended_error(mysql, CR_CONNECTION_ERROR,
1968
ER(CR_CONNECTION_ERROR),
1969
unix_socket, socket_errno);
1970
vio_delete(net->vio);
1974
mysql->options.protocol=MYSQL_PROTOCOL_SOCKET;
1976
#elif defined(__WIN__)
1978
(mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
1979
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
1980
(! have_tcpip && (unix_socket || !host && is_NT()))))
1982
if ((hPipe= create_named_pipe(mysql, mysql->options.connect_timeout,
1983
(char**) &host, (char**) &unix_socket)) ==
1984
INVALID_HANDLE_VALUE)
1987
("host: '%s' socket: '%s' have_tcpip: %d",
1988
host ? host : "<null>",
1989
unix_socket ? unix_socket : "<null>",
1991
if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
1992
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
1993
(unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE)))
1995
/* Try also with TCP/IP */
1999
net->vio=vio_new_win32pipe(hPipe);
2000
my_snprintf(host_info=buff, sizeof(buff)-1,
2001
ER(CR_NAMEDPIPE_CONNECTION), unix_socket);
2006
(!mysql->options.protocol ||
2007
mysql->options.protocol == MYSQL_PROTOCOL_TCP))
2009
struct addrinfo *res_lst, hints, *t_res;
2011
char port_buf[NI_MAXSERV];
2013
unix_socket=0; /* This is not used */
2021
my_snprintf(host_info=buff, sizeof(buff)-1, ER(CR_TCP_CONNECTION), host);
2022
DBUG_PRINT("info",("Server name: '%s'. TCP sock: %d", host, port));
2024
thr_alarm_init(&alarmed);
2025
thr_alarm(&alarmed, mysql->options.connect_timeout, &alarm_buff);
2028
DBUG_PRINT("info",("IP '%s'", "client"));
2031
thr_end_alarm(&alarmed);
2034
memset(&hints, 0, sizeof(hints));
2035
hints.ai_socktype= SOCK_STREAM;
2036
hints.ai_protocol= IPPROTO_TCP;
2037
hints.ai_family= AF_UNSPEC;
2039
DBUG_PRINT("info",("IPV6 getaddrinfo %s", host));
2040
my_snprintf(port_buf, NI_MAXSERV, "%d", port);
2041
gai_errno= getaddrinfo(host, port_buf, &hints, &res_lst);
2046
For DBUG we are keeping the right message but for client we default to
2047
historical error message.
2049
DBUG_PRINT("info",("IPV6 getaddrinfo error %d", gai_errno));
2050
set_mysql_extended_error(mysql, CR_UNKNOWN_HOST, unknown_sqlstate,
2051
ER(CR_UNKNOWN_HOST), host, errno);
2056
/* We only look at the first item (something to think about changing in the future) */
2059
my_socket sock= socket(t_res->ai_family, t_res->ai_socktype,
2060
t_res->ai_protocol);
2061
if (sock == SOCKET_ERROR)
2063
set_mysql_extended_error(mysql, CR_IPSOCK_ERROR, unknown_sqlstate,
2064
ER(CR_IPSOCK_ERROR), socket_errno);
2065
freeaddrinfo(res_lst);
2069
net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ);
2072
DBUG_PRINT("error",("Unknow protocol %d ", mysql->options.protocol));
2073
set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
2075
freeaddrinfo(res_lst);
2079
if (my_connect(sock, t_res->ai_addr, t_res->ai_addrlen,
2080
mysql->options.connect_timeout))
2082
DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno,
2084
set_mysql_extended_error(mysql, CR_CONN_HOST_ERROR, unknown_sqlstate,
2085
ER(CR_CONN_HOST_ERROR), host, socket_errno);
2086
vio_delete(net->vio);
2088
freeaddrinfo(res_lst);
2093
freeaddrinfo(res_lst);
2098
DBUG_PRINT("error",("Unknow protocol %d ",mysql->options.protocol));
2099
set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
2103
if (my_net_init(net, net->vio))
2105
vio_delete(net->vio);
2107
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
2110
vio_keepalive(net->vio,TRUE);
2112
/* If user set read_timeout, let it override the default */
2113
if (mysql->options.read_timeout)
2114
my_net_set_read_timeout(net, mysql->options.read_timeout);
2116
/* If user set write_timeout, let it override the default */
2117
if (mysql->options.write_timeout)
2118
my_net_set_write_timeout(net, mysql->options.write_timeout);
2120
if (mysql->options.max_allowed_packet)
2121
net->max_packet_size= mysql->options.max_allowed_packet;
2123
/* Get version info */
2124
mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */
2125
if (mysql->options.connect_timeout &&
2126
vio_poll_read(net->vio, mysql->options.connect_timeout))
2128
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2129
ER(CR_SERVER_LOST_EXTENDED),
2130
"waiting for initial communication packet",
2136
Part 1: Connection established, read and parse first packet
2139
if ((pkt_length=cli_safe_read(mysql)) == packet_error)
2141
if (mysql->net.last_errno == CR_SERVER_LOST)
2142
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2143
ER(CR_SERVER_LOST_EXTENDED),
2144
"reading initial communication packet",
2148
/* Check if version of protocol matches current one */
2150
mysql->protocol_version= net->read_pos[0];
2151
DBUG_DUMP("packet",(uchar*) net->read_pos,10);
2152
DBUG_PRINT("info",("mysql protocol version %d, server=%d",
2153
PROTOCOL_VERSION, mysql->protocol_version));
2154
if (mysql->protocol_version != PROTOCOL_VERSION)
2156
set_mysql_extended_error(mysql, CR_VERSION_ERROR, unknown_sqlstate,
2157
ER(CR_VERSION_ERROR), mysql->protocol_version,
2161
end=strend((char*) net->read_pos+1);
2162
mysql->thread_id=uint4korr(end+1);
2165
Scramble is split into two parts because old clients does not understand
2166
long scrambles; here goes the first part.
2168
strmake(mysql->scramble, end, SCRAMBLE_LENGTH_323);
2169
end+= SCRAMBLE_LENGTH_323+1;
2171
if (pkt_length >= (uint) (end+1 - (char*) net->read_pos))
2172
mysql->server_capabilities=uint2korr(end);
2173
if (pkt_length >= (uint) (end+18 - (char*) net->read_pos))
2175
/* New protocol with 16 bytes to describe server characteristics */
2176
mysql->server_language=end[2];
2177
mysql->server_status=uint2korr(end+3);
2180
if (pkt_length >= (uint) (end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1 -
2181
(char *) net->read_pos))
2182
strmake(mysql->scramble+SCRAMBLE_LENGTH_323, end,
2183
SCRAMBLE_LENGTH-SCRAMBLE_LENGTH_323);
2185
mysql->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
2187
if (mysql->options.secure_auth && passwd[0] &&
2188
!(mysql->server_capabilities & CLIENT_SECURE_CONNECTION))
2190
set_mysql_error(mysql, CR_SECURE_AUTH, unknown_sqlstate);
2194
if (mysql_init_character_set(mysql))
2197
/* Save connection information */
2198
if (!my_multi_malloc(MYF(0),
2199
&mysql->host_info, (uint) strlen(host_info)+1,
2200
&mysql->host, (uint) strlen(host)+1,
2201
&mysql->unix_socket,unix_socket ?
2202
(uint) strlen(unix_socket)+1 : (uint) 1,
2203
&mysql->server_version,
2204
(uint) (end - (char*) net->read_pos),
2206
!(mysql->user=my_strdup(user,MYF(0))) ||
2207
!(mysql->passwd=my_strdup(passwd,MYF(0))))
2209
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
2212
strmov(mysql->host_info,host_info);
2213
strmov(mysql->host,host);
2215
strmov(mysql->unix_socket,unix_socket);
2217
mysql->unix_socket=0;
2218
strmov(mysql->server_version,(char*) net->read_pos+1);
2222
Part 2: format and send client info to the server for access check
2225
client_flag|=mysql->options.client_flag;
2226
client_flag|=CLIENT_CAPABILITIES;
2227
if (client_flag & CLIENT_MULTI_STATEMENTS)
2228
client_flag|= CLIENT_MULTI_RESULTS;
2230
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
2231
if (mysql->options.ssl_key || mysql->options.ssl_cert ||
2232
mysql->options.ssl_ca || mysql->options.ssl_capath ||
2233
mysql->options.ssl_cipher)
2234
mysql->options.use_ssl= 1;
2235
if (mysql->options.use_ssl)
2236
client_flag|=CLIENT_SSL;
2237
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY*/
2239
client_flag|=CLIENT_CONNECT_WITH_DB;
2241
/* Remove options that server doesn't support */
2242
client_flag= ((client_flag &
2243
~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)) |
2244
(client_flag & mysql->server_capabilities));
2245
client_flag&= ~CLIENT_COMPRESS;
2247
if (client_flag & CLIENT_PROTOCOL_41)
2249
/* 4.1 server and 4.1 client has a 32 byte option flag */
2250
int4store(buff,client_flag);
2251
int4store(buff+4, net->max_packet_size);
2252
buff[8]= (char) mysql->charset->number;
2253
bzero(buff+9, 32-9);
2258
int2store(buff,client_flag);
2259
int3store(buff+2,net->max_packet_size);
2262
mysql->client_flag=client_flag;
2264
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
2265
if (client_flag & CLIENT_SSL)
2267
/* Do the SSL layering. */
2268
struct st_mysql_options *options= &mysql->options;
2269
struct st_VioSSLFd *ssl_fd;
2272
Send client_flag, max_packet_size - unencrypted otherwise
2273
the server does not know we want to do SSL
2275
if (my_net_write(net, (uchar*) buff, (uint) (end-buff)) || net_flush(net))
2277
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2278
ER(CR_SERVER_LOST_EXTENDED),
2279
"sending connection information to server",
2284
/* Create the VioSSLConnectorFd - init SSL and load certs */
2285
if (!(ssl_fd= new_VioSSLConnectorFd(options->ssl_key,
2288
options->ssl_capath,
2289
options->ssl_cipher)))
2291
set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
2294
mysql->connector_fd= (void*)ssl_fd;
2296
/* Connect to the server */
2297
DBUG_PRINT("info", ("IO layer change in progress..."));
2298
if (sslconnect(ssl_fd, mysql->net.vio,
2299
(long) (mysql->options.connect_timeout)))
2301
set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
2304
DBUG_PRINT("info", ("IO layer change done!"));
2306
/* Verify server cert */
2307
if ((client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
2308
ssl_verify_server_cert(mysql->net.vio, mysql->host))
2310
set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
2315
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
2317
DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu",
2318
mysql->server_version,mysql->server_capabilities,
2319
mysql->server_status, client_flag));
2320
/* This needs to be changed as it's not useful with big packets */
2321
if (user && user[0])
2322
strmake(end,user,USERNAME_LENGTH); /* Max user name */
2324
read_user_name((char*) end);
2326
/* We have to handle different version of handshake here */
2327
#ifdef _CUSTOMCONFIG_
2328
#include "_cust_libmysql.h"
2330
DBUG_PRINT("info",("user: %s",end));
2331
end= strend(end) + 1;
2334
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
2336
*end++= SCRAMBLE_LENGTH;
2337
scramble(end, mysql->scramble, passwd);
2338
end+= SCRAMBLE_LENGTH;
2342
scramble_323(end, mysql->scramble, passwd);
2343
end+= SCRAMBLE_LENGTH_323 + 1;
2347
*end++= '\0'; /* empty password */
2349
/* Add database if needed */
2350
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
2352
end= strmake(end, db, NAME_LEN) + 1;
2353
mysql->db= my_strdup(db,MYF(MY_WME));
2356
/* Write authentication package */
2357
if (my_net_write(net, (uchar*) buff, (size_t) (end-buff)) || net_flush(net))
2359
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2360
ER(CR_SERVER_LOST_EXTENDED),
2361
"sending authentication information",
2367
Part 3: Authorization data's been sent. Now server can reply with
2368
OK-packet, or re-request scrambled password.
2371
if ((pkt_length=cli_safe_read(mysql)) == packet_error)
2373
if (mysql->net.last_errno == CR_SERVER_LOST)
2374
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2375
ER(CR_SERVER_LOST_EXTENDED),
2376
"reading authorization packet",
2381
if (pkt_length == 1 && net->read_pos[0] == 254 &&
2382
mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
2385
By sending this very specific reply server asks us to send scrambled
2386
password in old format.
2388
scramble_323(buff, mysql->scramble, passwd);
2389
if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) ||
2392
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2393
ER(CR_SERVER_LOST_EXTENDED),
2394
"sending password information",
2398
/* Read what server thinks about out new auth message report */
2399
if (cli_safe_read(mysql) == packet_error)
2401
if (mysql->net.last_errno == CR_SERVER_LOST)
2402
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2403
ER(CR_SERVER_LOST_EXTENDED),
2404
"reading final connect information",
2410
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
2413
#ifdef CHECK_LICENSE
2414
if (check_license(mysql))
2418
if (db && mysql_select_db(mysql, db))
2420
if (mysql->net.last_errno == CR_SERVER_LOST)
2421
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2422
ER(CR_SERVER_LOST_EXTENDED),
2423
"Setting intital database",
2428
if (mysql->options.init_commands)
2430
DYNAMIC_ARRAY *init_commands= mysql->options.init_commands;
2431
char **ptr= (char**)init_commands->buffer;
2432
char **end_command= ptr + init_commands->elements;
2434
my_bool reconnect=mysql->reconnect;
2437
for (; ptr < end_command; ptr++)
2440
if (mysql_real_query(mysql,*ptr, (ulong) strlen(*ptr)))
2444
if (!(res= cli_use_result(mysql)))
2446
mysql_free_result(res);
2449
mysql->reconnect=reconnect;
2452
DBUG_PRINT("exit", ("Mysql handler: 0x%lx", (long) mysql));
2453
reset_sigpipe(mysql);
2457
reset_sigpipe(mysql);
2458
DBUG_PRINT("error",("message: %u/%s (%s)",
2463
/* Free alloced memory */
2465
mysql_close_free(mysql);
2466
if (!(((ulong) client_flag) & CLIENT_REMEMBER_OPTIONS))
2467
mysql_close_free_options(mysql);
2473
my_bool mysql_reconnect(MYSQL *mysql)
2476
DBUG_ENTER("mysql_reconnect");
2478
DBUG_PRINT("enter", ("mysql->reconnect: %d", mysql->reconnect));
2480
if (!mysql->reconnect ||
2481
(mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info)
2483
/* Allow reconnect next time */
2484
mysql->server_status&= ~SERVER_STATUS_IN_TRANS;
2485
set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate);
2488
mysql_init(&tmp_mysql);
2489
tmp_mysql.options= mysql->options;
2490
tmp_mysql.options.my_cnf_file= tmp_mysql.options.my_cnf_group= 0;
2492
if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
2493
mysql->db, mysql->port, mysql->unix_socket,
2494
mysql->client_flag | CLIENT_REMEMBER_OPTIONS))
2496
mysql->net.last_errno= tmp_mysql.net.last_errno;
2497
strmov(mysql->net.last_error, tmp_mysql.net.last_error);
2498
strmov(mysql->net.sqlstate, tmp_mysql.net.sqlstate);
2501
if (mysql_set_character_set(&tmp_mysql, mysql->charset->csname))
2503
DBUG_PRINT("error", ("mysql_set_character_set() failed"));
2504
bzero((char*) &tmp_mysql.options,sizeof(tmp_mysql.options));
2505
mysql_close(&tmp_mysql);
2506
mysql->net.last_errno= tmp_mysql.net.last_errno;
2507
strmov(mysql->net.last_error, tmp_mysql.net.last_error);
2508
strmov(mysql->net.sqlstate, tmp_mysql.net.sqlstate);
2512
DBUG_PRINT("info", ("reconnect succeded"));
2513
tmp_mysql.reconnect= 1;
2514
tmp_mysql.free_me= mysql->free_me;
2517
For each stmt in mysql->stmts, move it to tmp_mysql if it is
2518
in state MYSQL_STMT_INIT_DONE, otherwise close it.
2521
LIST *element= mysql->stmts;
2522
for (; element; element= element->next)
2524
MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
2525
if (stmt->state != MYSQL_STMT_INIT_DONE)
2528
stmt->last_errno= CR_SERVER_LOST;
2529
strmov(stmt->last_error, ER(CR_SERVER_LOST));
2530
strmov(stmt->sqlstate, unknown_sqlstate);
2534
tmp_mysql.stmts= list_add(tmp_mysql.stmts, &stmt->list);
2536
/* No need to call list_delete for statement here */
2541
/* Don't free options as these are now used in tmp_mysql */
2542
bzero((char*) &mysql->options,sizeof(mysql->options));
2546
net_clear(&mysql->net, 1);
2547
mysql->affected_rows= ~(my_ulonglong) 0;
2552
/**************************************************************************
2553
Set current database
2554
**************************************************************************/
2557
mysql_select_db(MYSQL *mysql, const char *db)
2560
DBUG_ENTER("mysql_select_db");
2561
DBUG_PRINT("enter",("db: '%s'",db));
2563
if ((error=simple_command(mysql,COM_INIT_DB, (const uchar*) db,
2564
(ulong) strlen(db),0)))
2566
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
2567
mysql->db=my_strdup(db,MYF(MY_WME));
2572
/*************************************************************************
2573
Send a QUIT to the server and close the connection
2574
If handle is alloced by mysql connect free it.
2575
*************************************************************************/
2577
static void mysql_close_free_options(MYSQL *mysql)
2579
DBUG_ENTER("mysql_close_free_options");
2581
my_free(mysql->options.user,MYF(MY_ALLOW_ZERO_PTR));
2582
my_free(mysql->options.host,MYF(MY_ALLOW_ZERO_PTR));
2583
my_free(mysql->options.password,MYF(MY_ALLOW_ZERO_PTR));
2584
my_free(mysql->options.unix_socket,MYF(MY_ALLOW_ZERO_PTR));
2585
my_free(mysql->options.db,MYF(MY_ALLOW_ZERO_PTR));
2586
my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
2587
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
2588
my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
2589
my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
2590
my_free(mysql->options.client_ip,MYF(MY_ALLOW_ZERO_PTR));
2591
if (mysql->options.init_commands)
2593
DYNAMIC_ARRAY *init_commands= mysql->options.init_commands;
2594
char **ptr= (char**)init_commands->buffer;
2595
char **end= ptr + init_commands->elements;
2596
for (; ptr<end; ptr++)
2597
my_free(*ptr,MYF(MY_WME));
2598
delete_dynamic(init_commands);
2599
my_free((char*)init_commands,MYF(MY_WME));
2601
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
2602
mysql_ssl_free(mysql);
2603
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
2605
if (mysql->options.shared_memory_base_name != def_shared_memory_base_name)
2606
my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
2607
#endif /* HAVE_SMEM */
2608
bzero((char*) &mysql->options,sizeof(mysql->options));
2613
static void mysql_close_free(MYSQL *mysql)
2615
my_free((uchar*) mysql->host_info,MYF(MY_ALLOW_ZERO_PTR));
2616
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
2617
my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
2618
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
2619
#if defined(EMBEDDED_LIBRARY) || MYSQL_VERSION_ID >= 50100
2620
my_free(mysql->info_buffer,MYF(MY_ALLOW_ZERO_PTR));
2621
mysql->info_buffer= 0;
2623
/* Clear pointers for better safety */
2624
mysql->host_info= mysql->user= mysql->passwd= mysql->db= 0;
2629
Clear connection pointer of every statement: this is necessary
2630
to give error on attempt to use a prepared statement of closed
2634
mysql_detach_stmt_list()
2635
stmt_list pointer to mysql->stmts
2636
func_name name of calling function
2639
There is similar code in mysql_reconnect(), so changes here
2640
should also be reflected there.
2643
void mysql_detach_stmt_list(LIST **stmt_list __attribute__((unused)),
2644
const char *func_name __attribute__((unused)))
2647
/* Reset connection handle in all prepared statements. */
2648
LIST *element= *stmt_list;
2649
char buff[MYSQL_ERRMSG_SIZE];
2650
DBUG_ENTER("mysql_detach_stmt_list");
2652
my_snprintf(buff, sizeof(buff)-1, ER(CR_STMT_CLOSED), func_name);
2653
for (; element; element= element->next)
2655
MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
2656
set_stmt_error(stmt, CR_STMT_CLOSED, unknown_sqlstate, buff);
2658
/* No need to call list_delete for statement here */
2662
#endif /* MYSQL_CLIENT */
2666
void STDCALL mysql_close(MYSQL *mysql)
2668
DBUG_ENTER("mysql_close");
2669
if (mysql) /* Some simple safety */
2671
/* If connection is still up, send a QUIT message */
2672
if (mysql->net.vio != 0)
2674
free_old_query(mysql);
2675
mysql->status=MYSQL_STATUS_READY; /* Force command */
2677
simple_command(mysql,COM_QUIT,(uchar*) 0,0,1);
2678
end_server(mysql); /* Sets mysql->net.vio= 0 */
2680
mysql_close_free_options(mysql);
2681
mysql_close_free(mysql);
2682
mysql_detach_stmt_list(&mysql->stmts, "mysql_close");
2683
#ifndef MYSQL_SERVER
2685
(*mysql->methods->free_embedded_thd)(mysql);
2688
my_free((uchar*) mysql,MYF(0));
2694
static my_bool cli_read_query_result(MYSQL *mysql)
2700
DBUG_ENTER("cli_read_query_result");
2702
if ((length = cli_safe_read(mysql)) == packet_error)
2704
free_old_query(mysql); /* Free old result */
2705
#ifdef MYSQL_CLIENT /* Avoid warn of unused labels*/
2708
pos=(uchar*) mysql->net.read_pos;
2709
if ((field_count= net_field_length(&pos)) == 0)
2711
mysql->affected_rows= net_field_length_ll(&pos);
2712
mysql->insert_id= net_field_length_ll(&pos);
2713
DBUG_PRINT("info",("affected_rows: %lu insert_id: %lu",
2714
(ulong) mysql->affected_rows,
2715
(ulong) mysql->insert_id));
2716
if (protocol_41(mysql))
2718
mysql->server_status=uint2korr(pos); pos+=2;
2719
mysql->warning_count=uint2korr(pos); pos+=2;
2721
else if (mysql->server_capabilities & CLIENT_TRANSACTIONS)
2723
/* MySQL 4.0 protocol */
2724
mysql->server_status=uint2korr(pos); pos+=2;
2725
mysql->warning_count= 0;
2727
DBUG_PRINT("info",("status: %u warning_count: %u",
2728
mysql->server_status, mysql->warning_count));
2729
if (pos < mysql->net.read_pos+length && net_field_length(&pos))
2730
mysql->info=(char*) pos;
2734
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
2738
if (!(mysql->options.client_flag & CLIENT_LOCAL_FILES))
2740
set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
2744
error= handle_local_infile(mysql,(char*) pos);
2745
if ((length= cli_safe_read(mysql)) == packet_error || error)
2747
goto get_info; /* Get info packet */
2750
if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
2751
mysql->server_status|= SERVER_STATUS_IN_TRANS;
2753
if (!(fields=cli_read_rows(mysql,(MYSQL_FIELD*)0, protocol_41(mysql) ? 7:5)))
2755
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
2756
(uint) field_count,0,
2757
mysql->server_capabilities)))
2759
mysql->status= MYSQL_STATUS_GET_RESULT;
2760
mysql->field_count= (uint) field_count;
2761
DBUG_PRINT("exit",("ok"));
2767
Send the query and return so we can do something else.
2768
Needs to be followed by mysql_read_query_result() when we want to
2769
finish processing it.
2773
mysql_send_query(MYSQL* mysql, const char* query, ulong length)
2775
DBUG_ENTER("mysql_send_query");
2776
DBUG_RETURN(simple_command(mysql, COM_QUERY, (uchar*) query, length, 1));
2781
mysql_real_query(MYSQL *mysql, const char *query, ulong length)
2783
DBUG_ENTER("mysql_real_query");
2784
DBUG_PRINT("enter",("handle: 0x%lx", (long) mysql));
2785
DBUG_PRINT("query",("Query = '%-.4096s'",query));
2787
if (mysql_send_query(mysql,query,length))
2789
DBUG_RETURN((int) (*mysql->methods->read_query_result)(mysql));
2793
/**************************************************************************
2794
Alloc result struct for buffered results. All rows are read to buffer.
2795
mysql_data_seek may be used.
2796
**************************************************************************/
2798
MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql)
2801
DBUG_ENTER("mysql_store_result");
2805
if (mysql->status != MYSQL_STATUS_GET_RESULT)
2807
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
2810
mysql->status=MYSQL_STATUS_READY; /* server is ready */
2811
if (!(result=(MYSQL_RES*) my_malloc((uint) (sizeof(MYSQL_RES)+
2813
mysql->field_count),
2814
MYF(MY_WME | MY_ZEROFILL))))
2816
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
2819
result->methods= mysql->methods;
2820
result->eof=1; /* Marker for buffered */
2821
result->lengths=(ulong*) (result+1);
2823
(*mysql->methods->read_rows)(mysql,mysql->fields,mysql->field_count)))
2825
my_free((uchar*) result,MYF(0));
2828
mysql->affected_rows= result->row_count= result->data->rows;
2829
result->data_cursor= result->data->data;
2830
result->fields= mysql->fields;
2831
result->field_alloc= mysql->field_alloc;
2832
result->field_count= mysql->field_count;
2833
/* The rest of result members is bzeroed in malloc */
2834
mysql->fields=0; /* fields is now in result */
2835
clear_alloc_root(&mysql->field_alloc);
2836
/* just in case this was mistakenly called after mysql_stmt_execute() */
2837
mysql->unbuffered_fetch_owner= 0;
2838
DBUG_RETURN(result); /* Data fetched */
2842
/**************************************************************************
2843
Alloc struct for use with unbuffered reads. Data is fetched by domand
2844
when calling to mysql_fetch_row.
2845
mysql_data_seek is a noop.
2847
No other queries may be specified with the same MYSQL handle.
2848
There shouldn't be much processing per row because mysql server shouldn't
2849
have to wait for the client (and will not wait more than 30 sec/packet).
2850
**************************************************************************/
2852
static MYSQL_RES * cli_use_result(MYSQL *mysql)
2855
DBUG_ENTER("cli_use_result");
2859
if (mysql->status != MYSQL_STATUS_GET_RESULT)
2861
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
2864
if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result)+
2865
sizeof(ulong)*mysql->field_count,
2866
MYF(MY_WME | MY_ZEROFILL))))
2868
result->lengths=(ulong*) (result+1);
2869
result->methods= mysql->methods;
2870
if (!(result->row=(MYSQL_ROW)
2871
my_malloc(sizeof(result->row[0])*(mysql->field_count+1), MYF(MY_WME))))
2872
{ /* Ptrs: to one row */
2873
my_free((uchar*) result,MYF(0));
2876
result->fields= mysql->fields;
2877
result->field_alloc= mysql->field_alloc;
2878
result->field_count= mysql->field_count;
2879
result->current_field=0;
2880
result->handle= mysql;
2881
result->current_row= 0;
2882
mysql->fields=0; /* fields is now in result */
2883
clear_alloc_root(&mysql->field_alloc);
2884
mysql->status=MYSQL_STATUS_USE_RESULT;
2885
mysql->unbuffered_fetch_owner= &result->unbuffered_fetch_cancelled;
2886
DBUG_RETURN(result); /* Data is read to be fetched */
2890
/**************************************************************************
2891
Return next row of the query results
2892
**************************************************************************/
2895
mysql_fetch_row(MYSQL_RES *res)
2897
DBUG_ENTER("mysql_fetch_row");
2899
{ /* Unbufferred fetch */
2902
MYSQL *mysql= res->handle;
2903
if (mysql->status != MYSQL_STATUS_USE_RESULT)
2905
set_mysql_error(mysql,
2906
res->unbuffered_fetch_cancelled ?
2907
CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC,
2910
else if (!(read_one_row(mysql, res->field_count, res->row, res->lengths)))
2913
DBUG_RETURN(res->current_row=res->row);
2915
DBUG_PRINT("info",("end of data"));
2917
mysql->status=MYSQL_STATUS_READY;
2919
Reset only if owner points to us: there is a chance that somebody
2920
started new query after mysql_stmt_close():
2922
if (mysql->unbuffered_fetch_owner == &res->unbuffered_fetch_cancelled)
2923
mysql->unbuffered_fetch_owner= 0;
2924
/* Don't clear handle in mysql_free_result */
2927
DBUG_RETURN((MYSQL_ROW) NULL);
2931
if (!res->data_cursor)
2933
DBUG_PRINT("info",("end of data"));
2934
DBUG_RETURN(res->current_row=(MYSQL_ROW) NULL);
2936
tmp = res->data_cursor->data;
2937
res->data_cursor = res->data_cursor->next;
2938
DBUG_RETURN(res->current_row=tmp);
2943
/**************************************************************************
2944
Get column lengths of the current row
2945
If one uses mysql_use_result, res->lengths contains the length information,
2946
else the lengths are calculated from the offset between pointers.
2947
**************************************************************************/
2950
mysql_fetch_lengths(MYSQL_RES *res)
2954
if (!(column=res->current_row))
2955
return 0; /* Something is wrong */
2957
(*res->methods->fetch_lengths)(res->lengths, column, res->field_count);
2958
return res->lengths;
2963
mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)
2965
DBUG_ENTER("mysql_option");
2966
DBUG_PRINT("enter",("option: %d",(int) option));
2968
case MYSQL_OPT_CONNECT_TIMEOUT:
2969
mysql->options.connect_timeout= *(uint*) arg;
2971
case MYSQL_OPT_READ_TIMEOUT:
2972
mysql->options.read_timeout= *(uint*) arg;
2974
case MYSQL_OPT_WRITE_TIMEOUT:
2975
mysql->options.write_timeout= *(uint*) arg;
2977
case MYSQL_OPT_COMPRESS:
2978
mysql->options.compress= 1; /* Remember for connect */
2979
mysql->options.client_flag|= CLIENT_COMPRESS;
2981
case MYSQL_OPT_NAMED_PIPE: /* This option is depricated */
2982
mysql->options.protocol=MYSQL_PROTOCOL_PIPE; /* Force named pipe */
2984
case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/
2985
if (!arg || test(*(uint*) arg))
2986
mysql->options.client_flag|= CLIENT_LOCAL_FILES;
2988
mysql->options.client_flag&= ~CLIENT_LOCAL_FILES;
2990
case MYSQL_INIT_COMMAND:
2991
add_init_command(&mysql->options,arg);
2993
case MYSQL_READ_DEFAULT_FILE:
2994
my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
2995
mysql->options.my_cnf_file=my_strdup(arg,MYF(MY_WME));
2997
case MYSQL_READ_DEFAULT_GROUP:
2998
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
2999
mysql->options.my_cnf_group=my_strdup(arg,MYF(MY_WME));
3001
case MYSQL_SET_CHARSET_DIR:
3002
my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
3003
mysql->options.charset_dir=my_strdup(arg,MYF(MY_WME));
3005
case MYSQL_SET_CHARSET_NAME:
3006
my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
3007
mysql->options.charset_name=my_strdup(arg,MYF(MY_WME));
3009
case MYSQL_OPT_PROTOCOL:
3010
mysql->options.protocol= *(uint*) arg;
3012
case MYSQL_SHARED_MEMORY_BASE_NAME:
3014
if (mysql->options.shared_memory_base_name != def_shared_memory_base_name)
3015
my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
3016
mysql->options.shared_memory_base_name=my_strdup(arg,MYF(MY_WME));
3019
case MYSQL_OPT_USE_REMOTE_CONNECTION:
3020
case MYSQL_OPT_USE_EMBEDDED_CONNECTION:
3021
case MYSQL_OPT_GUESS_CONNECTION:
3022
mysql->options.methods_to_use= option;
3024
case MYSQL_SET_CLIENT_IP:
3025
mysql->options.client_ip= my_strdup(arg, MYF(MY_WME));
3027
case MYSQL_SECURE_AUTH:
3028
mysql->options.secure_auth= *(my_bool *) arg;
3030
case MYSQL_REPORT_DATA_TRUNCATION:
3031
mysql->options.report_data_truncation= test(*(my_bool *) arg);
3033
case MYSQL_OPT_RECONNECT:
3034
mysql->reconnect= *(my_bool *) arg;
3036
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
3037
if (*(my_bool*) arg)
3038
mysql->options.client_flag|= CLIENT_SSL_VERIFY_SERVER_CERT;
3040
mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT;
3049
/****************************************************************************
3050
Functions to get information from the MySQL structure
3051
These are functions to make shared libraries more usable.
3052
****************************************************************************/
3055
my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res)
3057
return res->row_count;
3060
unsigned int STDCALL mysql_num_fields(MYSQL_RES *res)
3062
return res->field_count;
3065
uint STDCALL mysql_errno(MYSQL *mysql)
3067
return mysql ? mysql->net.last_errno : mysql_server_last_errno;
3071
const char * STDCALL mysql_error(MYSQL *mysql)
3073
return mysql ? mysql->net.last_error : mysql_server_last_error;
3078
Get version number for server in a form easy to test on
3081
mysql_get_server_version()
3088
We will ensure that a newer server always has a bigger number.
3091
Signed number > 323000
3095
mysql_get_server_version(MYSQL *mysql)
3097
uint major, minor, version;
3098
char *pos= mysql->server_version, *end_pos;
3099
major= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1;
3100
minor= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1;
3101
version= (uint) strtoul(pos, &end_pos, 10);
3102
return (ulong) major*10000L+(ulong) (minor*100+version);
3107
mysql_set_character_set function sends SET NAMES cs_name to
3108
the server (which changes character_set_client, character_set_result
3109
and character_set_connection) and updates mysql->charset so other
3110
functions like mysql_real_escape will work correctly.
3112
int STDCALL mysql_set_character_set(MYSQL *mysql, const char *cs_name)
3114
struct charset_info_st *cs;
3115
const char *save_csdir= charsets_dir;
3117
if (mysql->options.charset_dir)
3118
charsets_dir= mysql->options.charset_dir;
3120
if (strlen(cs_name) < MY_CS_NAME_SIZE &&
3121
(cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY, MYF(0))))
3123
char buff[MY_CS_NAME_SIZE + 10];
3124
charsets_dir= save_csdir;
3125
/* Skip execution of "SET NAMES" for pre-4.1 servers */
3126
if (mysql_get_server_version(mysql) < 40100)
3128
sprintf(buff, "SET NAMES %s", cs_name);
3129
if (!mysql_real_query(mysql, buff, strlen(buff)))
3136
char cs_dir_name[FN_REFLEN];
3137
get_charsets_dir(cs_dir_name);
3138
set_mysql_extended_error(mysql, CR_CANT_READ_CHARSET, unknown_sqlstate,
3139
ER(CR_CANT_READ_CHARSET), cs_name, cs_dir_name);
3141
charsets_dir= save_csdir;
3142
return mysql->net.last_errno;