diff options
author | MySQL Team <mysql@php.net> | 2001-01-23 16:48:50 +0000 |
---|---|---|
committer | MySQL Team <mysql@php.net> | 2001-01-23 16:48:50 +0000 |
commit | 800f555b707c696798877c80352ded46289e87c4 (patch) | |
tree | c540242b6e6da4e9b99b46797a26b215abef0a64 /ext/mysql/libmysql/libmysql.c | |
parent | d36858681a0d48414702524ebd16f31289b06fa8 (diff) | |
download | php-git-800f555b707c696798877c80352ded46289e87c4.tar.gz |
Upgrade ext/mysql/libmysql to version 3.23.32. One notable bug fix is
that the client can now connect to a server which is using a default
charset other than latin1.
Diffstat (limited to 'ext/mysql/libmysql/libmysql.c')
-rw-r--r-- | ext/mysql/libmysql/libmysql.c | 171 |
1 files changed, 135 insertions, 36 deletions
diff --git a/ext/mysql/libmysql/libmysql.c b/ext/mysql/libmysql/libmysql.c index a5ba1406a4..52fa65d72a 100644 --- a/ext/mysql/libmysql/libmysql.c +++ b/ext/mysql/libmysql/libmysql.c @@ -52,6 +52,12 @@ my_string mysql_unix_port=0; #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES | CLIENT_TRANSACTIONS) +#ifdef __WIN__ +#define CONNECT_TIMEOUT 20 +#else +#define CONNECT_TIMEOUT 0 +#endif + #if defined(MSDOS) || defined(__WIN__) #define ERRNO WSAGetLastError() #define perror(A) @@ -100,13 +106,14 @@ static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, * Base version coded by Steve Bernacki, Jr. <steve@navinet.net> *****************************************************************************/ -static int connect2(File s, const struct sockaddr *name, uint namelen, uint to) +static int connect2(my_socket s, const struct sockaddr *name, uint namelen, + uint timeout) { #if defined(__WIN__) return connect(s, (struct sockaddr*) name, namelen); #else int flags, res, s_err; - size_socket s_err_size = sizeof(uint); + SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint); fd_set sfds; struct timeval tv; time_t start_time, now_time; @@ -115,7 +122,7 @@ static int connect2(File s, const struct sockaddr *name, uint namelen, uint to) * exactly like the normal connect() call does. */ - if (to == 0) + if (timeout == 0) return connect(s, (struct sockaddr*) name, namelen); flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */ @@ -162,13 +169,13 @@ static int connect2(File s, const struct sockaddr *name, uint namelen, uint to) start_time = time(NULL); for (;;) { - tv.tv_sec = (long) to; + tv.tv_sec = (long) timeout; tv.tv_usec = 0; if ((res = select(s+1, NULL, &sfds, NULL, &tv)) >= 0) break; now_time=time(NULL); - to-= (uint) (now_time - start_time); - if (errno != EINTR || (int) to <= 0) + timeout-= (uint) (now_time - start_time); + if (errno != EINTR || (int) timeout <= 0) return -1; } @@ -182,7 +189,7 @@ static int connect2(File s, const struct sockaddr *name, uint namelen, uint to) return(-1); if (s_err) - { /* getsockopt() could suceed */ + { /* getsockopt could succeed */ errno = s_err; return(-1); /* but return an error... */ } @@ -392,7 +399,7 @@ static void free_rows(MYSQL_DATA *cur) { if (cur) { - free_root(&cur->alloc); + free_root(&cur->alloc,MYF(0)); my_free((gptr) cur,MYF(0)); } } @@ -459,8 +466,8 @@ static void free_old_query(MYSQL *mysql) { DBUG_ENTER("free_old_query"); if (mysql->fields) - free_root(&mysql->field_alloc); - init_alloc_root(&mysql->field_alloc,8192); /* Assume rowlength < 8192 */ + 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; @@ -512,8 +519,8 @@ static void read_user_name(char *name) static void read_user_name(char *name) { - char *str=getenv("USER"); - strmov(name,str ? str : "ODBC"); /* ODBC will send user variable */ + char *str=getenv("USER"); /* ODBC will send user variable */ + strmake(name,str ? str : "ODBC", USERNAME_LENGTH); } #endif @@ -557,7 +564,7 @@ append_wild(char *to, char *end, const char *wild) **************************************************************************/ void STDCALL -mysql_debug(const char *debug) +mysql_debug(const char *debug __attribute__((unused))) { #ifndef DBUG_OFF char *env; @@ -649,7 +656,7 @@ mysql_free_result(MYSQL_RES *result) } free_rows(result->data); if (result->fields) - free_root(&result->field_alloc); + free_root(&result->field_alloc,MYF(0)); if (result->row) my_free((gptr) result->row,MYF(0)); my_free((gptr) result,MYF(0)); @@ -665,8 +672,9 @@ mysql_free_result(MYSQL_RES *result) 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", + "ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath", + "character-set-dir", "default-character-set", "interactive-timeout", + "connect_timeout", NullS }; @@ -726,6 +734,7 @@ static void mysql_read_default_options(struct st_mysql_options *options, 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); @@ -796,6 +805,9 @@ static void mysql_read_default_options(struct st_mysql_options *options, 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; default: DBUG_PRINT("warning",("unknown option: %s",option[0])); } @@ -839,6 +851,8 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, 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 @@ -873,7 +887,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, strmov(net->last_error,ER(net->last_errno)); DBUG_RETURN(0); } - init_alloc_root(&result->alloc,8192); /* Assume rowlength < 8192 */ + init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */ result->alloc.min_malloc=sizeof(MYSQL_ROWS); prev_ptr= &result->data; result->rows=0; @@ -986,9 +1000,7 @@ mysql_init(MYSQL *mysql) } else bzero((char*) (mysql),sizeof(*(mysql))); -#ifdef __WIN__ - mysql->options.connect_timeout=20; -#endif + mysql->options.connect_timeout=CONNECT_TIMEOUT; #if defined(SIGPIPE) && defined(THREAD) if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE)) (void) signal(SIGPIPE,pipe_sig_handler); @@ -1125,8 +1137,9 @@ 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[100],charset_name_buff[16],*end,*host_info, *charset_name; - int sock; + 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; @@ -1257,7 +1270,8 @@ 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)); - if ((sock = socket(AF_INET,SOCK_STREAM,0)) == SOCKET_ERROR) + /* _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),ERRNO); @@ -1317,6 +1331,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, 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; @@ -1325,6 +1340,13 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, /* 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; @@ -1370,7 +1392,10 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, { charset_name=charset_name_buff; sprintf(charset_name,"%d",mysql->server_language); /* In case of errors */ - mysql->charset=get_charset((uint8) mysql->server_language, MYF(MY_WME)); + 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; @@ -1378,10 +1403,18 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if (!mysql->charset) { net->last_errno=CR_CANT_READ_CHARSET; - sprintf(net->last_error,ER(net->last_errno), - charset_name ? charset_name : "unknown", - mysql->options.charset_dir ? mysql->options.charset_dir : - "default"); + 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; } @@ -1410,10 +1443,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, mysql->unix_socket=0; strmov(mysql->server_version,(char*) net->read_pos+1); mysql->port=port; - mysql->client_flag=client_flag | mysql->options.client_flag; - DBUG_PRINT("info",("Server version = '%s' capabilites: %ld status: %d", - mysql->server_version,mysql->server_capabilities, - mysql->server_status)); + client_flag|=mysql->options.client_flag; /* Send client information for access check */ client_flag|=CLIENT_CAPABILITIES; @@ -1426,8 +1456,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if (db) client_flag|=CLIENT_CONNECT_WITH_DB; #ifdef HAVE_COMPRESS - if (mysql->server_capabilities & CLIENT_COMPRESS && - (mysql->options.compress || client_flag & CLIENT_COMPRESS)) + if ((mysql->server_capabilities & CLIENT_COMPRESS) && + (mysql->options.compress || (client_flag & CLIENT_COMPRESS))) client_flag|=CLIENT_COMPRESS; /* We will use compression */ else #endif @@ -1470,9 +1500,13 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, } #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); + strmake(buff+5,user,32); /* Max user name */ else read_user_name((char*) buff+5); #ifdef _CUSTOMCONFIG_ @@ -1483,7 +1517,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, (my_bool) (mysql->protocol_version == 9)); if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB)) { - end=strmov(end+1,db); + end=strmake(end+1,db,NAME_LEN); mysql->db=my_strdup(db,MYF(MY_WME)); db=0; } @@ -1662,6 +1696,71 @@ mysql_query(MYSQL *mysql, const char *query) return mysql_real_query(mysql,query, (uint) strlen(query)); } +int STDCALL +mysql_send_query(MYSQL* mysql, const char* query) +{ + return mysql_real_send_query(mysql, query, strlen(query)); +} + +/* send the query and return so we can do something else */ +/* needs to be followed by mysql_reap_query() when we want to + finish processing it +*/ +int STDCALL +mysql_real_send_query(MYSQL* mysql, const char* query, uint len) +{ + return simple_command(mysql, COM_QUERY, query, len, 1); +} + +int STDCALL +mysql_reap_query(MYSQL* mysql) +{ + uchar *pos; + ulong field_count; + MYSQL_DATA *fields; + uint len; + DBUG_ENTER("mysql_reap_query"); + DBUG_PRINT("enter",("handle: %lx",mysql)); + if((len = 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+len && 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 ((len=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) |