1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems, Inc.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1
/* Copyright (C) 2000-2004 DRIZZLE AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation.
7
There are special exceptions to the terms and conditions of the GPL as it
8
is applied to this software. View the full text of the exception in file
9
EXCEPTIONS-CLIENT in the directory of this software distribution.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
20
20
#include <drizzled/global.h>
21
#include "libdrizzle_priv.h"
23
#include <libdrizzle/libdrizzle.h>
24
#include <libdrizzle/pack.h>
25
#include <libdrizzle/errmsg.h>
21
#include <mysys/my_sys.h>
23
#include <mysys/mysys_err.h>
24
#include <mystrings/m_string.h>
25
#include <mystrings/m_ctype.h>
28
#include <vio/violite.h>
26
29
#include <sys/stat.h>
27
30
#include <signal.h>
47
50
#ifdef HAVE_SYS_UN_H
48
51
#include <sys/un.h>
53
#include <mysys/my_pthread.h> /* because of signal() */
50
54
#ifndef INADDR_NONE
51
55
#define INADDR_NONE -1
57
/* Borrowed from libicu header */
59
#define U8_IS_SINGLE(c) (((c)&0x80)==0)
60
#define U8_LENGTH(c) \
61
((uint32_t)(c)<=0x7f ? 1 : \
62
((uint32_t)(c)<=0x7ff ? 2 : \
63
((uint32_t)(c)<=0xd7ff ? 3 : \
64
((uint32_t)(c)<=0xdfff || (uint32_t)(c)>0x10ffff ? 0 : \
65
((uint32_t)(c)<=0xffff ? 3 : 4)\
58
#include <sql_common.h>
59
#include "client_settings.h"
72
61
#undef net_buffer_length
73
62
#undef max_allowed_packet
75
64
uint32_t net_buffer_length= 8192;
76
65
uint32_t max_allowed_packet= 1024L*1024L*1024L;
78
unsigned int drizzle_port=0;
68
#define SOCKET_ERROR -1
71
If allowed through some configuration, then this needs to
74
#define MAX_LONG_DATA_LENGTH 8192
75
#define unsigned_field(A) ((A)->flags & UNSIGNED_FLAG)
77
static void append_wild(char *to,char *end,const char *wild);
83
80
static DRIZZLE_PARAMETERS drizzle_internal_parameters=
84
81
{&max_allowed_packet, &net_buffer_length, 0};
86
const DRIZZLE_PARAMETERS * drizzle_get_parameters(void)
83
const DRIZZLE_PARAMETERS *STDCALL drizzle_get_parameters(void)
88
85
return &drizzle_internal_parameters;
91
unsigned int drizzle_get_default_port(void)
96
void drizzle_set_default_port(unsigned int port)
88
bool STDCALL drizzle_thread_init()
90
return my_thread_init();
93
void STDCALL drizzle_thread_end()
102
100
Expand wildcard to a sql string
127
123
/**************************************************************************
124
Ignore SIGPIPE handler
126
**************************************************************************/
129
my_pipe_sig_handler(int sig __attribute__((unused)))
131
#ifdef DONT_REMEMBER_SIGNAL
132
(void) signal(SIGPIPE, my_pipe_sig_handler);
137
/**************************************************************************
128
138
Change user and database
129
139
**************************************************************************/
131
141
int cli_read_change_user_result(DRIZZLE *drizzle)
135
145
pkt_length= cli_safe_read(drizzle);
137
147
if (pkt_length == packet_error)
143
bool drizzle_change_user(DRIZZLE *drizzle, const char *user,
144
const char *passwd, const char *db)
153
bool STDCALL drizzle_change_user(DRIZZLE *drizzle, const char *user,
154
const char *passwd, const char *db)
146
156
char buff[USERNAME_LENGTH+SCRAMBLED_PASSWORD_CHAR_LENGTH+NAME_LEN+2];
159
const CHARSET_INFO *saved_cs= drizzle->charset;
161
/* Get the connection-default character set. */
163
if (drizzle_init_character_set(drizzle))
165
drizzle->charset= saved_cs;
150
169
/* Use an empty string instead of NULL. */
157
176
/* Store user into the buffer */
158
end= strncpy(end, user, USERNAME_LENGTH) + USERNAME_LENGTH + 1;
177
end= strmake(end, user, USERNAME_LENGTH) + 1;
160
179
/* write scrambled password according to server capabilities */
164
183
*end++= SCRAMBLE_LENGTH;
184
scramble(end, drizzle->scramble, passwd);
165
185
end+= SCRAMBLE_LENGTH;
169
189
*end++= '\0'; /* empty password */
170
190
/* Add database if needed */
171
end= strncpy(end, db ? db : "", NAME_LEN) + NAME_LEN + 1;
191
end= strmake(end, db ? db : "", NAME_LEN) + 1;
173
193
/* Add character set number. */
174
195
if (drizzle->server_capabilities & CLIENT_SECURE_CONNECTION)
176
int2store(end, (uint16_t) 45); // utf8mb4 number from mystrings/ctype-utf8.c
197
int2store(end, (ushort) drizzle->charset->number);
180
201
/* Write authentication package */
181
(void)simple_command(drizzle,COM_CHANGE_USER, (unsigned char*) buff, (uint32_t) (end-buff), 1);
202
(void)simple_command(drizzle,COM_CHANGE_USER, (uchar*) buff, (ulong) (end-buff), 1);
183
204
rc= (*drizzle->methods->read_change_user_result)(drizzle);
193
214
free(drizzle->db);
195
216
/* alloc new connect information */
196
drizzle->user= strdup(user);
197
drizzle->passwd= strdup(passwd);
198
drizzle->db= db ? strdup(db) : 0;
217
drizzle->user= my_strdup(user,MYF(MY_WME));
218
drizzle->passwd=my_strdup(passwd,MYF(MY_WME));
219
drizzle->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
223
drizzle->charset= saved_cs;
204
#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL)
205
struct passwd *getpwuid(uid_t);
206
char* getlogin(void);
209
230
/**************************************************************************
210
231
Do a query. If query returned rows, free old rows.
211
232
Read data by drizzle_store_result or by repeat call of drizzle_fetch_row
212
233
**************************************************************************/
215
236
drizzle_query(DRIZZLE *drizzle, const char *query)
217
return drizzle_real_query(drizzle,query, (uint32_t) strlen(query));
238
return drizzle_real_query(drizzle,query, (uint) strlen(query));
274
295
/*****************************************************************************
297
*****************************************************************************/
299
DRIZZLE_RES * STDCALL
300
drizzle_list_dbs(DRIZZLE *drizzle, const char *wild)
304
append_wild(strmov(buff,"show databases"),buff+sizeof(buff),wild);
305
if (drizzle_query(drizzle,buff))
307
return (drizzle_store_result(drizzle));
311
/*****************************************************************************
275
312
List all tables in a database
276
313
If wild is given then only the tables matching wild is returned
277
314
*****************************************************************************/
316
DRIZZLE_RES * STDCALL
280
317
drizzle_list_tables(DRIZZLE *drizzle, const char *wild)
283
char *ptr= strcpy(buff, "show tables");
284
ptr+= 11; /* strlen("show tables"); */
286
append_wild(ptr,buff+sizeof(buff),wild);
321
append_wild(strmov(buff,"show tables"),buff+sizeof(buff),wild);
287
322
if (drizzle_query(drizzle,buff))
289
324
return (drizzle_store_result(drizzle));
293
328
DRIZZLE_FIELD *cli_list_fields(DRIZZLE *drizzle)
295
330
DRIZZLE_DATA *query;
296
if (!(query= cli_read_rows(drizzle,(DRIZZLE_FIELD*) 0, 8)))
331
if (!(query= cli_read_rows(drizzle,(DRIZZLE_FIELD*) 0,
332
protocol_41(drizzle) ? 8 : 6)))
299
drizzle->field_count= (uint32_t) query->rows;
300
return unpack_fields(query, drizzle->field_count, 1);
335
drizzle->field_count= (uint) query->rows;
336
return unpack_fields(query,&drizzle->field_alloc,
337
drizzle->field_count, 1, drizzle->server_capabilities);
308
345
show fields in 'table' like "wild"
309
346
**************************************************************************/
348
DRIZZLE_RES * STDCALL
312
349
drizzle_list_fields(DRIZZLE *drizzle, const char *table, const char *wild)
314
351
DRIZZLE_RES *result;
315
352
DRIZZLE_FIELD *fields;
316
char buff[257], *end;
318
end= strncpy(buff, table, 128) + 128;
319
end= strncpy(end+1, wild ? wild : "", 128) + 128;
355
end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128);
321
356
free_old_query(drizzle);
322
if (simple_command(drizzle, COM_FIELD_LIST, (unsigned char*) buff,
323
(uint32_t) (end-buff), 1) ||
357
if (simple_command(drizzle, COM_FIELD_LIST, (uchar*) buff,
358
(ulong) (end-buff), 1) ||
324
359
!(fields= (*drizzle->methods->list_fields)(drizzle)))
327
362
if (!(result = (DRIZZLE_RES *) malloc(sizeof(DRIZZLE_RES))))
330
memset(result, 0, sizeof(DRIZZLE_RES));
332
365
result->methods= drizzle->methods;
366
result->field_alloc=drizzle->field_alloc;
333
367
drizzle->fields=0;
334
368
result->field_count = drizzle->field_count;
335
369
result->fields= fields;
340
374
/* List all running processes (threads) in server */
376
DRIZZLE_RES * STDCALL
343
377
drizzle_list_processes(DRIZZLE *drizzle)
345
379
DRIZZLE_DATA *fields;
346
uint32_t field_count;
349
383
if (simple_command(drizzle,COM_PROCESS_INFO,0,0,0))
351
385
free_old_query(drizzle);
352
pos=(unsigned char*) drizzle->net.read_pos;
353
field_count=(uint32_t) net_field_length(&pos);
354
if (!(fields = (*drizzle->methods->read_rows)(drizzle,(DRIZZLE_FIELD*) 0, 7)))
386
pos=(uchar*) drizzle->net.read_pos;
387
field_count=(uint) net_field_length(&pos);
388
if (!(fields = (*drizzle->methods->read_rows)(drizzle,(DRIZZLE_FIELD*) 0,
389
protocol_41(drizzle) ? 7 : 5)))
356
if (!(drizzle->fields=unpack_fields(fields, field_count, 0)))
391
if (!(drizzle->fields=unpack_fields(fields,&drizzle->field_alloc,field_count,0,
392
drizzle->server_capabilities)))
358
394
drizzle->status=DRIZZLE_STATUS_GET_RESULT;
359
395
drizzle->field_count=field_count;
365
drizzle_shutdown(DRIZZLE *drizzle)
401
drizzle_shutdown(DRIZZLE *drizzle, enum drizzle_enum_shutdown_level shutdown_level)
367
return(simple_command(drizzle, COM_SHUTDOWN, 0, 0, 0));
404
level[0]= (uchar) shutdown_level;
405
return(simple_command(drizzle, COM_SHUTDOWN, level, 1, 0));
372
drizzle_refresh(DRIZZLE *drizzle, uint32_t options)
410
drizzle_refresh(DRIZZLE *drizzle,uint options)
374
unsigned char bits[1];
375
bits[0]= (unsigned char) options;
413
bits[0]= (uchar) options;
376
414
return(simple_command(drizzle, COM_REFRESH, bits, 1, 0));
381
419
drizzle_kill(DRIZZLE *drizzle, uint32_t pid)
383
unsigned char buff[4];
384
422
int4store(buff,pid);
385
423
return(simple_command(drizzle,COM_PROCESS_KILL,buff,sizeof(buff),0));
390
428
drizzle_set_server_option(DRIZZLE *drizzle, enum enum_drizzle_set_option option)
392
unsigned char buff[2];
393
int2store(buff, (uint32_t) option);
431
int2store(buff, (uint) option);
394
432
return(simple_command(drizzle, COM_SET_OPTION, buff, sizeof(buff), 0));
400
438
drizzle->net.read_pos[drizzle->packet_length]=0; /* End of stat string */
401
439
if (!drizzle->net.read_pos[0])
403
drizzle_set_error(drizzle, CR_WRONG_HOST_INFO, sqlstate_get_unknown());
441
set_drizzle_error(drizzle, CR_WRONG_HOST_INFO, unknown_sqlstate);
404
442
return drizzle->net.last_error;
406
444
return (char*) drizzle->net.read_pos;
449
drizzle_stat(DRIZZLE *drizzle)
451
if (simple_command(drizzle,COM_STATISTICS,0,0,0))
452
return(drizzle->net.last_error);
453
return((*drizzle->methods->read_statistics)(drizzle));
411
458
drizzle_ping(DRIZZLE *drizzle)
422
469
drizzle_get_server_info(const DRIZZLE *drizzle)
424
471
return((char*) drizzle->server_version);
429
476
drizzle_get_host_info(const DRIZZLE *drizzle)
431
478
return(drizzle->host_info);
436
483
drizzle_get_proto_info(const DRIZZLE *drizzle)
438
485
return (drizzle->protocol_version);
442
489
drizzle_get_client_info(void)
444
return (char*) VERSION;
491
return (char*) MYSQL_SERVER_VERSION;
447
uint32_t drizzle_get_client_version(void)
494
uint32_t STDCALL drizzle_get_client_version(void)
449
return DRIZZLE_VERSION_ID;
496
return MYSQL_VERSION_ID;
452
bool drizzle_eof(const DRIZZLE_RES *res)
499
bool STDCALL drizzle_eof(const DRIZZLE_RES *res)
457
const DRIZZLE_FIELD * drizzle_fetch_field_direct(const DRIZZLE_RES *res, unsigned int fieldnr)
504
const DRIZZLE_FIELD * STDCALL drizzle_fetch_field_direct(const DRIZZLE_RES *res, unsigned int fieldnr)
459
506
return &(res)->fields[fieldnr];
462
const DRIZZLE_FIELD * drizzle_fetch_fields(const DRIZZLE_RES *res)
509
const DRIZZLE_FIELD * STDCALL drizzle_fetch_fields(const DRIZZLE_RES *res)
464
511
return res->fields;
467
DRIZZLE_ROW_OFFSET drizzle_row_tell(const DRIZZLE_RES *res)
514
DRIZZLE_ROW_OFFSET STDCALL drizzle_row_tell(const DRIZZLE_RES *res)
469
516
return res->data_cursor;
472
DRIZZLE_FIELD_OFFSET drizzle_field_tell(const DRIZZLE_RES *res)
519
DRIZZLE_FIELD_OFFSET STDCALL drizzle_field_tell(const DRIZZLE_RES *res)
474
521
return res->current_field;
479
unsigned int drizzle_field_count(const DRIZZLE *drizzle)
526
unsigned int STDCALL drizzle_field_count(const DRIZZLE *drizzle)
481
528
return drizzle->field_count;
484
uint64_t drizzle_affected_rows(const DRIZZLE *drizzle)
531
uint64_t STDCALL drizzle_affected_rows(const DRIZZLE *drizzle)
486
533
return drizzle->affected_rows;
489
uint64_t drizzle_insert_id(const DRIZZLE *drizzle)
536
uint64_t STDCALL drizzle_insert_id(const DRIZZLE *drizzle)
491
538
return drizzle->insert_id;
494
const char * drizzle_sqlstate(const DRIZZLE *drizzle)
541
const char *STDCALL drizzle_sqlstate(const DRIZZLE *drizzle)
496
return drizzle ? drizzle->net.sqlstate : sqlstate_get_cant_connect();
543
return drizzle ? drizzle->net.sqlstate : cant_connect_sqlstate;
499
uint32_t drizzle_warning_count(const DRIZZLE *drizzle)
546
uint32_t STDCALL drizzle_warning_count(const DRIZZLE *drizzle)
501
548
return drizzle->warning_count;
504
const char * drizzle_info(const DRIZZLE *drizzle)
551
const char *STDCALL drizzle_info(const DRIZZLE *drizzle)
506
553
return drizzle->info;
509
uint32_t drizzle_thread_id(const DRIZZLE *drizzle)
556
uint32_t STDCALL drizzle_thread_id(const DRIZZLE *drizzle)
511
558
return drizzle->thread_id;
561
const char * STDCALL drizzle_character_set_name(const DRIZZLE *drizzle)
563
return drizzle->charset->csname;
566
void STDCALL drizzle_get_character_set_info(const DRIZZLE *drizzle, MY_CHARSET_INFO *csinfo)
568
csinfo->number = drizzle->charset->number;
569
csinfo->state = drizzle->charset->state;
570
csinfo->csname = drizzle->charset->csname;
571
csinfo->name = drizzle->charset->name;
572
csinfo->comment = drizzle->charset->comment;
573
csinfo->mbminlen = drizzle->charset->mbminlen;
574
csinfo->mbmaxlen = drizzle->charset->mbmaxlen;
576
if (drizzle->options.charset_dir)
577
csinfo->dir = drizzle->options.charset_dir;
579
csinfo->dir = charsets_dir;
582
uint STDCALL drizzle_thread_safe(void)
588
bool STDCALL drizzle_embedded(void)
590
#ifdef EMBEDDED_LIBRARY
514
597
/****************************************************************************
515
598
Some support functions
516
599
****************************************************************************/
522
605
void my_net_local_init(NET *net)
524
net->max_packet= (uint32_t) net_buffer_length;
607
net->max_packet= (uint) net_buffer_length;
525
608
my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
526
609
my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
527
610
net->retry_count= 1;
528
net->max_packet_size= (net_buffer_length > max_allowed_packet) ?
529
net_buffer_length : max_allowed_packet;
611
net->max_packet_size= max(net_buffer_length, max_allowed_packet);
615
This function is used to create HEX string that you
616
can use in a SQL statement in of the either ways:
617
INSERT INTO blob_column VALUES (0xAABBCC); (any DRIZZLE version)
618
INSERT INTO blob_column VALUES (X'AABBCC'); (4.1 and higher)
620
The string in "from" is encoded to a HEX string.
621
The result is placed in "to" and a terminating null byte is appended.
623
The string pointed to by "from" must be "length" bytes long.
624
You must allocate the "to" buffer to be at least length*2+1 bytes long.
625
Each character needs two bytes, and you need room for the terminating
626
null byte. When drizzle_hex_string() returns, the contents of "to" will
627
be a null-terminated string. The return value is the length of the
628
encoded string, not including the terminating null character.
630
The return value does not contain any leading 0x or a leading X' and
631
trailing '. The caller must supply whichever of those is desired.
635
drizzle_hex_string(char *to, const char *from, uint32_t length)
640
for (end= from + length; from < end; from++)
642
*to++= _dig_vec_upper[((unsigned char) *from) >> 4];
643
*to++= _dig_vec_upper[((unsigned char) *from) & 0x0F];
646
return (uint32_t) (to-to0);
535
652
Returns the length of the to string
539
656
drizzle_escape_string(char *to,const char *from, uint32_t length)
541
const char *to_start= to;
542
const char *end, *to_end=to_start + 2*length;
543
bool overflow= false;
544
for (end= from + length; from < end; from++)
658
return escape_string_for_drizzle(default_charset_info, to, 0, from, length);
662
drizzle_real_escape_string(DRIZZLE *drizzle, char *to,const char *from,
665
if (drizzle->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
666
return escape_quotes_for_drizzle(drizzle->charset, to, 0, from, length);
667
return escape_string_for_drizzle(drizzle->charset, to, 0, from, length);
671
myodbc_remove_escape(const DRIZZLE *drizzle, char *name)
675
bool use_mb_flag= use_mb(drizzle->charset);
678
for (end=name; *end ; end++) ;
681
for (to=name ; *name ; name++)
548
if (!U8_IS_SINGLE(*from))
685
if (use_mb_flag && (l = my_ismbchar( drizzle->charset, name , end ) ) )
550
tmp_length= U8_LENGTH(*from);
551
if (to + tmp_length > to_end)
562
case 0: /* Must be escaped for 'mysql' */
565
case '\n': /* Must be escaped for logs */
577
case '"': /* Better safe than sorry */
580
case '\032': /* This gives problems on Win32 */
693
if (*name == '\\' && name[1])
605
return overflow ? (size_t) -1 : (size_t) (to - to_start);
608
700
int cli_unbuffered_fetch(DRIZZLE *drizzle, char **row)