diff options
author | unknown <hf@deer.(none)> | 2003-05-31 15:15:46 +0500 |
---|---|---|
committer | unknown <hf@deer.(none)> | 2003-05-31 15:15:46 +0500 |
commit | 62c7d2cd2711d3ab2b7d0adba2947b38168cc4b3 (patch) | |
tree | 4dd324e7d5c4509bfa76cfb1ebecf8f75b9cc6f5 | |
parent | 598f7ec5e353e7b601c6ade67031f0e74587a501 (diff) | |
download | mariadb-git-62c7d2cd2711d3ab2b7d0adba2947b38168cc4b3.tar.gz |
SCRUM:
Here is another pack of changes about gathering common client code in
sql-common/client.c.
Now i symlink the client.c from sql/ and libmysql/. These directories
have client_settings.h files to be included to client.c. It contains
defines and declarations to compile client.c in appropriate manner.
Also i've added include/sql_common.h, containing declarations of what
is exported from client.c
I removed as many #ifdef-s from client.c as i dared to. I think it's better
push it with some extra #ifdef-s now (of course, if everythihg besides it is
ok) so other people can check the code.
Makefile.am:
symlinking of sql-common/client.c was added
include/mysql.h:
MYSQL_CLIENT define moved here from libmysql/Makefile
libmysql/Makefile.am:
../libmysql/client_settings.h added to the list of necessary h-files
libmysql/Makefile.shared:
client.lo added to the list of objects
libmysql/libmysql.c:
a lot of changes about separating code between libmysql.c and client.c
mysys/default.c:
changed to keep compiler happy
sql-common/client.c:
a lot of changes about code separating
sql/Makefile.am:
mini_client.h has to be removed
sql/repl_failsafe.cc:
mysql_real_connect prototype was unified, so we've got to set connection timeout separately
sql/slave.cc:
trimming code to the changed function's prototypes
sql/sql_repl.cc:
mini_client isn't needed anymore
-rw-r--r-- | Makefile.am | 5 | ||||
-rw-r--r-- | include/mysql.h | 4 | ||||
-rw-r--r-- | include/sql_common.h | 53 | ||||
-rw-r--r-- | libmysql/Makefile.am | 5 | ||||
-rw-r--r-- | libmysql/Makefile.shared | 2 | ||||
-rw-r--r-- | libmysql/client_settings.h | 61 | ||||
-rw-r--r-- | libmysql/libmysql.c | 219 | ||||
-rw-r--r-- | mysys/default.c | 2 | ||||
-rw-r--r-- | sql-common/client.c | 584 | ||||
-rw-r--r-- | sql/Makefile.am | 8 | ||||
-rw-r--r-- | sql/client_settings.h | 33 | ||||
-rw-r--r-- | sql/repl_failsafe.cc | 5 | ||||
-rw-r--r-- | sql/slave.cc | 9 | ||||
-rw-r--r-- | sql/sql_repl.cc | 1 |
14 files changed, 624 insertions, 367 deletions
diff --git a/Makefile.am b/Makefile.am index 26c26357400..1fcf498a84b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -70,7 +70,10 @@ linked_netware_sources: #avoid recursive make calls in sql directory linked_server_sources: - cd sql; rm -f mini_client_errors.c;@LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c; rm -f pack.c;@LN_CP_F@ ../sql-common/pack.c pack.c + cd sql; rm -f mini_client_errors.c;\ + @LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c;\ + rm -f pack.c;@LN_CP_F@ ../sql-common/pack.c pack.c;\ + rm -f client.c;@LN_CP_F@ ../sql-common/client.c client.c echo timestamp > linked_server_sources # Create permission databases diff --git a/include/mysql.h b/include/mysql.h index 94f2152655d..91e4c6444ee 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -296,6 +296,10 @@ typedef struct st_mysql_res { #define MANAGER_CLIENT_ERR 450 #define MANAGER_INTERNAL_ERR 500 +#ifndef MYSQL_SERVER +#define MYSQL_CLIENT +#endif + typedef struct st_mysql_manager diff --git a/include/sql_common.h b/include/sql_common.h new file mode 100644 index 00000000000..aa4386a5623 --- /dev/null +++ b/include/sql_common.h @@ -0,0 +1,53 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + +#ifndef _sql_common_h +#define _sql_common_h + +extern const char *unknown_sqlstate; + +#ifdef __cplusplus +extern "C" { +#endif + +ulong STDCALL net_field_length(uchar **packet); +my_ulonglong net_field_length_ll(uchar **packet); + +MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, + my_bool default_value, uint server_capabilities); +my_bool advanced_command(MYSQL *mysql, enum enum_server_command command, + const char *header, ulong header_length, + const char *arg, ulong arg_length, my_bool skip_check); +void free_rows(MYSQL_DATA *cur); +MYSQL_DATA *read_rows (MYSQL *mysql,MYSQL_FIELD *fields, + uint field_count); +my_bool mysql_autenticate(MYSQL *mysql, const char *passwd); +void fetch_lengths(ulong *to, MYSQL_ROW column, uint field_count); +void free_old_query(MYSQL *mysql); +void end_server(MYSQL *mysql); +my_bool mysql_reconnect(MYSQL *mysql); +#ifdef __cplusplus +} +#endif + +#ifdef MYSQL_SERVER +#define protocol_41(A) FALSE +#else +#define protocol_41(A) ((A)->server_capabilities & CLIENT_PROTOCOL_41) +#endif + +#endif /* _sql_common_h */ diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am index 2e0a18d4677..128f1c03967 100644 --- a/libmysql/Makefile.am +++ b/libmysql/Makefile.am @@ -18,7 +18,7 @@ # This file is public domain and comes with NO WARRANTY of any kind target = libmysqlclient.la -target_defs = -DUNDEF_THREADS_HACK -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@ -DMYSQL_CLIENT +target_defs = -DUNDEF_THREADS_HACK -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@ LIBS = @CLIENT_LIBS@ INCLUDES = -I$(top_srcdir)/include $(openssl_includes) @@ -79,7 +79,8 @@ nh = my_global.h config-win32.h dbug.h errmsg.h \ m_ctype.h m_string.h \ my_alarm.h my_config.h my_dir.h my_list.h my_net.h my_sys.h \ mysql.h mysql_com.h mysql_version.h mysqld_error.h \ - mysys_err.h my_pthread.h thr_alarm.h violite.h hash.h + mysys_err.h my_pthread.h thr_alarm.h violite.h hash.h \ + sql_common.h ../libmysql/client_settings.h # Get a list of the needed objects lobjs = $(mysysobjects1) $(dbugobjects) $(mystringsobjects) $(sqlobjects) diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index 417b45c150d..9a5869c47ff 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -63,7 +63,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \ my_pread.lo mf_cache.lo md5.lo sha1.lo\ my_getopt.lo my_gethostbyname.lo my_port.lo sqlobjects = net.lo -sql_cmn_objects = pack.lo +sql_cmn_objects = pack.lo client.lo # Not needed in the minimum library mysysobjects2 = my_lib.lo diff --git a/libmysql/client_settings.h b/libmysql/client_settings.h new file mode 100644 index 00000000000..253f1515075 --- /dev/null +++ b/libmysql/client_settings.h @@ -0,0 +1,61 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + +#ifndef _client_settings_h +#define _client_settings_h +static my_bool mysql_client_init=0; +extern uint mysql_port; +extern my_string mysql_unix_port; + +#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG \ + | CLIENT_LOCAL_FILES | CLIENT_TRANSACTIONS \ + | CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION) + + +#ifdef __WIN__ +#define CONNECT_TIMEOUT 20 +#else +#define CONNECT_TIMEOUT 0 +#endif + +#ifdef HAVE_SMEM +char *shared_memory_base_name=0; +const char *def_shared_memory_base_name=default_shared_memory_base_name; +#endif + +static my_bool org_my_init_done=0; + +sig_handler pipe_sig_handler(int sig __attribute__((unused))); +my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list); +void read_user_name(char *name); +my_bool send_file_to_server(MYSQL *mysql, const char *filename); + +/* + Let the user specify that we don't want SIGPIPE; This doesn't however work + with threaded applications as we can have multiple read in progress. +*/ + +#if !defined(__WIN__) && defined(SIGPIPE) && !defined(THREAD) +#define init_sigpipe_variables sig_return old_signal_handler=(sig_return) 0; +#define set_sigpipe(mysql) if ((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE) old_signal_handler=signal(SIGPIPE,pipe_sig_handler) +#define reset_sigpipe(mysql) if ((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE) signal(SIGPIPE,old_signal_handler); +#else +#define init_sigpipe_variables +#define set_sigpipe(mysql) +#define reset_sigpipe(mysql) +#endif +#endif /* _client_settings_h */ diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 70f970d7442..766c62a03eb 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -57,14 +57,14 @@ #define INADDR_NONE -1 #endif -static my_bool mysql_client_init=0; +#include <sql_common.h> + uint mysql_port=0; my_string mysql_unix_port=0; ulong net_buffer_length=8192; ulong max_allowed_packet= 1024L*1024L*1024L; ulong net_read_timeout= NET_READ_TIMEOUT; ulong net_write_timeout= NET_WRITE_TIMEOUT; -const char *unknown_sqlstate= "000000"; #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG \ | CLIENT_LOCAL_FILES | CLIENT_TRANSACTIONS \ @@ -99,28 +99,16 @@ TYPELIB sql_protocol_typelib = {array_elements(sql_protocol_names_lib)-1,"", be changed */ #define MAX_LONG_DATA_LENGTH 8192 -#define protocol_41(A) ((A)->server_capabilities & CLIENT_PROTOCOL_41) +/*#define protocol_41(A) ((A)->server_capabilities & CLIENT_PROTOCOL_41)*/ #define unsigned_field(A) ((A)->flags & UNSIGNED_FLAG) -static MYSQL_DATA *read_rows (MYSQL *mysql,MYSQL_FIELD *fields, - uint field_count); -static int read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, - ulong *lengths); -static void end_server(MYSQL *mysql); -static void read_user_name(char *name); static void append_wild(char *to,char *end,const char *wild); -static my_bool mysql_reconnect(MYSQL *mysql); -static my_bool send_file_to_server(MYSQL *mysql,const char *filename); -static sig_handler pipe_sig_handler(int sig); +sig_handler pipe_sig_handler(int sig); static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, const char *from, ulong length); -static my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list); -static void fetch_lengths(ulong *to, MYSQL_ROW column, uint field_count); +my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list); static my_bool org_my_init_done=0; -extern ulong STDCALL net_field_length(uchar **packet); -extern my_ulonglong net_field_length_ll(uchar **packet); - int STDCALL mysql_server_init(int argc __attribute__((unused)), char **argv __attribute__((unused)), char **groups __attribute__((unused))) @@ -169,9 +157,10 @@ void STDCALL mysql_thread_end() #define reset_sigpipe(mysql) #endif +/* TO DELETE #define _libmysql_c #include "../sql-common/client.c" - +*/ static MYSQL* spawn_init(MYSQL* parent, const char* host, unsigned int port, const char* user, @@ -448,7 +437,7 @@ mysql_debug(const char *debug __attribute__((unused))) ARGSUSED **************************************************************************/ -static sig_handler +sig_handler pipe_sig_handler(int sig __attribute__((unused))) { DBUG_PRINT("info",("Hit by signal %d",sig)); @@ -869,6 +858,124 @@ error: DBUG_RETURN(1); } +#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL) +struct passwd *getpwuid(uid_t); +char* getlogin(void); +#endif + +#if defined(__NETWARE__) +/* default to "root" on NetWare */ +void read_user_name(char *name) +{ + char *str=getenv("USER"); + strmake(name, str ? str : "UNKNOWN_USER", USERNAME_LENGTH); +} + +#elif !defined(MSDOS) && ! defined(VMS) && !defined(__WIN__) && !defined(OS2) + +void read_user_name(char *name) +{ + DBUG_ENTER("read_user_name"); + if (geteuid() == 0) + (void) strmov(name,"root"); /* allow use of surun */ + else + { +#ifdef HAVE_GETPWUID + struct passwd *skr; + const char *str; + if ((str=getlogin()) == NULL) + { + if ((skr=getpwuid(geteuid())) != NULL) + str=skr->pw_name; + else if (!(str=getenv("USER")) && !(str=getenv("LOGNAME")) && + !(str=getenv("LOGIN"))) + str="UNKNOWN_USER"; + } + (void) strmake(name,str,USERNAME_LENGTH); +#elif HAVE_CUSERID + (void) cuserid(name); +#else + strmov(name,"UNKNOWN_USER"); +#endif + } + DBUG_VOID_RETURN; +} + +#else /* If MSDOS || VMS */ + +void read_user_name(char *name) +{ + char *str=getenv("USER"); /* ODBC will send user variable */ + strmake(name,str ? str : "ODBC", USERNAME_LENGTH); +} + +#endif + +my_bool send_file_to_server(MYSQL *mysql, const char *filename) +{ + int fd, readcount; + my_bool result= 1; + uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE); + char *buf, tmp_name[FN_REFLEN]; + NET *net= &mysql->net; + DBUG_ENTER("send_file_to_server"); + + if (!(buf=my_malloc(packet_length,MYF(0)))) + { + strmov(net->sqlstate, unknown_sqlstate); + strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY)); + DBUG_RETURN(1); + } + + fn_format(tmp_name,filename,"","",4); /* Convert to client format */ + if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0) + { + my_net_write(net,"",0); /* Server needs one packet */ + net_flush(net); + strmov(net->sqlstate, unknown_sqlstate); + net->last_errno=EE_FILENOTFOUND; + my_snprintf(net->last_error,sizeof(net->last_error)-1, + EE(net->last_errno),tmp_name, errno); + goto err; + } + + while ((readcount = (int) my_read(fd,(byte*) buf,packet_length,MYF(0))) > 0) + { + if (my_net_write(net,buf,readcount)) + { + DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file")); + strmov(net->sqlstate, unknown_sqlstate); + net->last_errno=CR_SERVER_LOST; + strmov(net->last_error,ER(net->last_errno)); + goto err; + } + } + /* Send empty packet to mark end of file */ + if (my_net_write(net,"",0) || net_flush(net)) + { + strmov(net->sqlstate, unknown_sqlstate); + net->last_errno=CR_SERVER_LOST; + sprintf(net->last_error,ER(net->last_errno),errno); + goto err; + } + if (readcount < 0) + { + strmov(net->sqlstate, unknown_sqlstate); + net->last_errno=EE_READ; /* the errmsg for not entire file read */ + my_snprintf(net->last_error,sizeof(net->last_error)-1, + tmp_name,errno); + goto err; + } + result=0; /* Ok */ + +err: + if (fd >= 0) + (void) my_close(fd,MYF(0)); + my_free(buf,MYF(0)); + DBUG_RETURN(result); +} + + /************************************************************************** Do a query. If query returned rows, free old rows. Read data by mysql_store_result or by repeat call of mysql_fetch_row @@ -880,7 +987,6 @@ mysql_query(MYSQL *mysql, const char *query) return mysql_real_query(mysql,query, (uint) strlen(query)); } - static MYSQL* spawn_init(MYSQL* parent, const char* host, unsigned int port, const char* user, const char* passwd) @@ -1074,7 +1180,6 @@ mysql_list_tables(MYSQL *mysql, const char *wild) DBUG_RETURN (mysql_store_result(mysql)); } - /************************************************************************** List all fields in a table If wild is given then only the fields matching wild is returned @@ -1116,7 +1221,6 @@ mysql_list_fields(MYSQL *mysql, const char *table, const char *wild) DBUG_RETURN(result); } - /* List all running processes (threads) in server */ MYSQL_RES * STDCALL @@ -1144,7 +1248,6 @@ mysql_list_processes(MYSQL *mysql) DBUG_RETURN(mysql_store_result(mysql)); } - #ifdef USE_OLD_FUNCTIONS int STDCALL mysql_create_db(MYSQL *mysql, const char *db) @@ -1280,64 +1383,6 @@ mysql_get_client_info(void) return (char*) MYSQL_SERVER_VERSION; } - -int STDCALL -mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg) -{ - DBUG_ENTER("mysql_option"); - DBUG_PRINT("enter",("option: %d",(int) option)); - switch (option) { - case MYSQL_OPT_CONNECT_TIMEOUT: - mysql->options.connect_timeout= *(uint*) arg; - break; - case MYSQL_OPT_COMPRESS: - mysql->options.compress= 1; /* Remember for connect */ - mysql->options.client_flag|= CLIENT_COMPRESS; - break; - case MYSQL_OPT_NAMED_PIPE: - mysql->options.protocol=MYSQL_PROTOCOL_PIPE; /* Force named pipe */ - break; - case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/ - if (!arg || test(*(uint*) arg)) - mysql->options.client_flag|= CLIENT_LOCAL_FILES; - else - mysql->options.client_flag&= ~CLIENT_LOCAL_FILES; - break; - case MYSQL_INIT_COMMAND: - add_init_command(&mysql->options,arg); - break; - case MYSQL_READ_DEFAULT_FILE: - my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR)); - mysql->options.my_cnf_file=my_strdup(arg,MYF(MY_WME)); - break; - case MYSQL_READ_DEFAULT_GROUP: - my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR)); - mysql->options.my_cnf_group=my_strdup(arg,MYF(MY_WME)); - break; - case MYSQL_SET_CHARSET_DIR: - my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR)); - mysql->options.charset_dir=my_strdup(arg,MYF(MY_WME)); - break; - case MYSQL_SET_CHARSET_NAME: - my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR)); - mysql->options.charset_name=my_strdup(arg,MYF(MY_WME)); - break; - case MYSQL_OPT_PROTOCOL: - mysql->options.protocol= *(uint*) arg; - break; - case MYSQL_SHARED_MEMORY_BASE_NAME: -#ifdef HAVE_SMEM - if (mysql->options.shared_memory_base_name != def_shared_memory_base_name) - my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); - mysql->options.shared_memory_base_name=my_strdup(arg,MYF(MY_WME)); -#endif - break; - default: - DBUG_RETURN(1); - } - DBUG_RETURN(0); -} - my_bool STDCALL mysql_eof(MYSQL_RES *res) { return res->eof; @@ -1380,21 +1425,11 @@ my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql) return mysql->last_used_con->insert_id; } -uint STDCALL mysql_errno(MYSQL *mysql) -{ - return mysql->net.last_errno; -} - const char *STDCALL mysql_sqlstate(MYSQL *mysql) { return mysql->net.sqlstate; } -const char * STDCALL mysql_error(MYSQL *mysql) -{ - return mysql->net.last_error; -} - uint STDCALL mysql_warning_count(MYSQL *mysql) { return mysql->warning_count; @@ -3519,7 +3554,7 @@ my_ulonglong STDCALL mysql_stmt_num_rows(MYSQL_STMT *stmt) 0 ok 1 error */ -static my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list) +my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list) { MYSQL *mysql; DBUG_ENTER("mysql_stmt_close"); diff --git a/mysys/default.c b/mysys/default.c index 17ee1b8c8da..7b02999160e 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -174,7 +174,7 @@ void load_defaults(const char *conf_file, const char **groups, res= (char**) (ptr+sizeof(alloc)); /* copy name + found arguments + command line arguments to new array */ - res[0]=*argc ? argv[0][0] : ""; + res[0]=*argc ? argv[0][0] : (char *)""; memcpy((gptr) (res+1), args.buffer, args.elements*sizeof(char*)); /* Skipp --defaults-file and --defaults-extra-file */ diff --git a/sql-common/client.c b/sql-common/client.c index 3e08c55737b..c586563cdc5 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1,6 +1,84 @@ -my_bool mysql_reconnect(MYSQL *mysql); -static my_bool send_file_to_server(MYSQL *mysql, const char *filename); -void end_server(MYSQL *mysql); +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <my_global.h> + +#if defined(MYSQL_SERVER) || defined(HAVE_EXTERNAL_CLIENT) + +#include "mysql.h" +#if !defined(MYSQL_SERVER) && defined(__WIN__) || defined(_WIN32) || defined(_WIN64) +#include <winsock.h> +#include <odbcinst.h> +#endif +#include <my_sys.h> +#include <mysys_err.h> +#include <m_string.h> +#include <m_ctype.h> +#include "mysql_version.h" +#include "mysqld_error.h" +#include "errmsg.h" +#include <violite.h> +#include <assert.h> +#if defined(THREAD) && !defined(__WIN__) +#include <my_pthread.h> /* because of signal() */ +#endif + +#if defined( OS2) && defined(MYSQL_SERVER) +#undef ER +#define ER CER +#endif + +#include <sys/stat.h> +#include <signal.h> +#include <time.h> + +#ifdef HAVE_PWD_H +#include <pwd.h> +#endif + +#if !defined(MSDOS) && !defined(__WIN__) +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#ifdef HAVE_SELECT_H +# include <select.h> +#endif +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif +#endif /*!defined(MSDOS) && !defined(__WIN__) */ +#ifdef HAVE_SYS_UN_H +# include <sys/un.h> +#endif + +#ifndef INADDR_NONE +#define INADDR_NONE -1 +#endif +#if defined(MSDOS) || defined(__WIN__) +#define perror(A) +#else +#include <errno.h> +#define SOCKET_ERROR -1 +#endif + +#include "client_settings.h" +#include <sql_common.h> + +const char *unknown_sqlstate= "000000"; /**************************************************************************** A modified version of connect(). my_connect() allows you to specify @@ -129,7 +207,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host, my_bool testing_named_pipes=0; char *host= *arg_host, *unix_socket= *arg_unix_socket; -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT if ( ! unix_socket || (unix_socket)[0] == 0x00) unix_socket = mysql_unix_port; #endif @@ -153,6 +231,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host, if (GetLastError() != ERROR_PIPE_BUSY) { net->last_errno=CR_NAMEDPIPEOPEN_ERROR; + strmov(net->sqlstate, unknown_sqlstate); sprintf(net->last_error,ER(net->last_errno),host, unix_socket, (ulong) GetLastError()); return INVALID_HANDLE_VALUE; @@ -161,6 +240,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host, if (! WaitNamedPipe(szPipeName, connect_timeout*1000) ) { net->last_errno=CR_NAMEDPIPEWAIT_ERROR; + strmov(net->sqlstate, unknown_sqlstate); sprintf(net->last_error,ER(net->last_errno),host, unix_socket, (ulong) GetLastError()); return INVALID_HANDLE_VALUE; @@ -169,6 +249,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host, if (hPipe == INVALID_HANDLE_VALUE) { net->last_errno=CR_NAMEDPIPEOPEN_ERROR; + strmov(net->sqlstate, unknown_sqlstate); sprintf(net->last_error,ER(net->last_errno),host, unix_socket, (ulong) GetLastError()); return INVALID_HANDLE_VALUE; @@ -178,6 +259,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host, { CloseHandle( hPipe ); net->last_errno=CR_NAMEDPIPESETSTATE_ERROR; + strmov(net->sqlstate, unknown_sqlstate); sprintf(net->last_error,ER(net->last_errno),host, unix_socket, (ulong) GetLastError()); return INVALID_HANDLE_VALUE; @@ -214,6 +296,7 @@ net_safe_read(MYSQL *mysql) CR_NET_PACKET_TOO_LARGE: CR_SERVER_LOST); strmov(net->last_error,ER(net->last_errno)); + strmov(net->sqlstate, unknown_sqlstate); return (packet_error); } if (net->read_pos[0] == 255) @@ -224,22 +307,28 @@ net_safe_read(MYSQL *mysql) net->last_errno=uint2korr(pos); pos+=2; len-=2; + if (protocol_41(mysql) && pos[0] == '#') + { + strmake(net->sqlstate, pos+1, SQLSTATE_LENGTH); + pos+= SQLSTATE_LENGTH+1; + } (void) strmake(net->last_error,(char*) pos, min((uint) len,(uint) sizeof(net->last_error)-1)); } else { net->last_errno=CR_UNKNOWN_ERROR; - (void) strmov(net->last_error,ER(net->last_errno)); + strmov(net->sqlstate, unknown_sqlstate); + strmov(net->last_error,ER(net->last_errno)); } - DBUG_PRINT("error",("Got error: %d (%s)", net->last_errno, - net->last_error)); + DBUG_PRINT("error",("Got error: %d/%s (%s)", + net->last_errno, net->sqlstate, net->last_error)); return(packet_error); } return len; } -static void free_rows(MYSQL_DATA *cur) +void free_rows(MYSQL_DATA *cur) { if (cur) { @@ -248,7 +337,7 @@ static void free_rows(MYSQL_DATA *cur) } } -static my_bool +my_bool advanced_command(MYSQL *mysql, enum enum_server_command command, const char *header, ulong header_length, const char *arg, ulong arg_length, my_bool skip_check) @@ -268,11 +357,13 @@ advanced_command(MYSQL *mysql, enum enum_server_command command, if (mysql->status != MYSQL_STATUS_READY) { strmov(net->last_error,ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC)); + strmov(net->sqlstate, unknown_sqlstate); return 1; } - mysql->net.last_error[0]=0; - mysql->net.last_errno=0; + net->last_error[0]=0; + net->last_errno=0; + strmov(net->sqlstate, unknown_sqlstate); mysql->net.report_error=0; mysql->info=0; mysql->affected_rows= ~(my_ulonglong) 0; @@ -318,7 +409,7 @@ simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg, return advanced_command(mysql, command, NullS, 0, arg, length, skip_check); } -static void free_old_query(MYSQL *mysql) +void free_old_query(MYSQL *mysql) { DBUG_ENTER("free_old_query"); if (mysql->fields) @@ -389,8 +480,6 @@ mysql_free_result(MYSQL_RES *result) DBUG_VOID_RETURN; } -#ifdef _libmysql_c - /**************************************************************************** Get options from my.cnf ****************************************************************************/ @@ -403,8 +492,8 @@ static const char *default_options[]= "character-sets-dir", "default-character-set", "interactive-timeout", "connect-timeout", "local-infile", "disable-local-infile", "replication-probe", "enable-reads-from-master", "repl-parse-query", - "ssl-cipher", "max-allowed-packet", - "protocol", "shared-memory-base-name", + "ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name", + "multi-results", "multi-queries", NullS }; @@ -517,9 +606,11 @@ static void mysql_read_default_options(struct st_mysql_options *options, options->db=my_strdup(opt_arg,MYF(MY_WME)); } break; +#ifdef MYSQL_CLIENT case 11: /* debug */ mysql_debug(opt_arg ? opt_arg : "d:t:o,/tmp/client.trace"); break; +#endif case 12: /* return-found-rows */ options->client_flag|=CLIENT_FOUND_ROWS; break; @@ -579,6 +670,7 @@ static void mysql_read_default_options(struct st_mysql_options *options, case 27: options->max_allowed_packet= atoi(opt_arg); break; +#ifdef MYSQL_CLIENT case 28: /* protocol */ if ((options->protocol = find_type(opt_arg, &sql_protocol_typelib,0)) == ~(ulong) 0) { @@ -586,6 +678,7 @@ static void mysql_read_default_options(struct st_mysql_options *options, exit(1); } break; +#endif case 29: /* shared_memory_base_name */ #ifdef HAVE_SMEM if (options->shared_memory_base_name != def_shared_memory_base_name) @@ -593,6 +686,12 @@ static void mysql_read_default_options(struct st_mysql_options *options, options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME)); #endif break; + case 30: + options->client_flag|= CLIENT_MULTI_RESULTS; + break; + case 31: + options->client_flag|= CLIENT_MULTI_QUERIES | CLIENT_MULTI_RESULTS; + break; default: DBUG_PRINT("warning",("unknown option: %s",option[0])); } @@ -603,15 +702,13 @@ static void mysql_read_default_options(struct st_mysql_options *options, DBUG_VOID_RETURN; } -#endif /*_libmysql_c*/ - /************************************************************************** Get column lengths of the current row If one uses mysql_use_result, res->lengths contains the length information, else the lengths are calculated from the offset between pointers. **************************************************************************/ -static void fetch_lengths(ulong *to, MYSQL_ROW column, uint field_count) +void fetch_lengths(ulong *to, MYSQL_ROW column, uint field_count) { ulong *prev_length; byte *start=0; @@ -648,6 +745,10 @@ unpack_fields_40(MYSQL_ROWS *row, MYSQL_FIELD *field, MEM_ROOT *alloc, field->length= (uint) uint3korr(row->data[2]); field->type= (enum enum_field_types) (uchar) row->data[3][0]; + field->catalog=(char*) ""; + field->db= (char*) ""; + field->catalog_length= 0; + field->db_length= 0; field->org_table_length= field->table_length= lengths[0]; field->name_length= lengths[1]; @@ -678,13 +779,15 @@ unpack_fields_40(MYSQL_ROWS *row, MYSQL_FIELD *field, MEM_ROOT *alloc, Change field rows to field structs ***************************************************************************/ -static MYSQL_FIELD * +MYSQL_FIELD * unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, my_bool default_value, uint server_capabilities) { +#ifdef MYSQL_CLIENT MYSQL_ROWS *row; +#endif MYSQL_FIELD *field,*result; - ulong lengths[8]; /* Max of fields */ + ulong lengths[9]; /* Max of fields */ DBUG_ENTER("unpack_fields"); field=result=(MYSQL_FIELD*) alloc_root(alloc, @@ -695,7 +798,7 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, DBUG_RETURN(0); } bzero((char*) field, (uint) sizeof(MYSQL_FIELD)*fields); -#ifdef _mini_client_c +#ifdef MYSQL_SERVER unpack_fields_40(data->data, field, alloc, lengths, default_value ? 6 : 5, default_value, server_capabilities & CLIENT_LONG_FLAG); #else @@ -705,33 +808,35 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, for (row=data->data; row ; row = row->next,field++) { uchar *pos; - fetch_lengths(&lengths[0], row->data, default_value ? 7 : 6); - field->db = strdup_root(alloc,(char*) row->data[0]); - field->table = strdup_root(alloc,(char*) row->data[1]); - field->org_table= strdup_root(alloc,(char*) row->data[2]); - field->name = strdup_root(alloc,(char*) row->data[3]); - field->org_name = strdup_root(alloc,(char*) row->data[4]); - - field->db_length= lengths[0]; - field->table_length= lengths[1]; - field->org_table_length= lengths[2]; - field->name_length= lengths[3]; - field->org_name_length= lengths[4]; + fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7); + field->catalog = strdup_root(alloc,(char*) row->data[0]); + field->db = strdup_root(alloc,(char*) row->data[1]); + field->table = strdup_root(alloc,(char*) row->data[2]); + field->org_table= strdup_root(alloc,(char*) row->data[3]); + field->name = strdup_root(alloc,(char*) row->data[4]); + field->org_name = strdup_root(alloc,(char*) row->data[5]); + + field->catalog_length= lengths[0]; + field->db_length= lengths[1]; + field->table_length= lengths[2]; + field->org_table_length= lengths[3]; + field->name_length= lengths[4]; + field->org_name_length= lengths[5]; /* Unpack fixed length parts */ - pos= (uchar*) row->data[5]; + pos= (uchar*) row->data[6]; field->charsetnr= uint2korr(pos); - field->length= (uint) uint3korr(pos+2); - field->type= (enum enum_field_types) pos[5]; - field->flags= uint2korr(pos+6); - field->decimals= (uint) pos[8]; + field->length= (uint) uint4korr(pos+2); + field->type= (enum enum_field_types) pos[6]; + field->flags= uint2korr(pos+7); + field->decimals= (uint) pos[9]; if (INTERNAL_NUM_FIELD(field)) field->flags|= NUM_FLAG; - if (default_value && row->data[6]) + if (default_value && row->data[7]) { - field->def=strdup_root(alloc,(char*) row->data[6]); - field->def_length= lengths[6]; + field->def=strdup_root(alloc,(char*) row->data[7]); + field->def_length= lengths[7]; } else field->def=0; @@ -743,14 +848,14 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, unpack_fields_40(data->data, field, alloc, lengths, default_value ? 6 : 5, default_value, server_capabilities & CLIENT_LONG_FLAG); #endif /* DELETE_SUPPORT_OF_4_0_PROTOCOL */ -#endif /*_mini_client_c*/ +#endif /*MYSQL_SERVER*/ free_rows(data); /* Free old data */ DBUG_RETURN(result); } /* Read all rows (fields or data) from server */ -static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, +MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, uint fields) { uint field; @@ -769,6 +874,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, MYF(MY_WME | MY_ZEROFILL)))) { net->last_errno=CR_OUT_OF_MEMORY; + strmov(net->sqlstate, unknown_sqlstate); strmov(net->last_error,ER(net->last_errno)); DBUG_RETURN(0); } @@ -797,6 +903,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, { free_rows(result); net->last_errno=CR_OUT_OF_MEMORY; + strmov(net->sqlstate, unknown_sqlstate); strmov(net->last_error,ER(net->last_errno)); DBUG_RETURN(0); } @@ -817,6 +924,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, { free_rows(result); net->last_errno=CR_MALFORMED_PACKET; + strmov(net->sqlstate, unknown_sqlstate); strmov(net->last_error,ER(net->last_errno)); DBUG_RETURN(0); } @@ -838,7 +946,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, } } *prev_ptr=0; /* last pointer is null */ -#ifndef _mini_client_c +#ifndef MYSQL_SERVER if (pkt_len > 1) /* MySQL 4.1 protocol */ { mysql->warning_count= uint2korr(cp+1); @@ -860,20 +968,21 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) { uint field; ulong pkt_len,len; - uchar *pos,*prev_pos, *end_pos; + uchar *pos, *prev_pos, *end_pos; + NET *net= &mysql->net; if ((pkt_len=net_safe_read(mysql)) == packet_error) return -1; - if (pkt_len <= 8 && mysql->net.read_pos[0] == 254) + if (pkt_len <= 8 && net->read_pos[0] == 254) { -#ifndef _mini_client_c +#ifndef MYSQL_SERVER if (pkt_len > 1) /* MySQL 4.1 protocol */ - mysql->warning_count= uint2korr(mysql->net.read_pos+1); + mysql->warning_count= uint2korr(net->read_pos+1); #endif return 1; /* End of data */ } prev_pos= 0; /* allowed to write at packet[-1] */ - pos=mysql->net.read_pos; + pos=net->read_pos; end_pos=pos+pkt_len; for (field=0 ; field < fields ; field++) { @@ -886,8 +995,9 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) { if (len > (ulong) (end_pos - pos)) { - mysql->net.last_errno=CR_UNKNOWN_ERROR; - strmov(mysql->net.last_error,ER(mysql->net.last_errno)); + net->last_errno=CR_UNKNOWN_ERROR; + strmov(net->last_error,ER(net->last_errno)); + strmov(net->sqlstate, unknown_sqlstate); return -1; } row[field] = (char*) pos; @@ -920,7 +1030,7 @@ mysql_init(MYSQL *mysql) } else bzero((char*) (mysql),sizeof(*(mysql))); -#ifndef _mini_client_c +#ifndef MYSQL_SERVER mysql->options.connect_timeout=CONNECT_TIMEOUT; mysql->last_used_con = mysql->next_slave = mysql->master = mysql; /* @@ -944,14 +1054,12 @@ mysql_init(MYSQL *mysql) mysql->options.shared_memory_base_name=(char*)def_shared_memory_base_name; #endif -#else /*_mini_client_c*/ +#else /*MYSQL_SERVER*/ #ifdef __WIN__ mysql->options.connect_timeout=20; #endif - mysql->net.read_timeout = slave_net_timeout; - -#endif /*_mini_client_c*/ +#endif /*MYSQL_SERVER*/ return mysql; } @@ -971,7 +1079,7 @@ mysql_init(MYSQL *mysql) void mysql_once_init(void) { -#ifndef _mini_client_c +#ifndef MYSQL_SERVER if (!mysql_client_init) { @@ -1014,9 +1122,9 @@ void mysql_once_init(void) my_thread_init(); /* Init if new thread */ #endif -#else /*_mini_client_c*/ +#else /*MYSQL_SERVER*/ init_client_errs(); -#endif /*_mini_client_c*/ +#endif /*MYSQL_SERVER*/ } @@ -1024,7 +1132,7 @@ void mysql_once_init(void) Handle password authentication */ -static my_bool mysql_autenticate(MYSQL *mysql, const char *passwd) +my_bool mysql_autenticate(MYSQL *mysql, const char *passwd) { ulong pkt_length; NET *net= &mysql->net; @@ -1074,6 +1182,7 @@ static my_bool mysql_autenticate(MYSQL *mysql, const char *passwd) if (my_net_write(net,buff,SCRAMBLE41_LENGTH) || net_flush(net)) { net->last_errno= CR_SERVER_LOST; + strmov(net->sqlstate, unknown_sqlstate); strmov(net->last_error,ER(net->last_errno)); goto error; } @@ -1088,60 +1197,6 @@ error: return 1; } -#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL) -struct passwd *getpwuid(uid_t); -char* getlogin(void); -#endif - - -#if defined(__NETWARE__) -/* default to "root" on NetWare */ -static void read_user_name(char *name) -{ - char *str=getenv("USER"); - strmake(name, str ? str : "UNKNOWN_USER", USERNAME_LENGTH); -} - -#elif !defined(MSDOS) && ! defined(VMS) && !defined(__WIN__) && !defined(OS2) - -static void read_user_name(char *name) -{ - DBUG_ENTER("read_user_name"); - if (geteuid() == 0) - (void) strmov(name,"root"); /* allow use of surun */ - else - { -#ifdef HAVE_GETPWUID - struct passwd *skr; - const char *str; - if ((str=getlogin()) == NULL) - { - if ((skr=getpwuid(geteuid())) != NULL) - str=skr->pw_name; - else if (!(str=getenv("USER")) && !(str=getenv("LOGNAME")) && - !(str=getenv("LOGIN"))) - str="UNKNOWN_USER"; - } - (void) strmake(name,str,USERNAME_LENGTH); -#elif HAVE_CUSERID - (void) cuserid(name); -#else - strmov(name,"UNKNOWN_USER"); -#endif - } - DBUG_VOID_RETURN; -} - -#else /* If MSDOS || VMS */ - -static void read_user_name(char *name) -{ - char *str=getenv("USER"); /* ODBC will send user variable */ - strmake(name,str ? str : "ODBC", USERNAME_LENGTH); -} - -#endif - /* Note that the mysql argument must be initialized with mysql_init() before calling mysql_real_connect ! @@ -1150,20 +1205,20 @@ static void read_user_name(char *name) MYSQL * STDCALL mysql_real_connect(MYSQL *mysql,const char *host, const char *user, const char *passwd, const char *db, - uint port, const char *unix_socket,ulong client_flag -#ifdef _mini_client_c - , uint net_read_timeout -#endif -) + uint port, const char *unix_socket,ulong client_flag) { - char buff[NAME_LEN+USERNAME_LENGTH+100],charset_name_buff[16]; - char *end,*host_info,*charset_name; +#ifdef MYSQL_CLIENT + char *charset_name; + char charset_name_buff[16]; +#endif + char buff[NAME_LEN+USERNAME_LENGTH+100]; + char *end,*host_info; my_socket sock; uint32 ip_addr; struct sockaddr_in sock_addr; ulong pkt_length; NET *net= &mysql->net; -#ifdef _mini_client_c +#ifdef MYSQL_SERVER thr_alarm_t alarmed; ALARM alarm_buff; ulong max_allowed_packet; @@ -1187,11 +1242,11 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, /* Don't give sigpipe errors if the client doesn't want them */ set_sigpipe(mysql); net->vio = 0; /* If something goes wrong */ -#ifdef _mini_client_c + mysql->client_flag=0; /* For handshake */ +#ifdef MYSQL_SERVER mysql->charset=default_charset_info; /* Set character set */ #endif -#ifdef _libmysql_c /* use default options */ if (mysql->options.my_cnf_file || mysql->options.my_cnf_group) { @@ -1223,15 +1278,6 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, port=mysql->options.port; if (!unix_socket) unix_socket=mysql->options.unix_socket; -#endif /*_libmysql_c*/ -#ifdef _mini_client_c - if (!port) - port = MYSQL_PORT; /* Should always be set by mysqld */ - if (!unix_socket) - unix_socket=MYSQL_UNIX_ADDR; - if (!mysql->options.connect_timeout) - mysql->options.connect_timeout= net_read_timeout; -#endif /*mini_client_c*/ mysql->reconnect=1; /* Reconnect as default */ mysql->server_status=SERVER_STATUS_AUTOCOMMIT; @@ -1239,7 +1285,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, /* Grab a socket and connect it to the server */ -#if defined(_libmysql_c) && defined(HAVE_SMEM) +#if defined(MYSQL_CLIENT) && defined(HAVE_SMEM) if ((!mysql->options.protocol || mysql->options.protocol == MYSQL_PROTOCOL_MEMORY) && (!host || !strcmp(host,LOCAL_HOST))) @@ -1269,18 +1315,18 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, #endif /* HAVE_SMEM */ #if defined(HAVE_SYS_UN_H) if ( -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT (!mysql->options.protocol || mysql->options.protocol == MYSQL_PROTOCOL_SOCKET)&& (unix_socket || mysql_unix_port) && #endif -#ifdef _mini_client_c +#ifdef MYSQL_SERVER unix_socket && #endif (!host || !strcmp(host,LOCAL_HOST))) { host=LOCAL_HOST; -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT if (!unix_socket) unix_socket=mysql_unix_port; #endif @@ -1289,6 +1335,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if ((sock = socket(AF_UNIX,SOCK_STREAM,0)) == SOCKET_ERROR) { net->last_errno=CR_SOCKET_CREATE_ERROR; + strmov(net->sqlstate, unknown_sqlstate); sprintf(net->last_error,ER(net->last_errno),socket_errno); goto error; } @@ -1302,10 +1349,11 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, DBUG_PRINT("error",("Got error %d on connect to local server", socket_errno)); net->last_errno=CR_CONNECTION_ERROR; + strmov(net->sqlstate, unknown_sqlstate); sprintf(net->last_error,ER(net->last_errno),unix_socket,socket_errno); goto error; } -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT else mysql->options.protocol=MYSQL_PROTOCOL_SOCKET; #endif @@ -1313,13 +1361,13 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, else #elif defined(__WIN__) { -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT if ((!mysql->options.protocol || mysql->options.protocol == MYSQL_PROTOCOL_PIPE)&& ((unix_socket || !host && is_NT() || host && !strcmp(host,LOCAL_HOST_NAMEDPIPE) ||! have_tcpip))&& (!net->vio)) -#elif _mini_client_c +#elif MYSQL_SERVER if ((unix_socket || !host && is_NT() || host && !strcmp(host,LOCAL_HOST_NAMEDPIPE) || @@ -1350,17 +1398,17 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, } } } -#ifdef _mini_client_c +#ifdef MYSQL_SERVER if (hPipe == INVALID_HANDLE_VALUE) #endif #endif -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT if ((!mysql->options.protocol || mysql->options.protocol == MYSQL_PROTOCOL_TCP)&&(!net->vio)) #endif { unix_socket=0; /* This is not used */ -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT if (!port) port=mysql_port; #endif @@ -1368,18 +1416,19 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, host=LOCAL_HOST; sprintf(host_info=buff,ER(CR_TCP_CONNECTION),host); DBUG_PRINT("info",("Server name: '%s'. TCP sock: %d", host,port)); -#ifdef _mini_client_c +#ifdef MYSQL_SERVER thr_alarm_init(&alarmed); - thr_alarm(&alarmed, net_read_timeout, &alarm_buff); + thr_alarm(&alarmed, mysql->options.connect_timeout, &alarm_buff); #endif sock = (my_socket) socket(AF_INET,SOCK_STREAM,0); -#ifdef _mini_client_c +#ifdef MYSQL_SERVER thr_end_alarm(&alarmed); #endif /* _WIN64 ; Assume that the (int) range is enough for socket() */ if (sock == SOCKET_ERROR) { net->last_errno=CR_IPSOCK_ERROR; + strmov(net->sqlstate, unknown_sqlstate); sprintf(net->last_error,ER(net->last_errno),socket_errno); goto error; } @@ -1406,6 +1455,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, { my_gethostbyname_r_free(); net->last_errno=CR_UNKNOWN_HOST; + strmov(net->sqlstate, unknown_sqlstate); sprintf(net->last_error, ER(CR_UNKNOWN_HOST), host, tmp_errno); goto error; } @@ -1419,29 +1469,32 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno, host)); net->last_errno= CR_CONN_HOST_ERROR; + strmov(net->sqlstate, unknown_sqlstate); sprintf(net->last_error ,ER(CR_CONN_HOST_ERROR), host, socket_errno); goto error; } } -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT else if (!net->vio) { DBUG_PRINT("error",("Unknow protocol %d ",mysql->options.protocol)); net->last_errno= CR_CONN_UNKNOW_PROTOCOL; + strmov(net->sqlstate, unknown_sqlstate); sprintf(net->last_error ,ER(CR_CONN_UNKNOW_PROTOCOL)); goto error; } -#endif /*_libmysql_c*/ +#endif /*MYSQL_CLIENT*/ if (!net->vio || my_net_init(net, net->vio)) { vio_delete(net->vio); net->vio = 0; net->last_errno=CR_OUT_OF_MEMORY; + strmov(net->sqlstate, unknown_sqlstate); strmov(net->last_error,ER(net->last_errno)); goto error; } vio_keepalive(net->vio,TRUE); -#ifdef _mini_client_c +#ifdef MYSQL_SERVER net->read_timeout=slave_net_timeout; #endif /* Get version info */ @@ -1450,6 +1503,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, vio_poll_read(net->vio, mysql->options.connect_timeout)) { net->last_errno= CR_SERVER_LOST; + strmov(net->sqlstate, unknown_sqlstate); strmov(net->last_error,ER(net->last_errno)); goto error; } @@ -1463,10 +1517,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, DBUG_PRINT("info",("mysql protocol version %d, server=%d", PROTOCOL_VERSION, mysql->protocol_version)); if (mysql->protocol_version != PROTOCOL_VERSION -#ifdef _mini_client_c - && mysql->protocol_version != PROTOCOL_VERSION-1 -#endif - ) + && mysql->protocol_version != PROTOCOL_VERSION-1) { net->last_errno= CR_VERSION_ERROR; sprintf(net->last_error, ER(CR_VERSION_ERROR), mysql->protocol_version, @@ -1487,14 +1538,15 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, mysql->server_status=uint2korr(end+3); } -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT /* Set character set */ if ((charset_name=mysql->options.charset_name)) { const char *save=charsets_dir; if (mysql->options.charset_dir) charsets_dir=mysql->options.charset_dir; - mysql->charset=get_charset_by_name(mysql->options.charset_name, + mysql->charset=get_charset_by_csname(mysql->options.charset_name, + MY_CS_PRIMARY, MYF(MY_WME)); charsets_dir=save; } @@ -1512,6 +1564,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if (!mysql->charset) { net->last_errno=CR_CANT_READ_CHARSET; + strmov(net->sqlstate, unknown_sqlstate); if (mysql->options.charset_dir) sprintf(net->last_error,ER(net->last_errno), charset_name ? charset_name : "unknown", @@ -1526,7 +1579,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, } goto error; } -#endif /*_libmysql_c*/ +#endif /*MYSQL_CLIENT*/ /* Save connection information */ if (!user) user=""; @@ -1542,6 +1595,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, !(mysql->user=my_strdup(user,MYF(0))) || !(mysql->passwd=my_strdup(passwd,MYF(0)))) { + strmov(net->sqlstate, unknown_sqlstate); strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY)); goto error; } @@ -1557,6 +1611,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, /* Send client information for access check */ client_flag|=CLIENT_CAPABILITIES; + if (client_flag & CLIENT_MULTI_QUERIES) + client_flag|= CLIENT_MULTI_RESULTS; #ifdef HAVE_OPENSSL if (mysql->options.ssl_key || mysql->options.ssl_cert || @@ -1569,7 +1625,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if (db) client_flag|=CLIENT_CONNECT_WITH_DB; -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT /* Remove options that server doesn't support */ client_flag= ((client_flag & ~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)) | @@ -1579,10 +1635,12 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, #endif if (client_flag & CLIENT_PROTOCOL_41) { - /* 4.1 server and 4.1 client has a 4 byte option flag */ + /* 4.1 server and 4.1 client has a 32 byte option flag */ int4store(buff,client_flag); int4store(buff+4,max_allowed_packet); - end= buff+8; + buff[8]= mysql->charset->number; + bzero(buff+9, 32-9); + end= buff+32; } else { @@ -1591,9 +1649,9 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, end= buff+5; } mysql->client_flag=client_flag; -#endif /*_libmysql_c*/ +#endif /*MYSQL_CLIENT*/ -#ifdef _mini_client_c +#ifdef MYSQL_SERVER #ifdef HAVE_COMPRESS if ((mysql->server_capabilities & CLIENT_COMPRESS) && (mysql->options.compress || (client_flag & CLIENT_COMPRESS))) @@ -1601,9 +1659,9 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, else #endif client_flag&= ~CLIENT_COMPRESS; -#endif /*mini_client_c*/ +#endif /*MYSQL_SERVER*/ -#ifdef _mini_client_c +#ifdef MYSQL_SERVER #ifdef HAVE_OPENSSL if ((mysql->server_capabilities & CLIENT_SSL) && (mysql->options.use_ssl || (client_flag & CLIENT_SSL))) @@ -1626,7 +1684,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, int3store(buff+2,max_allowed_packet); end= buff+5; mysql->client_flag=client_flag; -#endif /*_mini_client_c*/ +#endif /*MYSQL_SERVER*/ #ifdef HAVE_OPENSSL /* @@ -1635,15 +1693,18 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, */ if (client_flag & CLIENT_SSL) { +#ifdef MYSQL_CLIENT struct st_mysql_options *options= &mysql->options; +#endif if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net)) { + strmov(net->sqlstate, unknown_sqlstate); net->last_errno= CR_SERVER_LOST; strmov(net->last_error,ER(net->last_errno)); goto error; } /* Do the SSL layering. */ -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT if (!(mysql->connector_fd= (gptr) new_VioSSLConnectorFd(options->ssl_key, options->ssl_cert, @@ -1651,15 +1712,17 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, options->ssl_capath, options->ssl_cipher))) { + strmov(net->sqlstate, unknown_sqlstate); net->last_errno= CR_SSL_CONNECTION_ERROR; strmov(net->last_error,ER(net->last_errno)); goto error; } -#endif /*libmysql_c*/ +#endif /*MYSQL_CLIENT*/ DBUG_PRINT("info", ("IO layer change in progress...")); if (sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd), mysql->net.vio, (long) (mysql->options.connect_timeout))) { + strmov(net->sqlstate, unknown_sqlstate); net->last_errno= CR_SSL_CONNECTION_ERROR; strmov(net->last_error,ER(net->last_errno)); goto error; @@ -1675,7 +1738,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if (user && user[0]) strmake(end,user,32); /* Max user name */ else -#ifdef _mini_client_c +#ifdef MYSQL_SERVER { user = getenv("USER"); if (!user) user = "mysql"; @@ -1683,9 +1746,9 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, } #else read_user_name((char*) end); -#endif /*_mini_client_c*/ +#endif /*MYSQL_SERVER*/ /* We have to handle different version of handshake here */ -#if defined(_CUSTOMCONFIG_) && defined(_libmysql_c) +#if defined(_CUSTOMCONFIG_) && defined(MYSQL_CLIENT) #include "_cust_libmysql.h"; #endif DBUG_PRINT("info",("user: %s",end)); @@ -1728,6 +1791,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, /* Write authentication package */ if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net)) { + strmov(net->sqlstate, unknown_sqlstate); net->last_errno= CR_SERVER_LOST; strmov(net->last_error,ER(net->last_errno)); goto error; @@ -1739,7 +1803,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if (client_flag & CLIENT_COMPRESS) /* We will use compression */ net->compress=1; -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT if (mysql->options.max_allowed_packet) net->max_packet_size= mysql->options.max_allowed_packet; if (db && mysql_select_db(mysql,db)) @@ -1772,7 +1836,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if (mysql->options.rpl_probe && mysql_rpl_probe(mysql)) goto error; -#endif /*_libmysql_c*/ +#endif /*MYSQL_CLIENT*/ DBUG_PRINT("exit",("Mysql handler: %lx",mysql)); reset_sigpipe(mysql); @@ -1780,7 +1844,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, error: reset_sigpipe(mysql); - DBUG_PRINT("error",("message: %u (%s)",net->last_errno,net->last_error)); + DBUG_PRINT("error",("message: %u/%s (%s)", + net->last_errno, net->sqlstate, net->last_error)); { /* Free alloced memory */ my_bool free_me=mysql->free_me; @@ -1794,6 +1859,7 @@ error: /* needed when we move MYSQL structure to a different address */ +#ifdef MYSQL_CLIENT /*should work in MYSQL_SERVER also, but doesn't */ static void mysql_fix_pointers(MYSQL* mysql, MYSQL* old_mysql) { MYSQL *tmp, *tmp_prev; @@ -1810,6 +1876,7 @@ static void mysql_fix_pointers(MYSQL* mysql, MYSQL* old_mysql) } tmp_prev->next_slave = mysql; } +#endif /*MYSQL_CLIENT*/ my_bool mysql_reconnect(MYSQL *mysql) { @@ -1817,15 +1884,11 @@ my_bool mysql_reconnect(MYSQL *mysql) DBUG_ENTER("mysql_reconnect"); if (!mysql->reconnect -#ifdef _libmysql_c - || (mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info -#endif -) + || (mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info) { /* Allow reconnect next time */ -#ifdef _libmysql_c mysql->server_status&= ~SERVER_STATUS_IN_TRANS; -#endif + strmov(mysql->net.sqlstate, unknown_sqlstate); mysql->net.last_errno=CR_SERVER_GONE_ERROR; strmov(mysql->net.last_error,ER(mysql->net.last_errno)); DBUG_RETURN(1); @@ -1834,23 +1897,23 @@ my_bool mysql_reconnect(MYSQL *mysql) tmp_mysql.options=mysql->options; bzero((char*) &mysql->options,sizeof(mysql->options)); tmp_mysql.rpl_pivot = mysql->rpl_pivot; +#ifdef MYSQL_SERVER + mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *)&mysql->net.read_timeout); +#endif if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd, mysql->db, mysql->port, mysql->unix_socket, - mysql->client_flag -#ifdef _mini_client_c - , mysql->net.read_timeout -#endif -)) + mysql->client_flag)) { mysql->net.last_errno= tmp_mysql.net.last_errno; strmov(mysql->net.last_error, tmp_mysql.net.last_error); + strmov(mysql->net.sqlstate, unknown_sqlstate); DBUG_RETURN(1); } tmp_mysql.free_me=mysql->free_me; mysql->free_me=0; mysql_close(mysql); *mysql=tmp_mysql; -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT /*rpl000010 fails if #ifdef-s were removed*/ mysql_fix_pointers(mysql, &tmp_mysql); /* adjust connection pointers */ #endif net_clear(&mysql->net); @@ -1924,7 +1987,6 @@ mysql_close(MYSQL *mysql) my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR)); -#ifdef _libmysql_c my_free(mysql->options.user,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.host,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.password,MYF(MY_ALLOW_ZERO_PTR)); @@ -1962,6 +2024,7 @@ mysql_close(MYSQL *mysql) } mysql->rpl_pivot=0; } +#ifdef MYSQL_CLIENT if (mysql->stmts) { /* Free any open prepared statements */ @@ -1974,7 +2037,7 @@ mysql_close(MYSQL *mysql) } if (mysql != mysql->master) mysql_close(mysql->master); -#endif /*_libmysql_c*/ +#endif /*MYSQL_CLIENT*/ #ifdef HAVE_OPENSSL mysql_ssl_free(mysql); @@ -1997,7 +2060,7 @@ my_bool STDCALL mysql_read_query_result(MYSQL *mysql) ulong length; DBUG_ENTER("mysql_read_query_result"); -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT /* Read from the connection which we actually used, which could differ from the original connection if we have slaves @@ -2008,21 +2071,20 @@ my_bool STDCALL mysql_read_query_result(MYSQL *mysql) if ((length = net_safe_read(mysql)) == packet_error) DBUG_RETURN(1); free_old_query(mysql); /* Free old result */ +#ifdef MYSQL_CLIENT /*or else gcc will warn of unused labels*/ get_info: +#endif pos=(uchar*) mysql->net.read_pos; if ((field_count= net_field_length(&pos)) == 0) { mysql->affected_rows= net_field_length_ll(&pos); mysql->insert_id= net_field_length_ll(&pos); -#ifdef _libmysql_c if (protocol_41(mysql)) { mysql->server_status=uint2korr(pos); pos+=2; mysql->warning_count=uint2korr(pos); pos+=2; } - else -#endif /*libmysql_c*/ - if (mysql->server_capabilities & CLIENT_TRANSACTIONS) + else if (mysql->server_capabilities & CLIENT_TRANSACTIONS) { mysql->server_status=uint2korr(pos); pos+=2; mysql->warning_count= 0; @@ -2033,6 +2095,7 @@ get_info: mysql->info=(char*) pos; DBUG_RETURN(0); } +#ifdef MYSQL_CLIENT if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */ { int error=send_file_to_server(mysql,(char*) pos); @@ -2040,16 +2103,13 @@ get_info: DBUG_RETURN(1); goto get_info; /* Get info packet */ } +#endif if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT)) mysql->server_status|= SERVER_STATUS_IN_TRANS; mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */ - if (!(fields=read_rows(mysql,(MYSQL_FIELD*)0, -#ifdef _libmysql_c - protocol_41(mysql) ? 6 : -#endif - 5))) + if (!(fields=read_rows(mysql,(MYSQL_FIELD*)0,protocol_41(mysql) ? 7 : 5))) DBUG_RETURN(1); if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc, (uint) field_count,0, @@ -2074,7 +2134,7 @@ mysql_send_query(MYSQL* mysql, const char* query, ulong length) DBUG_ENTER("mysql_send_query"); DBUG_PRINT("enter",("rpl_parse: %d rpl_pivot: %d", mysql->options.rpl_parse, mysql->rpl_pivot)); -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT if (mysql->options.rpl_parse && mysql->rpl_pivot) { switch (mysql_rpl_query_type(query, length)) { @@ -2088,7 +2148,7 @@ mysql_send_query(MYSQL* mysql, const char* query, ulong length) } mysql->last_used_con = mysql; -#endif /*libmysql_c*/ +#endif /*MYSQL_CLIENT*/ DBUG_RETURN(simple_command(mysql, COM_QUERY, query, length, 1)); } @@ -2106,65 +2166,6 @@ mysql_real_query(MYSQL *mysql, const char *query, ulong length) DBUG_RETURN((int) mysql_read_query_result(mysql)); } -static my_bool -send_file_to_server(MYSQL *mysql, const char *filename) -{ - int fd, readcount; - my_bool result= 1; - uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE); - char *buf, tmp_name[FN_REFLEN]; - DBUG_ENTER("send_file_to_server"); - - if (!(buf=my_malloc(packet_length,MYF(0)))) - { - strmov(mysql->net.last_error, ER(mysql->net.last_errno=CR_OUT_OF_MEMORY)); - DBUG_RETURN(1); - } - - fn_format(tmp_name,filename,"","",4); /* Convert to client format */ - if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0) - { - my_net_write(&mysql->net,"",0); /* Server needs one packet */ - net_flush(&mysql->net); - mysql->net.last_errno=EE_FILENOTFOUND; - my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1, - EE(mysql->net.last_errno),tmp_name, errno); - goto err; - } - - while ((readcount = (int) my_read(fd,(byte*) buf,packet_length,MYF(0))) > 0) - { - if (my_net_write(&mysql->net,buf,readcount)) - { - DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file")); - mysql->net.last_errno=CR_SERVER_LOST; - strmov(mysql->net.last_error,ER(mysql->net.last_errno)); - goto err; - } - } - /* Send empty packet to mark end of file */ - if (my_net_write(&mysql->net,"",0) || net_flush(&mysql->net)) - { - mysql->net.last_errno=CR_SERVER_LOST; - sprintf(mysql->net.last_error,ER(mysql->net.last_errno),errno); - goto err; - } - if (readcount < 0) - { - mysql->net.last_errno=EE_READ; /* the errmsg for not entire file read */ - my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1, - tmp_name,errno); - goto err; - } - result=0; /* Ok */ - -err: - if (fd >= 0) - (void) my_close(fd,MYF(0)); - my_free(buf,MYF(0)); - DBUG_RETURN(result); -} - /************************************************************************** Alloc result struct for buffered results. All rows are read to buffer. mysql_data_seek may be used. @@ -2176,7 +2177,7 @@ mysql_store_result(MYSQL *mysql) MYSQL_RES *result; DBUG_ENTER("mysql_store_result"); -#ifdef _libmysql_c +#ifdef MYSQL_CLIENT /* read from the actually used connection */ mysql = mysql->last_used_con; #endif @@ -2184,6 +2185,7 @@ mysql_store_result(MYSQL *mysql) DBUG_RETURN(0); if (mysql->status != MYSQL_STATUS_GET_RESULT) { + strmov(mysql->net.sqlstate, unknown_sqlstate); strmov(mysql->net.last_error, ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC)); DBUG_RETURN(0); @@ -2194,6 +2196,7 @@ mysql_store_result(MYSQL *mysql) mysql->field_count), MYF(MY_WME | MY_ZEROFILL)))) { + strmov(mysql->net.sqlstate, unknown_sqlstate); mysql->net.last_errno=CR_OUT_OF_MEMORY; strmov(mysql->net.last_error, ER(mysql->net.last_errno)); DBUG_RETURN(0); @@ -2272,6 +2275,66 @@ mysql_data_seek(MYSQL_RES *result, my_ulonglong row) result->data_cursor = tmp; } +int STDCALL +mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg) +{ + DBUG_ENTER("mysql_option"); + DBUG_PRINT("enter",("option: %d",(int) option)); + switch (option) { + case MYSQL_OPT_CONNECT_TIMEOUT: + mysql->options.connect_timeout= *(uint*) arg; + break; + case MYSQL_OPT_COMPRESS: + mysql->options.compress= 1; /* Remember for connect */ + mysql->options.client_flag|= CLIENT_COMPRESS; + break; + case MYSQL_OPT_NAMED_PIPE: + mysql->options.protocol=MYSQL_PROTOCOL_PIPE; /* Force named pipe */ + break; + case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/ + if (!arg || test(*(uint*) arg)) + mysql->options.client_flag|= CLIENT_LOCAL_FILES; + else + mysql->options.client_flag&= ~CLIENT_LOCAL_FILES; + break; +#ifdef MYSQL_CLIENT + case MYSQL_INIT_COMMAND: + add_init_command(&mysql->options,arg); + break; +#endif + case MYSQL_READ_DEFAULT_FILE: + my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR)); + mysql->options.my_cnf_file=my_strdup(arg,MYF(MY_WME)); + break; + case MYSQL_READ_DEFAULT_GROUP: + my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR)); + mysql->options.my_cnf_group=my_strdup(arg,MYF(MY_WME)); + break; + case MYSQL_SET_CHARSET_DIR: + my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR)); + mysql->options.charset_dir=my_strdup(arg,MYF(MY_WME)); + break; + case MYSQL_SET_CHARSET_NAME: + my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR)); + mysql->options.charset_name=my_strdup(arg,MYF(MY_WME)); + break; + case MYSQL_OPT_PROTOCOL: + mysql->options.protocol= *(uint*) arg; + break; + case MYSQL_SHARED_MEMORY_BASE_NAME: +#ifdef HAVE_SMEM + if (mysql->options.shared_memory_base_name != def_shared_memory_base_name) + my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); + mysql->options.shared_memory_base_name=my_strdup(arg,MYF(MY_WME)); +#endif + break; + default: + DBUG_RETURN(1); + } + DBUG_RETURN(0); +} + + /**************************************************************************** Functions to get information from the MySQL structure These are functions to make shared libraries more usable. @@ -2297,3 +2360,6 @@ const char * STDCALL mysql_error(MYSQL *mysql) { return mysql->net.last_error; } + +#endif /* defined(MYSQL_SERVER) || defined(HAVE_EXTERNAL_CLIENT) */ + diff --git a/sql/Makefile.am b/sql/Makefile.am index 608b959a8b9..eeaf96ce190 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -55,9 +55,9 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ opt_range.h opt_ft.h protocol.h \ sql_select.h structs.h table.h sql_udf.h hash_filo.h\ lex.h lex_symbol.h sql_acl.h sql_crypt.h \ - log_event.h mini_client.h sql_repl.h slave.h \ + log_event.h sql_repl.h slave.h \ stacktrace.h sql_sort.h sql_cache.h set_var.h \ - spatial.h gstream.h + spatial.h gstream.h client_settings.h mysqld_SOURCES = sql_lex.cc sql_handler.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \ item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \ @@ -83,7 +83,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \ sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \ slave.cc sql_repl.cc sql_union.cc sql_derived.cc \ - mini_client.cc mini_client_errors.c pack.c\ + client.c mini_client_errors.c pack.c\ stacktrace.c repl_failsafe.h repl_failsafe.cc sql_olap.cc\ gstream.cc spatial.cc sql_help.cc protocol_cursor.cc gen_lex_hash_SOURCES = gen_lex_hash.cc @@ -104,6 +104,8 @@ link_sources: @LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c rm -f pack.c @LN_CP_F@ ../sql-common/pack.c pack.c + rm -f client.c + @LN_CP_F@ ../sql-common/client.c client.c gen_lex_hash.o: gen_lex_hash.cc lex.h $(CXXCOMPILE) -c $(INCLUDES) $< diff --git a/sql/client_settings.h b/sql/client_settings.h new file mode 100644 index 00000000000..de0c7f40717 --- /dev/null +++ b/sql/client_settings.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + +#ifndef _client_settings_h +#define _client_settings_h +#include <thr_alarm.h> +#include <mysql_embed.h> +#include <mysql_com.h> + + +#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | \ + CLIENT_LOCAL_FILES | CLIENT_SECURE_CONNECTION) + + +extern ulong slave_net_timeout; +#define init_sigpipe_variables +#define set_sigpipe(mysql) +#define reset_sigpipe(mysql) +#endif /* _client_settings_h */ diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 1d0801fc3c1..2aa8f492ed3 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -23,7 +23,6 @@ #include "sql_repl.h" #include "slave.h" #include "sql_acl.h" -#include "mini_client.h" #include "log_event.h" #include <mysql.h> @@ -669,9 +668,9 @@ int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi) strmov(mysql->net.last_error, "Master is not configured"); DBUG_RETURN(1); } + mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *)&slave_net_timeout); if (!mysql_real_connect(mysql, mi->host, mi->user, mi->password, 0, - mi->port, 0, 0, - slave_net_timeout)) + mi->port, 0, 0)) DBUG_RETURN(1); DBUG_RETURN(0); } diff --git a/sql/slave.cc b/sql/slave.cc index cc40df38eff..a49389e0ec7 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -20,12 +20,12 @@ #include <mysql.h> #include <myisam.h> -#include "mini_client.h" #include "slave.h" #include "sql_repl.h" #include "repl_failsafe.h" #include <thr_alarm.h> #include <my_dir.h> +#include <sql_common.h> bool use_slave_mask = 0; MY_BITMAP slave_error_mask; @@ -2948,9 +2948,10 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi, while (!(slave_was_killed = io_slave_killed(thd,mi)) && (reconnect ? mysql_reconnect(mysql) != 0: - !mysql_real_connect(mysql, mi->host, mi->user, mi->password, 0, - mi->port, 0, client_flag, - thd->variables.net_read_timeout))) + !(mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, + (char *)&thd->variables.net_read_timeout), + mysql_real_connect(mysql, mi->host, mi->user, mi->password, 0, + mi->port, 0, client_flag)))) { /* Don't repeat last error */ if ((int)mysql_errno(mysql) != last_errno) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index b8f6de30840..fe47e553cf3 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -22,7 +22,6 @@ #include "sql_repl.h" #include "sql_acl.h" #include "log_event.h" -#include "mini_client.h" #include <my_dir.h> extern const char* any_db; |