diff options
Diffstat (limited to 'ext/mysql/libmysql/libmysql.c')
-rw-r--r-- | ext/mysql/libmysql/libmysql.c | 2604 |
1 files changed, 0 insertions, 2604 deletions
diff --git a/ext/mysql/libmysql/libmysql.c b/ext/mysql/libmysql/libmysql.c deleted file mode 100644 index 05558cf3ee..0000000000 --- a/ext/mysql/libmysql/libmysql.c +++ /dev/null @@ -1,2604 +0,0 @@ -/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB -This file is public domain and comes with NO WARRANTY of any kind */ - -#include <global.h> -#if 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.h" -#include "mysql_version.h" -#include "mysqld_error.h" -#include "errmsg.h" -#include <violite.h> -#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 -#ifdef HAVE_SYS_UN_H -# include <sys/un.h> -#endif -#if defined(THREAD) && !defined(__WIN__) -#include <my_pthread.h> /* because of signal() */ -#endif -#ifndef INADDR_NONE -#define INADDR_NONE -1 -#endif - -static my_bool mysql_client_init=0; -uint mysql_port=0; -my_string mysql_unix_port=0; - -#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS) - -#ifdef __WIN__ -#define CONNECT_TIMEOUT 20 -#else -#define CONNECT_TIMEOUT 0 -#endif - -#if defined(MSDOS) || defined(__WIN__) -/* socket_errno is defined in global.h for all platforms */ -#define perror(A) -#else -#include <errno.h> -#define SOCKET_ERROR -1 -#endif /* __WIN__ */ - -static void mysql_once_init(void); -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 int send_file_to_server(MYSQL *mysql,const char *filename); -static sig_handler pipe_sig_handler(int sig); -static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, - const char *from, ulong length); - -/* - 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 - -/**************************************************************************** -* A modified version of connect(). connect2() allows you to specify -* a timeout value, in seconds, that we should wait until we -* derermine we can't connect to a particular host. If timeout is 0, -* connect2() will behave exactly like connect(). -* -* Base version coded by Steve Bernacki, Jr. <steve@navinet.net> -*****************************************************************************/ - -static int connect2(my_socket s, const struct sockaddr *name, uint namelen, - uint timeout) -{ -#if defined(__WIN__) || defined(OS2) - return connect(s, (struct sockaddr*) name, namelen); -#else - int flags, res, s_err; - SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint); - fd_set sfds; - struct timeval tv; - time_t start_time, now_time; - - /* If they passed us a timeout of zero, we should behave - * exactly like the normal connect() call does. - */ - - if (timeout == 0) - return connect(s, (struct sockaddr*) name, namelen); - - flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */ -#ifdef O_NONBLOCK - fcntl(s, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */ -#endif - - res = connect(s, (struct sockaddr*) name, namelen); - s_err = errno; /* Save the error... */ - fcntl(s, F_SETFL, flags); - if ((res != 0) && (s_err != EINPROGRESS)) - { - errno = s_err; /* Restore it */ - return(-1); - } - if (res == 0) /* Connected quickly! */ - return(0); - - /* Otherwise, our connection is "in progress." We can use - * the select() call to wait up to a specified period of time - * for the connection to suceed. If select() returns 0 - * (after waiting howevermany seconds), our socket never became - * writable (host is probably unreachable.) Otherwise, if - * select() returns 1, then one of two conditions exist: - * - * 1. An error occured. We use getsockopt() to check for this. - * 2. The connection was set up sucessfully: getsockopt() will - * return 0 as an error. - * - * Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk> - * who posted this method of timing out a connect() in - * comp.unix.programmer on August 15th, 1997. - */ - - FD_ZERO(&sfds); - FD_SET(s, &sfds); - /* - * select could be interrupted by a signal, and if it is, - * the timeout should be adjusted and the select restarted - * to work around OSes that don't restart select and - * implementations of select that don't adjust tv upon - * failure to reflect the time remaining - */ - start_time = time(NULL); - for (;;) - { - tv.tv_sec = (long) timeout; - tv.tv_usec = 0; - if ((res = select(s+1, NULL, &sfds, NULL, &tv)) >= 0) - break; - now_time=time(NULL); - timeout-= (uint) (now_time - start_time); - if (errno != EINTR || (int) timeout <= 0) - return -1; - } - - /* select() returned something more interesting than zero, let's - * see if we have any errors. If the next two statements pass, - * we've got an open socket! - */ - - s_err=0; - if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0) - return(-1); - - if (s_err) - { /* getsockopt could succeed */ - errno = s_err; - return(-1); /* but return an error... */ - } - return(0); /* It's all good! */ -#endif -} - -/* -** Create a named pipe connection -*/ - -#ifdef __WIN__ - -HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host, - char **arg_unix_socket) -{ - HANDLE hPipe=INVALID_HANDLE_VALUE; - char szPipeName [ 257 ]; - DWORD dwMode; - int i; - my_bool testing_named_pipes=0; - char *host= *arg_host, *unix_socket= *arg_unix_socket; - - if ( ! unix_socket || (unix_socket)[0] == 0x00) - unix_socket = mysql_unix_port; - if (!host || !strcmp(host,LOCAL_HOST)) - host=LOCAL_HOST_NAMEDPIPE; - - sprintf( szPipeName, "\\\\%s\\pipe\\%s", host, unix_socket); - DBUG_PRINT("info",("Server name: '%s'. Named Pipe: %s", - host, unix_socket)); - - for (i=0 ; i < 100 ; i++) /* Don't retry forever */ - { - if ((hPipe = CreateFile(szPipeName, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - 0, - NULL )) != INVALID_HANDLE_VALUE) - break; - if (GetLastError() != ERROR_PIPE_BUSY) - { - net->last_errno=CR_NAMEDPIPEOPEN_ERROR; - sprintf(net->last_error,ER(net->last_errno),host, unix_socket, - (ulong) GetLastError()); - return INVALID_HANDLE_VALUE; - } - /* wait for for an other instance */ - if (! WaitNamedPipe(szPipeName, connect_timeout*1000) ) - { - net->last_errno=CR_NAMEDPIPEWAIT_ERROR; - sprintf(net->last_error,ER(net->last_errno),host, unix_socket, - (ulong) GetLastError()); - return INVALID_HANDLE_VALUE; - } - } - if (hPipe == INVALID_HANDLE_VALUE) - { - net->last_errno=CR_NAMEDPIPEOPEN_ERROR; - sprintf(net->last_error,ER(net->last_errno),host, unix_socket, - (ulong) GetLastError()); - return INVALID_HANDLE_VALUE; - } - dwMode = PIPE_READMODE_BYTE | PIPE_WAIT; - if ( !SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL) ) - { - CloseHandle( hPipe ); - net->last_errno=CR_NAMEDPIPESETSTATE_ERROR; - sprintf(net->last_error,ER(net->last_errno),host, unix_socket, - (ulong) GetLastError()); - return INVALID_HANDLE_VALUE; - } - *arg_host=host ; *arg_unix_socket=unix_socket; /* connect arg */ - return (hPipe); -} -#endif - - -/***************************************************************************** -** read a packet from server. Give error message if socket was down -** or packet is an error message -*****************************************************************************/ - -uint -net_safe_read(MYSQL *mysql) -{ - NET *net= &mysql->net; - uint len=0; - init_sigpipe_variables - - /* Don't give sigpipe errors if the client doesn't want them */ - set_sigpipe(mysql); - if (net->vio != 0) - len=my_net_read(net); - reset_sigpipe(mysql); - - if (len == packet_error || len == 0) - { - DBUG_PRINT("error",("Wrong connection or packet. fd: %s len: %d", - vio_description(net->vio),len)); - end_server(mysql); - net->last_errno=(net->last_errno == ER_NET_PACKET_TOO_LARGE ? - CR_NET_PACKET_TOO_LARGE: - CR_SERVER_LOST); - strmov(net->last_error,ER(net->last_errno)); - return(packet_error); - } - if (net->read_pos[0] == 255) - { - if (len > 3) - { - char *pos=(char*) net->read_pos+1; - if (mysql->protocol_version > 9) - { /* New client protocol */ - net->last_errno=uint2korr(pos); - pos+=2; - len-=2; - } - else - { - net->last_errno=CR_UNKNOWN_ERROR; - len--; - } - (void) strmake(net->last_error,(char*) pos, - min(len,sizeof(net->last_error)-1)); - } - else - { - net->last_errno=CR_UNKNOWN_ERROR; - (void) strmov(net->last_error,ER(net->last_errno)); - } - DBUG_PRINT("error",("Got error: %d (%s)", net->last_errno, - net->last_error)); - return(packet_error); - } - return len; -} - - -/* Get the length of next field. Change parameter to point at fieldstart */ -static ulong -net_field_length(uchar **packet) -{ - reg1 uchar *pos= *packet; - if (*pos < 251) - { - (*packet)++; - return (ulong) *pos; - } - if (*pos == 251) - { - (*packet)++; - return NULL_LENGTH; - } - if (*pos == 252) - { - (*packet)+=3; - return (ulong) uint2korr(pos+1); - } - if (*pos == 253) - { - (*packet)+=4; - return (ulong) uint3korr(pos+1); - } - (*packet)+=9; /* Must be 254 when here */ - return (ulong) uint4korr(pos+1); -} - -/* Same as above, but returns ulonglong values */ - -static my_ulonglong -net_field_length_ll(uchar **packet) -{ - reg1 uchar *pos= *packet; - if (*pos < 251) - { - (*packet)++; - return (my_ulonglong) *pos; - } - if (*pos == 251) - { - (*packet)++; - return (my_ulonglong) NULL_LENGTH; - } - if (*pos == 252) - { - (*packet)+=3; - return (my_ulonglong) uint2korr(pos+1); - } - if (*pos == 253) - { - (*packet)+=4; - return (my_ulonglong) uint3korr(pos+1); - } - (*packet)+=9; /* Must be 254 when here */ -#ifdef NO_CLIENT_LONGLONG - return (my_ulonglong) uint4korr(pos+1); -#else - return (my_ulonglong) uint8korr(pos+1); -#endif -} - - -static void free_rows(MYSQL_DATA *cur) -{ - if (cur) - { - free_root(&cur->alloc,MYF(0)); - my_free((gptr) cur,MYF(0)); - } -} - - -int -simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg, - uint length, my_bool skipp_check) -{ - NET *net= &mysql->net; - int result= -1; - init_sigpipe_variables - - /* Don't give sigpipe errors if the client doesn't want them */ - set_sigpipe(mysql); - if (mysql->net.vio == 0) - { /* Do reconnect if possible */ - if (mysql_reconnect(mysql)) - { - net->last_errno=CR_SERVER_GONE_ERROR; - strmov(net->last_error,ER(net->last_errno)); - goto end; - } - } - if (mysql->status != MYSQL_STATUS_READY) - { - strmov(net->last_error,ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC)); - goto end; - } - - mysql->net.last_error[0]=0; - mysql->net.last_errno=0; - mysql->info=0; - mysql->affected_rows= ~(my_ulonglong) 0; - net_clear(net); /* Clear receive buffer */ - if (!arg) - arg=""; - - if (net_write_command(net,(uchar) command,arg, - length ? length : (ulong) strlen(arg))) - { - DBUG_PRINT("error",("Can't send command to server. Error: %d",socket_errno)); - end_server(mysql); - if (mysql_reconnect(mysql) || - net_write_command(net,(uchar) command,arg, - length ? length : (ulong) strlen(arg))) - { - net->last_errno=CR_SERVER_GONE_ERROR; - strmov(net->last_error,ER(net->last_errno)); - goto end; - } - } - result=0; - if (!skipp_check) - result= ((mysql->packet_length=net_safe_read(mysql)) == packet_error ? - -1 : 0); - end: - reset_sigpipe(mysql); - return result; -} - - -static void free_old_query(MYSQL *mysql) -{ - DBUG_ENTER("free_old_query"); - if (mysql->fields) - free_root(&mysql->field_alloc,MYF(0)); - init_alloc_root(&mysql->field_alloc,8192,0); /* Assume rowlength < 8192 */ - mysql->fields=0; - mysql->field_count=0; /* For API */ - DBUG_VOID_RETURN; -} - -#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL) -struct passwd *getpwuid(uid_t); -char* getlogin(void); -#endif - -#if !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 - -#ifdef __WIN__ -static my_bool is_NT(void) -{ - char *os=getenv("OS"); - return (os && !strcmp(os, "Windows_NT")) ? 1 : 0; -} -#endif - -/* -** Expand wildcard to a sql string -*/ - -static void -append_wild(char *to, char *end, const char *wild) -{ - end-=5; /* Some extra */ - if (wild && wild[0]) - { - to=strmov(to," like '"); - while (*wild && to < end) - { - if (*wild == '\\' || *wild == '\'') - *to++='\\'; - *to++= *wild++; - } - if (*wild) /* Too small buffer */ - *to++='%'; /* Nicer this way */ - to[0]='\''; - to[1]=0; - } -} - - - -/************************************************************************** -** Init debugging if MYSQL_DEBUG environment variable is found -**************************************************************************/ - -void STDCALL -mysql_debug(const char *debug __attribute__((unused))) -{ -#ifndef DBUG_OFF - char *env; - if (_db_on_) - return; /* Already using debugging */ - if (debug) - { - DEBUGGER_ON; - DBUG_PUSH(debug); - } - else if ((env = getenv("MYSQL_DEBUG"))) - { - DEBUGGER_ON; - DBUG_PUSH(env); -#if !defined(_WINVER) && !defined(WINVER) - puts("\n-------------------------------------------------------"); - puts("MYSQL_DEBUG found. libmysql started with the following:"); - puts(env); - puts("-------------------------------------------------------\n"); -#else - { - char buff[80]; - strmov(strmov(buff,"libmysql: "),env); - MessageBox((HWND) 0,"Debugging variable MYSQL_DEBUG used",buff,MB_OK); - } -#endif - } -#endif -} - - -/************************************************************************** -** Close the server connection if we get a SIGPIPE - ARGSUSED -**************************************************************************/ - -static sig_handler -pipe_sig_handler(int sig __attribute__((unused))) -{ - DBUG_PRINT("info",("Hit by signal %d",sig)); -#ifdef DONT_REMEMBER_SIGNAL - (void) signal(SIGPIPE,pipe_sig_handler); -#endif -} - - -/************************************************************************** -** Shut down connection -**************************************************************************/ - -static void -end_server(MYSQL *mysql) -{ - DBUG_ENTER("end_server"); - if (mysql->net.vio != 0) - { - init_sigpipe_variables - DBUG_PRINT("info",("Net: %s", vio_description(mysql->net.vio))); - set_sigpipe(mysql); - vio_delete(mysql->net.vio); - reset_sigpipe(mysql); - mysql->net.vio= 0; /* Marker */ - } - net_end(&mysql->net); - free_old_query(mysql); - DBUG_VOID_RETURN; -} - - -void STDCALL -mysql_free_result(MYSQL_RES *result) -{ - DBUG_ENTER("mysql_free_result"); - DBUG_PRINT("enter",("mysql_res: %lx",result)); - if (result) - { - if (result->handle && result->handle->status == MYSQL_STATUS_USE_RESULT) - { - DBUG_PRINT("warning",("Not all rows in set were read; Ignoring rows")); - for (;;) - { - uint pkt_len; - if ((pkt_len=(uint) net_safe_read(result->handle)) == packet_error) - break; - if (pkt_len == 1 && result->handle->net.read_pos[0] == 254) - break; /* End of data */ - } - result->handle->status=MYSQL_STATUS_READY; - } - free_rows(result->data); - if (result->fields) - free_root(&result->field_alloc,MYF(0)); - if (result->row) - my_free((gptr) result->row,MYF(0)); - my_free((gptr) result,MYF(0)); - } - DBUG_VOID_RETURN; -} - - -/**************************************************************************** -** Get options from my.cnf -****************************************************************************/ - -static const char *default_options[]= -{ - "port","socket","compress","password","pipe", "timeout", "user", - "init-command", "host", "database", "debug", "return-found-rows", - "ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath", - "character-set-dir", "default-character-set", "interactive-timeout", - "connect-timeout", "local-infile", "disable-local-infile", - NullS -}; - -static TYPELIB option_types={array_elements(default_options)-1, - "options",default_options}; - -static void mysql_read_default_options(struct st_mysql_options *options, - const char *filename,const char *group) -{ - int argc; - char *argv_buff[1],**argv; - const char *groups[3]; - DBUG_ENTER("mysql_read_default_options"); - DBUG_PRINT("enter",("file: %s group: %s",filename,group ? group :"NULL")); - - argc=1; argv=argv_buff; argv_buff[0]= (char*) "client"; - groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0; - - load_defaults(filename, groups, &argc, &argv); - if (argc != 1) /* If some default option */ - { - char **option=argv; - while (*++option) - { - /* DBUG_PRINT("info",("option: %s",option[0])); */ - if (option[0][0] == '-' && option[0][1] == '-') - { - char *end=strcend(*option,'='); - char *opt_arg=0; - if (*end) - { - opt_arg=end+1; - *end=0; /* Remove '=' */ - } - /* Change all '_' in variable name to '-' */ - for (end= *option ; (end= strcend(end,'_')) ; ) - *end= '-'; - switch (find_type(*option+2,&option_types,2)) { - case 1: /* port */ - if (opt_arg) - options->port=atoi(opt_arg); - break; - case 2: /* socket */ - if (opt_arg) - { - my_free(options->unix_socket,MYF(MY_ALLOW_ZERO_PTR)); - options->unix_socket=my_strdup(opt_arg,MYF(MY_WME)); - } - break; - case 3: /* compress */ - options->compress=1; - break; - case 4: /* password */ - if (opt_arg) - { - my_free(options->password,MYF(MY_ALLOW_ZERO_PTR)); - options->password=my_strdup(opt_arg,MYF(MY_WME)); - } - break; - case 5: /* pipe */ - options->named_pipe=1; /* Force named pipe */ - break; - case 20: /* connect_timeout */ - case 6: /* timeout */ - if (opt_arg) - options->connect_timeout=atoi(opt_arg); - break; - case 7: /* user */ - if (opt_arg) - { - my_free(options->user,MYF(MY_ALLOW_ZERO_PTR)); - options->user=my_strdup(opt_arg,MYF(MY_WME)); - } - break; - case 8: /* init-command */ - if (opt_arg) - { - my_free(options->init_command,MYF(MY_ALLOW_ZERO_PTR)); - options->init_command=my_strdup(opt_arg,MYF(MY_WME)); - } - break; - case 9: /* host */ - if (opt_arg) - { - my_free(options->host,MYF(MY_ALLOW_ZERO_PTR)); - options->host=my_strdup(opt_arg,MYF(MY_WME)); - } - break; - case 10: /* database */ - if (opt_arg) - { - my_free(options->db,MYF(MY_ALLOW_ZERO_PTR)); - options->db=my_strdup(opt_arg,MYF(MY_WME)); - } - break; - case 11: /* debug */ - mysql_debug(opt_arg ? opt_arg : "d:t:o,/tmp/client.trace"); - break; - case 12: /* return-found-rows */ - options->client_flag|=CLIENT_FOUND_ROWS; - break; -#ifdef HAVE_OPENSSL - case 13: /* ssl_key */ - my_free(options->ssl_key, MYF(MY_ALLOW_ZERO_PTR)); - options->ssl_key = my_strdup(opt_arg, MYF(MY_WME)); - break; - case 14: /* ssl_cert */ - my_free(options->ssl_cert, MYF(MY_ALLOW_ZERO_PTR)); - options->ssl_cert = my_strdup(opt_arg, MYF(MY_WME)); - break; - case 15: /* ssl_ca */ - my_free(options->ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); - options->ssl_ca = my_strdup(opt_arg, MYF(MY_WME)); - break; - case 16: /* ssl_capath */ - my_free(options->ssl_capath, MYF(MY_ALLOW_ZERO_PTR)); - options->ssl_capath = my_strdup(opt_arg, MYF(MY_WME)); - break; -#else - case 13: /* Ignore SSL options */ - case 14: - case 15: - case 16: - break; -#endif /* HAVE_OPENSSL */ - case 17: /* charset-lib */ - my_free(options->charset_dir,MYF(MY_ALLOW_ZERO_PTR)); - options->charset_dir = my_strdup(opt_arg, MYF(MY_WME)); - break; - case 18: - my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR)); - options->charset_name = my_strdup(opt_arg, MYF(MY_WME)); - break; - case 19: /* Interactive-timeout */ - options->client_flag|= CLIENT_INTERACTIVE; - break; - case 21: - if (!opt_arg || atoi(opt_arg) != 0) - options->client_flag|= CLIENT_LOCAL_FILES; - else - options->client_flag&= ~CLIENT_LOCAL_FILES; - break; - case 22: - options->client_flag&= CLIENT_LOCAL_FILES; - break; - default: - DBUG_PRINT("warning",("unknown option: %s",option[0])); - } - } - } - } - free_defaults(argv); - DBUG_VOID_RETURN; -} - - -/*************************************************************************** -** Change field rows to field structs -***************************************************************************/ - -static MYSQL_FIELD * -unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, - my_bool default_value, my_bool long_flag_protocol) -{ - MYSQL_ROWS *row; - MYSQL_FIELD *field,*result; - DBUG_ENTER("unpack_fields"); - - field=result=(MYSQL_FIELD*) alloc_root(alloc,sizeof(MYSQL_FIELD)*fields); - if (!result) - DBUG_RETURN(0); - - for (row=data->data; row ; row = row->next,field++) - { - field->table= strdup_root(alloc,(char*) row->data[0]); - field->name= strdup_root(alloc,(char*) row->data[1]); - field->length= (uint) uint3korr(row->data[2]); - field->type= (enum enum_field_types) (uchar) row->data[3][0]; - if (long_flag_protocol) - { - field->flags= uint2korr(row->data[4]); - field->decimals=(uint) (uchar) row->data[4][2]; - } - else - { - field->flags= (uint) (uchar) row->data[4][0]; - field->decimals=(uint) (uchar) row->data[4][1]; - } - if (INTERNAL_NUM_FIELD(field)) - field->flags|= NUM_FLAG; - if (default_value && row->data[5]) - field->def=strdup_root(alloc,(char*) row->data[5]); - else - field->def=0; - field->max_length= 0; - } - 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, - uint fields) -{ - uint field,pkt_len; - ulong len; - uchar *cp; - char *to, *end_to; - MYSQL_DATA *result; - MYSQL_ROWS **prev_ptr,*cur; - NET *net = &mysql->net; - DBUG_ENTER("read_rows"); - - if ((pkt_len=(uint) net_safe_read(mysql)) == packet_error) - DBUG_RETURN(0); - if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), - MYF(MY_WME | MY_ZEROFILL)))) - { - net->last_errno=CR_OUT_OF_MEMORY; - strmov(net->last_error,ER(net->last_errno)); - DBUG_RETURN(0); - } - init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */ - result->alloc.min_malloc=sizeof(MYSQL_ROWS); - prev_ptr= &result->data; - result->rows=0; - result->fields=fields; - - while (*(cp=net->read_pos) != 254 || pkt_len != 1) - { - result->rows++; - if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc, - sizeof(MYSQL_ROWS))) || - !(cur->data= ((MYSQL_ROW) - alloc_root(&result->alloc, - (fields+1)*sizeof(char *)+pkt_len)))) - { - free_rows(result); - net->last_errno=CR_OUT_OF_MEMORY; - strmov(net->last_error,ER(net->last_errno)); - DBUG_RETURN(0); - } - *prev_ptr=cur; - prev_ptr= &cur->next; - to= (char*) (cur->data+fields+1); - end_to = to + pkt_len - 1; - for (field=0 ; field < fields ; field++) - { - if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH) - { /* null field */ - cur->data[field] = 0; - } - else - { - cur->data[field] = to; - if (len > end_to - to) - { - free_rows(result); - net->last_errno = CR_UNKNOWN_ERROR; - strmov(net->last_error, ER(net->last_errno)); - DBUG_RETURN(0); - } - memcpy(to,(char*) cp,len); to[len]=0; - to+=len+1; - cp+=len; - if (mysql_fields) - { - if (mysql_fields[field].max_length < len) - mysql_fields[field].max_length=len; - } - } - } - cur->data[field]=to; /* End of last field */ - if ((pkt_len=net_safe_read(mysql)) == packet_error) - { - free_rows(result); - DBUG_RETURN(0); - } - } - *prev_ptr=0; /* last pointer is null */ - DBUG_PRINT("exit",("Got %d rows",result->rows)); - DBUG_RETURN(result); -} - - -/* -** Read one row. Uses packet buffer as storage for fields. -** When next packet is read, the previous field values are destroyed -*/ - - -static int -read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) -{ - uint field; - ulong pkt_len,len; - uchar *pos,*prev_pos,*end_pos; - - if ((pkt_len=(uint) net_safe_read(mysql)) == packet_error) - return -1; - if (pkt_len == 1 && mysql->net.read_pos[0] == 254) - return 1; /* End of data */ - prev_pos= 0; /* allowed to write at packet[-1] */ - pos=mysql->net.read_pos; - end_pos=pos+pkt_len; - for (field=0 ; field < fields ; field++) - { - if ((len=(ulong) net_field_length(&pos)) == NULL_LENGTH) - { /* null field */ - row[field] = 0; - *lengths++=0; - } - else - { - if (len > end_pos - pos) - { - mysql->net.last_errno=CR_UNKNOWN_ERROR; - strmov(mysql->net.last_error, ER(mysql->net.last_errno)); - return -1; - } - row[field] = (char*) pos; - pos+=len; - *lengths++=len; - } - if (prev_pos) - *prev_pos=0; /* Terminate prev field */ - prev_pos=pos; - } - row[field]=(char*) prev_pos+1; /* End of last field */ - *prev_pos=0; /* Terminate last field */ - return 0; -} - -/**************************************************************************** -** Init MySQL structure or allocate one -****************************************************************************/ - -MYSQL * STDCALL -mysql_init(MYSQL *mysql) -{ - mysql_once_init(); - if (!mysql) - { - if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL)))) - return 0; - mysql->free_me=1; - mysql->net.vio = 0; - } - else - bzero((char*) (mysql),sizeof(*(mysql))); - mysql->options.connect_timeout=CONNECT_TIMEOUT; -#if defined(SIGPIPE) && defined(THREAD) && !defined(__WIN__) - if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE)) - (void) signal(SIGPIPE,pipe_sig_handler); -#endif - -/* - Only enable LOAD DATA INFILE by default if configured with - --with-enabled-local-inflile -*/ -#ifdef ENABLED_LOCAL_INFILE - mysql->options.client_flag|= CLIENT_LOCAL_FILES; -#endif - return mysql; -} - - -static void mysql_once_init() -{ - if (!mysql_client_init) - { - mysql_client_init=1; - my_init(); /* Will init threads */ - init_client_errs(); - if (!mysql_port) - { - mysql_port = MYSQL_PORT; -#ifndef MSDOS - { - struct servent *serv_ptr; - char *env; - if ((serv_ptr = getservbyname("mysql", "tcp"))) - mysql_port = (uint) ntohs((ushort) serv_ptr->s_port); - if ((env = getenv("MYSQL_TCP_PORT"))) - mysql_port =(uint) atoi(env); - } -#endif - } - if (!mysql_unix_port) - { - char *env; -#ifdef __WIN__ - mysql_unix_port = (char*) MYSQL_NAMEDPIPE; -#else - mysql_unix_port = (char*) MYSQL_UNIX_ADDR; -#endif - if ((env = getenv("MYSQL_UNIX_PORT"))) - mysql_unix_port = env; - } - mysql_debug(NullS); -#if defined(SIGPIPE) && !defined(THREAD) && !defined(__WIN__) - (void) signal(SIGPIPE,SIG_IGN); -#endif - } -#ifdef THREAD - else - my_thread_init(); /* Init if new thread */ -#endif -} - -#ifdef HAVE_OPENSSL -/************************************************************************** -** Fill in SSL part of MYSQL structure and set 'use_ssl' flag. -** NB! Errors are not reported until you do mysql_real_connect. -**************************************************************************/ - -int STDCALL -mysql_ssl_set(MYSQL *mysql, const char *key, const char *cert, - const char *ca, const char *capath) -{ - mysql->options.ssl_key = key==0 ? 0 : my_strdup(key,MYF(0)); - mysql->options.ssl_cert = cert==0 ? 0 : my_strdup(cert,MYF(0)); - mysql->options.ssl_ca = ca==0 ? 0 : my_strdup(ca,MYF(0)); - mysql->options.ssl_capath = capath==0 ? 0 : my_strdup(capath,MYF(0)); - mysql->options.use_ssl = true; - mysql->connector_fd = new_VioSSLConnectorFd(key, cert, ca, capath); - return 0; -} - -/************************************************************************** -**************************************************************************/ - -char * STDCALL -mysql_ssl_cipher(MYSQL *mysql) -{ - return (char *)mysql->net.vio->cipher_description(); -} - - -/************************************************************************** -** Free strings in the SSL structure and clear 'use_ssl' flag. -** NB! Errors are not reported until you do mysql_real_connect. -**************************************************************************/ - -int STDCALL -mysql_ssl_clear(MYSQL *mysql) -{ - my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR)); - mysql->options.ssl_key = 0; - mysql->options.ssl_cert = 0; - mysql->options.ssl_ca = 0; - mysql->options.ssl_capath = 0; - mysql->options.use_ssl = false; - mysql->connector_fd->delete(); - mysql->connector_fd = 0; - return 0; -} -#endif /* HAVE_OPENSSL */ - -/************************************************************************** -** Connect to sql server -** If host == 0 then use localhost -**************************************************************************/ - -MYSQL * STDCALL -mysql_connect(MYSQL *mysql,const char *host, - const char *user, const char *passwd) -{ - MYSQL *res; - mysql=mysql_init(mysql); /* Make it thread safe */ - { - DBUG_ENTER("mysql_connect"); - if (!(res=mysql_real_connect(mysql,host,user,passwd,NullS,0,NullS,0))) - { - if (mysql->free_me) - my_free((gptr) mysql,MYF(0)); - } - DBUG_RETURN(res); - } -} - - -/* -** Note that the mysql argument must be initialized with mysql_init() -** before calling mysql_real_connect ! -*/ - -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,uint client_flag) -{ - char buff[NAME_LEN+USERNAME_LENGTH+100],charset_name_buff[16]; - char *end,*host_info,*charset_name; - my_socket sock; - uint32 ip_addr; - struct sockaddr_in sock_addr; - uint pkt_length; - NET *net= &mysql->net; -#ifdef __WIN__ - HANDLE hPipe=INVALID_HANDLE_VALUE; -#endif -#ifdef HAVE_SYS_UN_H - struct sockaddr_un UNIXaddr; -#endif - init_sigpipe_variables - DBUG_ENTER("mysql_real_connect"); - - DBUG_PRINT("enter",("host: %s db: %s user: %s", - host ? host : "(Null)", - db ? db : "(Null)", - user ? user : "(Null)")); - - /* Don't give sigpipe errors if the client doesn't want them */ - set_sigpipe(mysql); - net->vio = 0; /* If something goes wrong */ - /* use default options */ - if (mysql->options.my_cnf_file || mysql->options.my_cnf_group) - { - mysql_read_default_options(&mysql->options, - (mysql->options.my_cnf_file ? - mysql->options.my_cnf_file : "my"), - mysql->options.my_cnf_group); - my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR)); - mysql->options.my_cnf_file=mysql->options.my_cnf_group=0; - } - - /* Some empty-string-tests are done because of ODBC */ - if (!host || !host[0]) - host=mysql->options.host; - if (!user || !user[0]) - user=mysql->options.user; - if (!passwd) - { - passwd=mysql->options.password; -#ifndef DONT_USE_MYSQL_PWD - if (!passwd) - passwd=getenv("MYSQL_PWD"); /* get it from environment (haneke) */ -#endif - } - if (!db || !db[0]) - db=mysql->options.db; - if (!port) - port=mysql->options.port; - if (!unix_socket) - unix_socket=mysql->options.unix_socket; - - mysql->reconnect=1; /* Reconnect as default */ - mysql->server_status=SERVER_STATUS_AUTOCOMMIT; - - /* - ** Grab a socket and connect it to the server - */ - -#if defined(HAVE_SYS_UN_H) - if ((!host || !strcmp(host,LOCAL_HOST)) && (unix_socket || mysql_unix_port)) - { - host=LOCAL_HOST; - if (!unix_socket) - unix_socket=mysql_unix_port; - host_info=(char*) ER(CR_LOCALHOST_CONNECTION); - DBUG_PRINT("info",("Using UNIX sock '%s'",unix_socket)); - if ((sock = socket(AF_UNIX,SOCK_STREAM,0)) == SOCKET_ERROR) - { - net->last_errno=CR_SOCKET_CREATE_ERROR; - sprintf(net->last_error,ER(net->last_errno),socket_errno); - goto error; - } - net->vio = vio_new(sock, VIO_TYPE_SOCKET, TRUE); - bzero((char*) &UNIXaddr,sizeof(UNIXaddr)); - UNIXaddr.sun_family = AF_UNIX; - strmov(UNIXaddr.sun_path, unix_socket); - if (connect2(sock,(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr), - mysql->options.connect_timeout) <0) - { - DBUG_PRINT("error",("Got error %d on connect to local server",socket_errno)); - net->last_errno=CR_CONNECTION_ERROR; - sprintf(net->last_error,ER(net->last_errno),unix_socket,socket_errno); - goto error; - } - } - else -#elif defined(__WIN__) - { - if ((unix_socket || - !host && is_NT() || - host && !strcmp(host,LOCAL_HOST_NAMEDPIPE) || - mysql->options.named_pipe || !have_tcpip)) - { - sock=0; - if ((hPipe=create_named_pipe(net, mysql->options.connect_timeout, - (char**) &host, (char**) &unix_socket)) == - INVALID_HANDLE_VALUE) - { - DBUG_PRINT("error", - ("host: '%s' socket: '%s' named_pipe: %d have_tcpip: %d", - host ? host : "<null>", - unix_socket ? unix_socket : "<null>", - (int) mysql->options.named_pipe, - (int) have_tcpip)); - if (mysql->options.named_pipe || - (host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) || - (unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE))) - goto error; /* User only requested named pipes */ - /* Try also with TCP/IP */ - } - else - { - net->vio=vio_new_win32pipe(hPipe); - sprintf(host_info=buff, ER(CR_NAMEDPIPE_CONNECTION), host, - unix_socket); - } - } - } - if (hPipe == INVALID_HANDLE_VALUE) -#endif - { - unix_socket=0; /* This is not used */ - if (!port) - port=mysql_port; - if (!host) - host=LOCAL_HOST; - sprintf(host_info=buff,ER(CR_TCP_CONNECTION),host); - DBUG_PRINT("info",("Server name: '%s'. TCP sock: %d", host,port)); - /* _WIN64 ; Assume that the (int) range is enough for socket() */ - if ((sock = (my_socket) socket(AF_INET,SOCK_STREAM,0)) == SOCKET_ERROR) - { - net->last_errno=CR_IPSOCK_ERROR; - sprintf(net->last_error,ER(net->last_errno),socket_errno); - goto error; - } - net->vio = vio_new(sock,VIO_TYPE_TCPIP,FALSE); - bzero((char*) &sock_addr,sizeof(sock_addr)); - sock_addr.sin_family = AF_INET; - - /* - ** The server name may be a host name or IP address - */ - - if ((int) (ip_addr = inet_addr(host)) != (int) INADDR_NONE) - { - memcpy_fixed(&sock_addr.sin_addr,&ip_addr,sizeof(ip_addr)); - } - else -#if defined(HAVE_GETHOSTBYNAME_R) && defined(_REENTRANT) && defined(THREAD) - { - int tmp_errno; - struct hostent tmp_hostent,*hp; - char buff2[GETHOSTBYNAME_BUFF_SIZE]; - hp = my_gethostbyname_r(host,&tmp_hostent,buff2,sizeof(buff2), - &tmp_errno); - if (!hp) - { - net->last_errno=CR_UNKNOWN_HOST; - sprintf(net->last_error, ER(CR_UNKNOWN_HOST), host, tmp_errno); - goto error; - } - memcpy(&sock_addr.sin_addr,hp->h_addr, (size_t) hp->h_length); - } -#else - { - struct hostent *hp; - if (!(hp=gethostbyname(host))) - { - net->last_errno=CR_UNKNOWN_HOST; - sprintf(net->last_error, ER(CR_UNKNOWN_HOST), host, socket_errno); - goto error; - } - memcpy(&sock_addr.sin_addr,hp->h_addr, (size_t) hp->h_length); - } -#endif - sock_addr.sin_port = (ushort) htons((ushort) port); - if (connect2(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr), - mysql->options.connect_timeout) <0) - { - DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno,host)); - net->last_errno= CR_CONN_HOST_ERROR; - sprintf(net->last_error ,ER(CR_CONN_HOST_ERROR), host, socket_errno); - goto error; - } - } - - 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->last_error,ER(net->last_errno)); - goto error; - } - vio_keepalive(net->vio,TRUE); - - /* Get version info */ - mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */ - if (mysql->options.connect_timeout && - vio_poll_read(net->vio, mysql->options.connect_timeout)) - { - net->last_errno= CR_SERVER_LOST; - strmov(net->last_error,ER(net->last_errno)); - goto error; - } - if ((pkt_length=net_safe_read(mysql)) == packet_error) - goto error; - - /* Check if version of protocoll matches current one */ - - mysql->protocol_version= net->read_pos[0]; - DBUG_DUMP("packet",(char*) net->read_pos,10); - DBUG_PRINT("info",("mysql protocol version %d, server=%d", - PROTOCOL_VERSION, mysql->protocol_version)); - if (mysql->protocol_version != PROTOCOL_VERSION && - mysql->protocol_version != PROTOCOL_VERSION-1) - { - net->last_errno= CR_VERSION_ERROR; - sprintf(net->last_error, ER(CR_VERSION_ERROR), mysql->protocol_version, - PROTOCOL_VERSION); - goto error; - } - end=strend((char*) net->read_pos+1); - mysql->thread_id=uint4korr(end+1); - end+=5; - strmake(mysql->scramble_buff,end,8); - end+=9; - if (pkt_length >= (uint) (end+1 - (char*) net->read_pos)) - mysql->server_capabilities=uint2korr(end); - if (pkt_length >= (uint) (end+18 - (char*) net->read_pos)) - { - /* New protocol with 16 bytes to describe server characteristics */ - mysql->server_language=end[2]; - mysql->server_status=uint2korr(end+3); - } - - /* 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, - MYF(MY_WME)); - charsets_dir=save; - } - else if (mysql->server_language) - { - charset_name=charset_name_buff; - sprintf(charset_name,"%d",mysql->server_language); /* In case of errors */ - if (!(mysql->charset = - get_charset((uint8) mysql->server_language, MYF(MY_WME)))) - mysql->charset = default_charset_info; /* shouldn't be fatal */ - - } - else - mysql->charset=default_charset_info; - - if (!mysql->charset) - { - net->last_errno=CR_CANT_READ_CHARSET; - if (mysql->options.charset_dir) - sprintf(net->last_error,ER(net->last_errno), - charset_name ? charset_name : "unknown", - mysql->options.charset_dir); - else - { - char cs_dir_name[FN_REFLEN]; - get_charsets_dir(cs_dir_name); - sprintf(net->last_error,ER(net->last_errno), - charset_name ? charset_name : "unknown", - cs_dir_name); - } - goto error; - } - - /* Save connection information */ - if (!user) user=""; - if (!passwd) passwd=""; - if (!my_multi_malloc(MYF(0), - &mysql->host_info, (uint) strlen(host_info)+1, - &mysql->host, (uint) strlen(host)+1, - &mysql->unix_socket,unix_socket ? - (uint) strlen(unix_socket)+1 : (uint) 1, - &mysql->server_version, - (uint) (end - (char*) net->read_pos), - NullS) || - !(mysql->user=my_strdup(user,MYF(0))) || - !(mysql->passwd=my_strdup(passwd,MYF(0)))) - { - strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY)); - goto error; - } - strmov(mysql->host_info,host_info); - strmov(mysql->host,host); - if (unix_socket) - strmov(mysql->unix_socket,unix_socket); - else - mysql->unix_socket=0; - strmov(mysql->server_version,(char*) net->read_pos+1); - mysql->port=port; - client_flag|=mysql->options.client_flag; - - /* Send client information for access check */ - client_flag|=CLIENT_CAPABILITIES; - -#ifdef HAVE_OPENSSL - if (mysql->options.use_ssl) - client_flag|=CLIENT_SSL; -#endif /* HAVE_OPENSSL */ - if (db) - client_flag|=CLIENT_CONNECT_WITH_DB; -#ifdef HAVE_COMPRESS - if ((mysql->server_capabilities & CLIENT_COMPRESS) && - (mysql->options.compress || (client_flag & CLIENT_COMPRESS))) - client_flag|=CLIENT_COMPRESS; /* We will use compression */ - else -#endif - client_flag&= ~CLIENT_COMPRESS; - -#ifdef HAVE_OPENSSL - if ((mysql->server_capabilities & CLIENT_SSL) && - (mysql->options.use_ssl || (client_flag & CLIENT_SSL))) - { - DBUG_PRINT("info", ("Changing IO layer to SSL")); - client_flag |= CLIENT_SSL; - } - else - { - if (client_flag & CLIENT_SSL) - { - DBUG_PRINT("info", ("Leaving IO layer intact because server doesn't support SSL")); - } - client_flag &= ~CLIENT_SSL; - } -#endif /* HAVE_OPENSSL */ - - int2store(buff,client_flag); - mysql->client_flag=client_flag; - -#ifdef HAVE_OPENSSL - /* Oops.. are we careful enough to not send ANY information */ - /* without encryption? */ - if (client_flag & CLIENT_SSL) - { - if (my_net_write(net,buff,(uint) (2)) || net_flush(net)) - goto error; - /* Do the SSL layering. */ - DBUG_PRINT("info", ("IO layer change in progress...")); - VioSSLConnectorFd* connector_fd = (VioSSLConnectorFd*) - (mysql->connector_fd); - VioSocket* vio_socket = (VioSocket*)(mysql->net.vio); - VioSSL* vio_ssl = connector_fd->connect(vio_socket); - mysql->net.vio = (NetVio*)(vio_ssl); - } -#endif /* HAVE_OPENSSL */ - - DBUG_PRINT("info",("Server version = '%s' capabilites: %ld status: %d client_flag: %d", - mysql->server_version,mysql->server_capabilities, - mysql->server_status, client_flag)); - - int3store(buff+2,max_allowed_packet); - if (user && user[0]) - strmake(buff+5,user,32); /* Max user name */ - else - read_user_name((char*) buff+5); -#ifdef _CUSTOMCONFIG_ -#include "_cust_libmysql.h"; -#endif - DBUG_PRINT("info",("user: %s",buff+5)); - end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd, - (my_bool) (mysql->protocol_version == 9)); - if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB)) - { - end=strmake(end+1,db,NAME_LEN); - mysql->db=my_strdup(db,MYF(MY_WME)); - db=0; - } - if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net) || - net_safe_read(mysql) == packet_error) - goto error; - if (client_flag & CLIENT_COMPRESS) /* We will use compression */ - net->compress=1; - if (db && mysql_select_db(mysql,db)) - goto error; - if (mysql->options.init_command) - { - my_bool reconnect=mysql->reconnect; - mysql->reconnect=0; - if (mysql_query(mysql,mysql->options.init_command)) - goto error; - mysql_free_result(mysql_use_result(mysql)); - mysql->reconnect=reconnect; - } - - DBUG_PRINT("exit",("Mysql handler: %lx",mysql)); - reset_sigpipe(mysql); - DBUG_RETURN(mysql); - -error: - reset_sigpipe(mysql); - DBUG_PRINT("error",("message: %u (%s)",net->last_errno,net->last_error)); - { - /* Free alloced memory */ - my_bool free_me=mysql->free_me; - end_server(mysql); - mysql->free_me=0; - mysql_close(mysql); - mysql->free_me=free_me; - } - DBUG_RETURN(0); -} - - -static my_bool mysql_reconnect(MYSQL *mysql) -{ - MYSQL tmp_mysql; - DBUG_ENTER("mysql_reconnect"); - - if (!mysql->reconnect || - (mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info) - { - /* Allov reconnect next time */ - mysql->server_status&= ~SERVER_STATUS_IN_TRANS; - DBUG_RETURN(1); - } - mysql_init(&tmp_mysql); - tmp_mysql.options=mysql->options; - bzero((char*) &mysql->options,sizeof(mysql->options)); - if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd, - mysql->db, mysql->port, mysql->unix_socket, - mysql->client_flag)) - DBUG_RETURN(1); - tmp_mysql.free_me=mysql->free_me; - mysql->free_me=0; - mysql_close(mysql); - *mysql=tmp_mysql; - net_clear(&mysql->net); - mysql->affected_rows= ~(my_ulonglong) 0; - DBUG_RETURN(0); -} - - -/************************************************************************** -** Change user and database -**************************************************************************/ - -my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, - const char *passwd, const char *db) -{ - char buff[512],*pos=buff; - DBUG_ENTER("mysql_change_user"); - - if (!user) - user=""; - if (!passwd) - passwd=""; - - pos=strmov(pos,user)+1; - pos=scramble(pos, mysql->scramble_buff, passwd, - (my_bool) (mysql->protocol_version == 9)); - pos=strmov(pos+1,db ? db : ""); - if (simple_command(mysql,COM_CHANGE_USER, buff,(uint) (pos-buff),0)) - DBUG_RETURN(1); - - 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)); - - mysql->user= my_strdup(user,MYF(MY_WME)); - mysql->passwd=my_strdup(passwd,MYF(MY_WME)); - mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0; - DBUG_RETURN(0); -} - - -/************************************************************************** -** Set current database -**************************************************************************/ - -int STDCALL -mysql_select_db(MYSQL *mysql, const char *db) -{ - int error; - DBUG_ENTER("mysql_select_db"); - DBUG_PRINT("enter",("db: '%s'",db)); - - if ((error=simple_command(mysql,COM_INIT_DB,db,(uint) strlen(db),0))) - DBUG_RETURN(error); - my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR)); - mysql->db=my_strdup(db,MYF(MY_WME)); - DBUG_RETURN(0); -} - - -/************************************************************************* -** Send a QUIT to the server and close the connection -** If handle is alloced by mysql connect free it. -*************************************************************************/ - -void STDCALL -mysql_close(MYSQL *mysql) -{ - DBUG_ENTER("mysql_close"); - if (mysql) /* Some simple safety */ - { - if (mysql->net.vio != 0) - { - free_old_query(mysql); - mysql->status=MYSQL_STATUS_READY; /* Force command */ - mysql->reconnect=0; - simple_command(mysql,COM_QUIT,NullS,0,1); - end_server(mysql); - } - my_free((gptr) mysql->host_info,MYF(MY_ALLOW_ZERO_PTR)); - 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)); - my_free(mysql->options.init_command,MYF(MY_ALLOW_ZERO_PTR)); - 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)); - my_free(mysql->options.unix_socket,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->options.db,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR)); - /* Clear pointers for better safety */ - mysql->host_info=mysql->user=mysql->passwd=mysql->db=0; - bzero((char*) &mysql->options,sizeof(mysql->options)); - mysql->net.vio = 0; -#ifdef HAVE_OPENSSL - ((VioConnectorFd*)(mysql->connector_fd))->delete(); - mysql->connector_fd = 0; -#endif /* HAVE_OPENSSL */ - if (mysql->free_me) - my_free((gptr) mysql,MYF(0)); - } - DBUG_VOID_RETURN; -} - - -/************************************************************************** -** Do a query. If query returned rows, free old rows. -** Read data by mysql_store_result or by repeat call of mysql_fetch_row -**************************************************************************/ - -int STDCALL -mysql_query(MYSQL *mysql, const char *query) -{ - return mysql_real_query(mysql,query, (uint) strlen(query)); -} - -/* - Send the query and return so we can do something else. - Needs to be followed by mysql_read_query_result() when we want to - finish processing it. -*/ - -int STDCALL -mysql_send_query(MYSQL* mysql, const char* query, uint length) -{ - return simple_command(mysql, COM_QUERY, query, length, 1); -} - -int STDCALL mysql_read_query_result(MYSQL *mysql) -{ - uchar *pos; - ulong field_count; - MYSQL_DATA *fields; - uint length; - DBUG_ENTER("mysql_read_query_result"); - - if ((length = net_safe_read(mysql)) == packet_error) - DBUG_RETURN(-1); - free_old_query(mysql); /* Free old result */ -get_info: - 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); - if (mysql->server_capabilities & CLIENT_TRANSACTIONS) - { - mysql->server_status=uint2korr(pos); pos+=2; - } - if (pos < mysql->net.read_pos+length && net_field_length(&pos)) - mysql->info=(char*) pos; - DBUG_RETURN(0); - } - if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */ - { - int error=send_file_to_server(mysql,(char*) pos); - if ((length=net_safe_read(mysql)) == packet_error || error) - DBUG_RETURN(-1); - goto get_info; /* Get info packet */ - } - 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,5))) - DBUG_RETURN(-1); - if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc, - (uint) field_count,0, - (my_bool) test(mysql->server_capabilities & - CLIENT_LONG_FLAG)))) - DBUG_RETURN(-1); - mysql->status=MYSQL_STATUS_GET_RESULT; - mysql->field_count=field_count; - DBUG_RETURN(0); -} - -int STDCALL -mysql_real_query(MYSQL *mysql, const char *query, uint length) -{ - DBUG_ENTER("mysql_real_query"); - DBUG_PRINT("enter",("handle: %lx",mysql)); - DBUG_PRINT("query",("Query = \"%s\"",query)); - if (simple_command(mysql,COM_QUERY,query,length,1)) - DBUG_RETURN(-1); - DBUG_RETURN(mysql_read_query_result(mysql)); -} - -static int -send_file_to_server(MYSQL *mysql, const char *filename) -{ - int fd, readcount; - char buf[IO_SIZE*15],*tmp_name; - DBUG_ENTER("send_file_to_server"); - - fn_format(buf,filename,"","",4); /* Convert to client format */ - if (!(tmp_name=my_strdup(buf,MYF(0)))) - { - strmov(mysql->net.last_error, ER(mysql->net.last_errno=CR_OUT_OF_MEMORY)); - DBUG_RETURN(-1); - } - if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0) - { - mysql->net.last_errno=EE_FILENOTFOUND; - sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno); - strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1); - my_net_write(&mysql->net,"",0); net_flush(&mysql->net); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); - } - - while ((readcount = (int) my_read(fd,buf,sizeof(buf),MYF(0))) > 0) - { - if (my_net_write(&mysql->net,buf,readcount)) - { - mysql->net.last_errno=CR_SERVER_LOST; - strmov(mysql->net.last_error,ER(mysql->net.last_errno)); - DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file")); - (void) my_close(fd,MYF(0)); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); - } - } - (void) my_close(fd,MYF(0)); - /* 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),socket_errno); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); - } - if (readcount < 0) - { - mysql->net.last_errno=EE_READ; /* the errmsg for not entire file read */ - sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno); - strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); - } - DBUG_RETURN(0); -} - - -/************************************************************************** -** Alloc result struct for buffered results. All rows are read to buffer. -** mysql_data_seek may be used. -**************************************************************************/ - -MYSQL_RES * STDCALL -mysql_store_result(MYSQL *mysql) -{ - MYSQL_RES *result; - DBUG_ENTER("mysql_store_result"); - - if (!mysql->fields) - DBUG_RETURN(0); - if (mysql->status != MYSQL_STATUS_GET_RESULT) - { - strmov(mysql->net.last_error, - ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC)); - DBUG_RETURN(0); - } - mysql->status=MYSQL_STATUS_READY; /* server is ready */ - if (!(result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+ - sizeof(ulong)*mysql->field_count, - MYF(MY_WME | MY_ZEROFILL)))) - { - mysql->net.last_errno=CR_OUT_OF_MEMORY; - strmov(mysql->net.last_error, ER(mysql->net.last_errno)); - DBUG_RETURN(0); - } - result->eof=1; /* Marker for buffered */ - result->lengths=(ulong*) (result+1); - if (!(result->data=read_rows(mysql,mysql->fields,mysql->field_count))) - { - my_free((gptr) result,MYF(0)); - DBUG_RETURN(0); - } - mysql->affected_rows= result->row_count= result->data->rows; - result->data_cursor= result->data->data; - result->fields= mysql->fields; - result->field_alloc= mysql->field_alloc; - result->field_count= mysql->field_count; - result->current_field=0; - result->current_row=0; /* Must do a fetch first */ - mysql->fields=0; /* fields is now in result */ - DBUG_RETURN(result); /* Data fetched */ -} - - -/************************************************************************** -** Alloc struct for use with unbuffered reads. Data is fetched by domand -** when calling to mysql_fetch_row. -** mysql_data_seek is a noop. -** -** No other queries may be specified with the same MYSQL handle. -** There shouldn't be much processing per row because mysql server shouldn't -** have to wait for the client (and will not wait more than 30 sec/packet). -**************************************************************************/ - -MYSQL_RES * STDCALL -mysql_use_result(MYSQL *mysql) -{ - MYSQL_RES *result; - DBUG_ENTER("mysql_use_result"); - - if (!mysql->fields) - DBUG_RETURN(0); - if (mysql->status != MYSQL_STATUS_GET_RESULT) - { - strmov(mysql->net.last_error, - ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC)); - DBUG_RETURN(0); - } - if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result)+ - sizeof(ulong)*mysql->field_count, - MYF(MY_WME | MY_ZEROFILL)))) - DBUG_RETURN(0); - result->lengths=(ulong*) (result+1); - if (!(result->row=(MYSQL_ROW) - my_malloc(sizeof(result->row[0])*(mysql->field_count+1), MYF(MY_WME)))) - { /* Ptrs: to one row */ - my_free((gptr) result,MYF(0)); - DBUG_RETURN(0); - } - result->fields= mysql->fields; - result->field_alloc= mysql->field_alloc; - result->field_count= mysql->field_count; - result->current_field=0; - result->handle= mysql; - result->current_row= 0; - mysql->fields=0; /* fields is now in result */ - mysql->status=MYSQL_STATUS_USE_RESULT; - DBUG_RETURN(result); /* Data is read to be fetched */ -} - - - -/************************************************************************** -** Return next field of the query results -**************************************************************************/ - -MYSQL_FIELD * STDCALL -mysql_fetch_field(MYSQL_RES *result) -{ - if (result->current_field >= result->field_count) - return(NULL); - return &result->fields[result->current_field++]; -} - - -/************************************************************************** -** Return next row of the query results -**************************************************************************/ - -MYSQL_ROW STDCALL -mysql_fetch_row(MYSQL_RES *res) -{ - DBUG_ENTER("mysql_fetch_row"); - if (!res->data) - { /* Unbufferred fetch */ - if (!res->eof) - { - if (!(read_one_row(res->handle,res->field_count,res->row, res->lengths))) - { - res->row_count++; - DBUG_RETURN(res->current_row=res->row); - } - else - { - DBUG_PRINT("info",("end of data")); - res->eof=1; - res->handle->status=MYSQL_STATUS_READY; - /* Don't clear handle in mysql_free_results */ - res->handle=0; - } - } - DBUG_RETURN((MYSQL_ROW) NULL); - } - { - MYSQL_ROW tmp; - if (!res->data_cursor) - { - DBUG_PRINT("info",("end of data")); - DBUG_RETURN(res->current_row=(MYSQL_ROW) NULL); - } - tmp = res->data_cursor->data; - res->data_cursor = res->data_cursor->next; - DBUG_RETURN(res->current_row=tmp); - } -} - -/************************************************************************** -** 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. -**************************************************************************/ - -ulong * STDCALL -mysql_fetch_lengths(MYSQL_RES *res) -{ - ulong *lengths,*prev_length; - byte *start; - MYSQL_ROW column,end; - - if (!(column=res->current_row)) - return 0; /* Something is wrong */ - if (res->data) - { - start=0; - prev_length=0; /* Keep gcc happy */ - lengths=res->lengths; - for (end=column+res->field_count+1 ; column != end ; column++,lengths++) - { - if (!*column) - { - *lengths=0; /* Null */ - continue; - } - if (start) /* Found end of prev string */ - *prev_length= (uint) (*column-start-1); - start= *column; - prev_length=lengths; - } - } - return res->lengths; -} - -/************************************************************************** -** Move to a specific row and column -**************************************************************************/ - -void STDCALL -mysql_data_seek(MYSQL_RES *result, my_ulonglong row) -{ - MYSQL_ROWS *tmp=0; - DBUG_PRINT("info",("mysql_data_seek(%ld)",(long) row)); - if (result->data) - for (tmp=result->data->data; row-- && tmp ; tmp = tmp->next) ; - result->current_row=0; - result->data_cursor = tmp; -} - -/************************************************************************* -** put the row or field cursor one a position one got from mysql_row_tell() -** This doesn't restore any data. The next mysql_fetch_row or -** mysql_fetch_field will return the next row or field after the last used -*************************************************************************/ - -MYSQL_ROW_OFFSET STDCALL -mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET row) -{ - MYSQL_ROW_OFFSET return_value=result->data_cursor; - result->current_row= 0; - result->data_cursor= row; - return return_value; -} - - -MYSQL_FIELD_OFFSET STDCALL -mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET field_offset) -{ - MYSQL_FIELD_OFFSET return_value=result->current_field; - result->current_field=field_offset; - return return_value; -} - -/***************************************************************************** -** List all databases -*****************************************************************************/ - -MYSQL_RES * STDCALL -mysql_list_dbs(MYSQL *mysql, const char *wild) -{ - char buff[255]; - DBUG_ENTER("mysql_list_dbs"); - - append_wild(strmov(buff,"show databases"),buff+sizeof(buff),wild); - if (mysql_query(mysql,buff)) - DBUG_RETURN(0); - DBUG_RETURN (mysql_store_result(mysql)); -} - - -/***************************************************************************** -** List all tables in a database -** If wild is given then only the tables matching wild is returned -*****************************************************************************/ - -MYSQL_RES * STDCALL -mysql_list_tables(MYSQL *mysql, const char *wild) -{ - char buff[255]; - DBUG_ENTER("mysql_list_tables"); - - append_wild(strmov(buff,"show tables"),buff+sizeof(buff),wild); - if (mysql_query(mysql,buff)) - DBUG_RETURN(0); - DBUG_RETURN (mysql_store_result(mysql)); -} - - -/************************************************************************** -** List all fields in a table -** If wild is given then only the fields matching wild is returned -** Instead of this use query: -** show fields in 'table' like "wild" -**************************************************************************/ - -MYSQL_RES * STDCALL -mysql_list_fields(MYSQL *mysql, const char *table, const char *wild) -{ - MYSQL_RES *result; - MYSQL_DATA *query; - char buff[257],*end; - DBUG_ENTER("mysql_list_fields"); - DBUG_PRINT("enter",("table: '%s' wild: '%s'",table,wild ? wild : "")); - - LINT_INIT(query); - - end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128); - if (simple_command(mysql,COM_FIELD_LIST,buff,(uint) (end-buff),1) || - !(query = read_rows(mysql,(MYSQL_FIELD*) 0,6))) - DBUG_RETURN(NULL); - - free_old_query(mysql); - if (!(result = (MYSQL_RES *) my_malloc(sizeof(MYSQL_RES), - MYF(MY_WME | MY_ZEROFILL)))) - { - free_rows(query); - DBUG_RETURN(NULL); - } - result->field_alloc=mysql->field_alloc; - mysql->fields=0; - result->field_count = (uint) query->rows; - result->fields= unpack_fields(query,&result->field_alloc, - result->field_count,1, - (my_bool) test(mysql->server_capabilities & - CLIENT_LONG_FLAG)); - result->eof=1; - DBUG_RETURN(result); -} - -/* List all running processes (threads) in server */ - -MYSQL_RES * STDCALL -mysql_list_processes(MYSQL *mysql) -{ - MYSQL_DATA *fields; - uint field_count; - uchar *pos; - DBUG_ENTER("mysql_list_processes"); - - LINT_INIT(fields); - if (simple_command(mysql,COM_PROCESS_INFO,0,0,0)) - DBUG_RETURN(0); - free_old_query(mysql); - pos=(uchar*) mysql->net.read_pos; - field_count=(uint) net_field_length(&pos); - if (!(fields = read_rows(mysql,(MYSQL_FIELD*) 0,5))) - DBUG_RETURN(NULL); - if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,field_count,0, - (my_bool) test(mysql->server_capabilities & - CLIENT_LONG_FLAG)))) - DBUG_RETURN(0); - mysql->status=MYSQL_STATUS_GET_RESULT; - mysql->field_count=field_count; - DBUG_RETURN(mysql_store_result(mysql)); -} - - -int STDCALL -mysql_create_db(MYSQL *mysql, const char *db) -{ - DBUG_ENTER("mysql_createdb"); - DBUG_PRINT("enter",("db: %s",db)); - DBUG_RETURN(simple_command(mysql,COM_CREATE_DB,db, (uint) strlen(db),0)); -} - - -int STDCALL -mysql_drop_db(MYSQL *mysql, const char *db) -{ - DBUG_ENTER("mysql_drop_db"); - DBUG_PRINT("enter",("db: %s",db)); - DBUG_RETURN(simple_command(mysql,COM_DROP_DB,db,(uint) strlen(db),0)); -} - - -int STDCALL -mysql_shutdown(MYSQL *mysql) -{ - DBUG_ENTER("mysql_shutdown"); - DBUG_RETURN(simple_command(mysql,COM_SHUTDOWN,0,0,0)); -} - - -int STDCALL -mysql_refresh(MYSQL *mysql,uint options) -{ - uchar bits[1]; - DBUG_ENTER("mysql_refresh"); - bits[0]= (uchar) options; - DBUG_RETURN(simple_command(mysql,COM_REFRESH,(char*) bits,1,0)); -} - -int STDCALL -mysql_kill(MYSQL *mysql,ulong pid) -{ - char buff[12]; - DBUG_ENTER("mysql_kill"); - int4store(buff,pid); - DBUG_RETURN(simple_command(mysql,COM_PROCESS_KILL,buff,4,0)); -} - - -int STDCALL -mysql_dump_debug_info(MYSQL *mysql) -{ - DBUG_ENTER("mysql_dump_debug_info"); - DBUG_RETURN(simple_command(mysql,COM_DEBUG,0,0,0)); -} - -char * STDCALL -mysql_stat(MYSQL *mysql) -{ - DBUG_ENTER("mysql_stat"); - if (simple_command(mysql,COM_STATISTICS,0,0,0)) - return mysql->net.last_error; - mysql->net.read_pos[mysql->packet_length]=0; /* End of stat string */ - if (!mysql->net.read_pos[0]) - { - mysql->net.last_errno=CR_WRONG_HOST_INFO; - strmov(mysql->net.last_error, ER(mysql->net.last_errno)); - return mysql->net.last_error; - } - DBUG_RETURN((char*) mysql->net.read_pos); -} - - -int STDCALL -mysql_ping(MYSQL *mysql) -{ - DBUG_ENTER("mysql_ping"); - DBUG_RETURN(simple_command(mysql,COM_PING,0,0,0)); -} - - -char * STDCALL -mysql_get_server_info(MYSQL *mysql) -{ - return((char*) mysql->server_version); -} - - -char * STDCALL -mysql_get_host_info(MYSQL *mysql) -{ - return(mysql->host_info); -} - - -uint STDCALL -mysql_get_proto_info(MYSQL *mysql) -{ - return (mysql->protocol_version); -} - -char * STDCALL -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 */ - break; - case MYSQL_OPT_NAMED_PIPE: - mysql->options.named_pipe=1; /* 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: - my_free(mysql->options.init_command,MYF(MY_ALLOW_ZERO_PTR)); - mysql->options.init_command=my_strdup(arg,MYF(MY_WME)); - 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; - default: - DBUG_RETURN(-1); - } - DBUG_RETURN(0); -} - -/**************************************************************************** -** Functions to get information from the MySQL structure -** These are functions to make shared libraries more usable. -****************************************************************************/ - -/* MYSQL_RES */ -my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res) -{ - return res->row_count; -} - -unsigned int STDCALL mysql_num_fields(MYSQL_RES *res) -{ - return res->field_count; -} - -my_bool STDCALL mysql_eof(MYSQL_RES *res) -{ - return res->eof; -} - -MYSQL_FIELD * STDCALL mysql_fetch_field_direct(MYSQL_RES *res,uint fieldnr) -{ - return &(res)->fields[fieldnr]; -} - -MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res) -{ - return (res)->fields; -} - -MYSQL_ROWS * STDCALL mysql_row_tell(MYSQL_RES *res) -{ - return res->data_cursor; -} - -uint STDCALL mysql_field_tell(MYSQL_RES *res) -{ - return (res)->current_field; -} - -/* MYSQL */ - -unsigned int STDCALL mysql_field_count(MYSQL *mysql) -{ - return mysql->field_count; -} - -my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql) -{ - return (mysql)->affected_rows; -} - -my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql) -{ - return (mysql)->insert_id; -} - -uint STDCALL mysql_errno(MYSQL *mysql) -{ - return (mysql)->net.last_errno; -} - -char * STDCALL mysql_error(MYSQL *mysql) -{ - return (mysql)->net.last_error; -} - -char *STDCALL mysql_info(MYSQL *mysql) -{ - return (mysql)->info; -} - -ulong STDCALL mysql_thread_id(MYSQL *mysql) -{ - return (mysql)->thread_id; -} - -const char * STDCALL mysql_character_set_name(MYSQL *mysql) -{ - return mysql->charset->name; -} - - -uint STDCALL mysql_thread_safe(void) -{ -#ifdef THREAD - return 1; -#else - return 0; -#endif -} - -/**************************************************************************** -** Some support functions -****************************************************************************/ - -/* -** Add escape characters to a string (blob?) to make it suitable for a insert -** to should at least have place for length*2+1 chars -** Returns the length of the to string -*/ - -ulong STDCALL -mysql_escape_string(char *to,const char *from,ulong length) -{ - return mysql_sub_escape_string(default_charset_info,to,from,length); -} - -ulong STDCALL -mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, - ulong length) -{ - return mysql_sub_escape_string(mysql->charset,to,from,length); -} - - -static ulong -mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, - const char *from, ulong length) -{ - const char *to_start=to; - const char *end; -#ifdef USE_MB - my_bool use_mb_flag=use_mb(charset_info); -#endif - for (end=from+length; from != end ; from++) - { -#ifdef USE_MB - int l; - if (use_mb_flag && (l = my_ismbchar(charset_info, from, end))) - { - while (l--) - *to++ = *from++; - from--; - continue; - } -#endif - switch (*from) { - case 0: /* Must be escaped for 'mysql' */ - *to++= '\\'; - *to++= '0'; - break; - case '\n': /* Must be escaped for logs */ - *to++= '\\'; - *to++= 'n'; - break; - case '\r': - *to++= '\\'; - *to++= 'r'; - break; - case '\\': - *to++= '\\'; - *to++= '\\'; - break; - case '\'': - *to++= '\\'; - *to++= '\''; - break; - case '"': /* Better safe than sorry */ - *to++= '\\'; - *to++= '"'; - break; - case '\032': /* This gives problems on Win32 */ - *to++= '\\'; - *to++= 'Z'; - break; - default: - *to++= *from; - } - } - *to=0; - return (ulong) (to-to_start); -} - - -char * STDCALL -mysql_odbc_escape_string(MYSQL *mysql, - char *to, ulong to_length, - const char *from, ulong from_length, - void *param, - char * (*extend_buffer) - (void *, char *, ulong *)) -{ - char *to_end=to+to_length-5; - const char *end; -#ifdef USE_MB - my_bool use_mb_flag=use_mb(mysql->charset); -#endif - - for (end=from+from_length; from != end ; from++) - { - if (to >= to_end) - { - to_length = (ulong) (end-from)+512; /* We want this much more */ - if (!(to=(*extend_buffer)(param, to, &to_length))) - return to; - to_end=to+to_length-5; - } -#ifdef USE_MB - { - int l; - if (use_mb_flag && (l = my_ismbchar(mysql->charset, from, end))) - { - while (l--) - *to++ = *from++; - from--; - continue; - } - } -#endif - switch (*from) { - case 0: /* Must be escaped for 'mysql' */ - *to++= '\\'; - *to++= '0'; - break; - case '\n': /* Must be escaped for logs */ - *to++= '\\'; - *to++= 'n'; - break; - case '\r': - *to++= '\\'; - *to++= 'r'; - break; - case '\\': - *to++= '\\'; - *to++= '\\'; - break; - case '\'': - *to++= '\\'; - *to++= '\''; - break; - case '"': /* Better safe than sorry */ - *to++= '\\'; - *to++= '"'; - break; - case '\032': /* This gives problems on Win32 */ - *to++= '\\'; - *to++= 'Z'; - break; - default: - *to++= *from; - } - } - return to; -} - -void STDCALL -myodbc_remove_escape(MYSQL *mysql,char *name) -{ - char *to; -#ifdef USE_MB - my_bool use_mb_flag=use_mb(mysql->charset); - char *end; - LINT_INIT(end); - if (use_mb_flag) - for (end=name; *end ; end++) ; -#endif - - for (to=name ; *name ; name++) - { -#ifdef USE_MB - int l; - if (use_mb_flag && (l = my_ismbchar( mysql->charset, name , end ) ) ) - { - while (l--) - *to++ = *name++; - name--; - continue; - } -#endif - if (*name == '\\' && name[1]) - name++; - *to++= *name; - } - *to=0; -} |