174
static void read_user_name(char *name)
177
strcpy(name,"root"); /* allow use of surun */
183
if ((str=getlogin()) == NULL)
185
if ((skr=getpwuid(geteuid())) != NULL)
187
else if (!(str=getenv("USER")) && !(str=getenv("LOGNAME")) &&
188
!(str=getenv("LOGIN")))
191
strncpy(name,str,USERNAME_LENGTH);
193
(void) cuserid(name);
195
strcpy(name,"UNKNOWN_USER");
202
drizzle_connect(DRIZZLE *drizzle,const char *host, const char *user,
203
const char *passwd, const char *db,
205
const char * unix_port __attribute__((__unused__)),
206
uint32_t client_flag)
208
char buff[NAME_LEN+USERNAME_LENGTH+100];
209
char *end,*host_info=NULL;
211
NET *net= &drizzle->net;
213
drizzle->methods= &client_methods;
214
net->vio = 0; /* If something goes wrong */
215
drizzle->client_flag=0; /* For handshake */
217
/* Some empty-string-tests are done because of ODBC */
218
if (!host || !host[0])
219
host=drizzle->options.host;
220
if (!user || !user[0])
222
user=drizzle->options.user;
228
passwd=drizzle->options.password;
233
db=drizzle->options.db;
235
port=drizzle->options.port;
237
drizzle->server_status=SERVER_STATUS_AUTOCOMMIT;
240
Part 0: Grab a socket and connect it to the server
244
struct addrinfo *res_lst, hints, *t_res;
246
char port_buf[NI_MAXSERV];
254
snprintf(host_info=buff, sizeof(buff)-1, ER(CR_TCP_CONNECTION), host);
256
memset(&hints, 0, sizeof(hints));
257
hints.ai_socktype= SOCK_STREAM;
259
snprintf(port_buf, NI_MAXSERV, "%d", port);
260
gai_errno= getaddrinfo(host, port_buf, &hints, &res_lst);
264
drizzle_set_extended_error(drizzle, CR_UNKNOWN_HOST, sqlstate_get_unknown(),
265
ER(CR_UNKNOWN_HOST), host, errno);
270
for (t_res= res_lst; t_res != NULL; t_res= t_res->ai_next)
272
int sock= socket(t_res->ai_family, t_res->ai_socktype,
277
net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ);
284
if (connect_with_timeout(sock, t_res->ai_addr, t_res->ai_addrlen, drizzle->options.connect_timeout))
286
vio_delete(net->vio);
293
freeaddrinfo(res_lst);
298
drizzle_set_extended_error(drizzle, CR_CONN_HOST_ERROR, sqlstate_get_unknown(),
299
ER(CR_CONN_HOST_ERROR), host, errno);
303
if (my_net_init(net, net->vio))
305
vio_delete(net->vio);
307
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
310
vio_keepalive(net->vio,true);
312
/* If user set read_timeout, let it override the default */
313
if (drizzle->options.read_timeout)
314
my_net_set_read_timeout(net, drizzle->options.read_timeout);
316
/* If user set write_timeout, let it override the default */
317
if (drizzle->options.write_timeout)
318
my_net_set_write_timeout(net, drizzle->options.write_timeout);
320
if (drizzle->options.max_allowed_packet)
321
net->max_packet_size= drizzle->options.max_allowed_packet;
323
/* Get version info */
324
drizzle->protocol_version= PROTOCOL_VERSION; /* Assume this */
325
if (drizzle->options.connect_timeout &&
326
vio_poll_read(net->vio, drizzle->options.connect_timeout))
328
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
329
ER(CR_SERVER_LOST_INITIAL_COMM_WAIT),
335
Part 1: Connection established, read and parse first packet
338
if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
340
if (drizzle->net.last_errno == CR_SERVER_LOST)
341
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
342
ER(CR_SERVER_LOST_INITIAL_COMM_READ),
346
/* Check if version of protocol matches current one */
348
drizzle->protocol_version= net->read_pos[0];
349
if (drizzle->protocol_version != PROTOCOL_VERSION)
351
drizzle_set_extended_error(drizzle, CR_VERSION_ERROR, sqlstate_get_unknown(),
352
ER(CR_VERSION_ERROR), drizzle->protocol_version,
356
end= strchr((char*) net->read_pos+1, '\0');
357
drizzle->thread_id=uint4korr(end+1);
360
Scramble is split into two parts because old clients does not understand
361
long scrambles; here goes the first part.
363
strncpy(drizzle->scramble, end, SCRAMBLE_LENGTH_323);
364
end+= SCRAMBLE_LENGTH_323+1;
366
if (pkt_length >= (uint) (end+1 - (char*) net->read_pos))
367
drizzle->server_capabilities=uint2korr(end);
368
if (pkt_length >= (uint) (end+18 - (char*) net->read_pos))
370
/* New protocol with 16 bytes to describe server characteristics */
371
drizzle->server_language=end[2];
372
drizzle->server_status=uint2korr(end+3);
375
if (pkt_length >= (uint) (end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1 -
376
(char *) net->read_pos))
377
strncpy(drizzle->scramble+SCRAMBLE_LENGTH_323, end,
378
SCRAMBLE_LENGTH-SCRAMBLE_LENGTH_323);
380
drizzle->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
382
if (drizzle->options.secure_auth && passwd[0] &&
383
!(drizzle->server_capabilities & CLIENT_SECURE_CONNECTION))
385
drizzle_set_error(drizzle, CR_SECURE_AUTH, sqlstate_get_unknown());
389
/* Save connection information */
390
if (!(drizzle->host_info= (char *)malloc(strlen(host_info)+1+strlen(host)+1
391
+(end - (char*) net->read_pos))) ||
392
!(drizzle->user=strdup(user)) ||
393
!(drizzle->passwd=strdup(passwd)))
395
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
398
drizzle->host= drizzle->host_info+strlen(host_info)+1;
399
drizzle->server_version= drizzle->host+strlen(host)+1;
400
strcpy(drizzle->host_info,host_info);
401
strcpy(drizzle->host,host);
402
strcpy(drizzle->server_version,(char*) net->read_pos+1);
406
Part 2: format and send client info to the server for access check
409
client_flag|=drizzle->options.client_flag;
410
client_flag|=CLIENT_CAPABILITIES;
411
if (client_flag & CLIENT_MULTI_STATEMENTS)
412
client_flag|= CLIENT_MULTI_RESULTS;
415
client_flag|=CLIENT_CONNECT_WITH_DB;
417
/* Remove options that server doesn't support */
418
client_flag= ((client_flag &
419
~(CLIENT_COMPRESS | CLIENT_SSL)) |
420
(client_flag & drizzle->server_capabilities));
421
client_flag&= ~CLIENT_COMPRESS;
423
int4store(buff, client_flag);
424
int4store(buff+4, net->max_packet_size);
425
buff[8]= (char) 45; // utf8 charset number
426
memset(buff+9, 0, 32-9);
429
drizzle->client_flag=client_flag;
431
/* This needs to be changed as it's not useful with big packets */
433
strncpy(end,user,USERNAME_LENGTH); /* Max user name */
435
read_user_name((char*) end);
437
/* We have to handle different version of handshake here */
438
end= strchr(end, '\0') + 1;
442
*end++= SCRAMBLE_LENGTH;
443
memset(end, 0, SCRAMBLE_LENGTH-1);
444
memcpy(end, passwd, strlen(passwd));
445
end+= SCRAMBLE_LENGTH;
449
*end++= '\0'; /* empty password */
451
/* Add database if needed */
452
if (db && (drizzle->server_capabilities & CLIENT_CONNECT_WITH_DB))
454
end= strncpy(end, db, NAME_LEN) + NAME_LEN + 1;
455
drizzle->db= strdup(db);
458
/* Write authentication package */
459
if (my_net_write(net, (unsigned char*) buff, (size_t) (end-buff)) || net_flush(net))
461
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
462
ER(CR_SERVER_LOST_SEND_AUTH),
468
Part 3: Authorization data's been sent. Now server can reply with
469
OK-packet, or re-request scrambled password.
472
if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
474
if (drizzle->net.last_errno == CR_SERVER_LOST)
475
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
476
ER(CR_SERVER_LOST_READ_AUTH),
481
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
485
if (db && drizzle_select_db(drizzle, db))
487
if (drizzle->net.last_errno == CR_SERVER_LOST)
488
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
489
ER(CR_SERVER_LOST_SETTING_DB),
499
/* Free alloced memory */
500
drizzle_disconnect(drizzle);
501
drizzle_close_free(drizzle);
502
if (!(((uint32_t) client_flag) & CLIENT_REMEMBER_OPTIONS))
503
drizzle_close_free_options(drizzle);
511
/**************************************************************************
513
**************************************************************************/
516
drizzle_select_db(DRIZZLE *drizzle, const char *db)
520
if ((error=simple_command(drizzle,COM_INIT_DB, (const unsigned char*) db,
521
(uint32_t) strlen(db),0)))
523
if (drizzle->db != NULL)
525
drizzle->db=strdup(db);
529
bool drizzle_reconnect(DRIZZLE *drizzle)
534
if (!drizzle->reconnect ||
535
(drizzle->server_status & SERVER_STATUS_IN_TRANS) || !drizzle->host_info)
537
/* Allow reconnect next time */
538
drizzle->server_status&= ~SERVER_STATUS_IN_TRANS;
539
drizzle_set_error(drizzle, CR_SERVER_GONE_ERROR, sqlstate_get_unknown());
542
drizzle_create(&tmp_drizzle);
543
tmp_drizzle.options= drizzle->options;
544
tmp_drizzle.options.my_cnf_file= tmp_drizzle.options.my_cnf_group= 0;
546
if (!drizzle_connect(&tmp_drizzle,drizzle->host,drizzle->user,drizzle->passwd,
547
drizzle->db, drizzle->port, 0,
548
drizzle->client_flag | CLIENT_REMEMBER_OPTIONS))
550
drizzle->net.last_errno= tmp_drizzle.net.last_errno;
551
strcpy(drizzle->net.last_error, tmp_drizzle.net.last_error);
552
strcpy(drizzle->net.sqlstate, tmp_drizzle.net.sqlstate);
556
tmp_drizzle.reconnect= 1;
557
tmp_drizzle.free_me= drizzle->free_me;
559
/* Don't free options as these are now used in tmp_drizzle */
560
memset(&drizzle->options, 0, sizeof(drizzle->options));
562
drizzle_close(drizzle);
563
*drizzle=tmp_drizzle;
564
net_clear(&drizzle->net, 1);
565
drizzle->affected_rows= ~(uint64_t) 0;
144
569
/**************************************************************************
145
570
Shut down connection
146
571
**************************************************************************/
587
/*************************************************************************
588
Send a QUIT to the server and close the connection
589
If handle is alloced by DRIZZLE connect free it.
590
*************************************************************************/
592
void drizzle_close_free_options(DRIZZLE *drizzle)
594
if (drizzle->options.user != NULL)
595
free(drizzle->options.user);
596
if (drizzle->options.host != NULL)
597
free(drizzle->options.host);
598
if (drizzle->options.password != NULL)
599
free(drizzle->options.password);
600
if (drizzle->options.db != NULL)
601
free(drizzle->options.db);
602
if (drizzle->options.my_cnf_file != NULL)
603
free(drizzle->options.my_cnf_file);
604
if (drizzle->options.my_cnf_group != NULL)
605
free(drizzle->options.my_cnf_group);
606
if (drizzle->options.client_ip != NULL)
607
free(drizzle->options.client_ip);
608
memset(&drizzle->options, 0, sizeof(drizzle->options));
613
void drizzle_close_free(DRIZZLE *drizzle)
615
if (drizzle->host_info != NULL)
616
free((unsigned char*) drizzle->host_info);
617
if (drizzle->user != NULL)
619
if (drizzle->passwd != NULL)
620
free(drizzle->passwd);
621
if (drizzle->db != NULL)
623
if (drizzle->info_buffer != NULL)
624
free(drizzle->info_buffer);
625
drizzle->info_buffer= 0;
627
/* Clear pointers for better safety */
628
drizzle->host_info= drizzle->user= drizzle->passwd= drizzle->db= 0;
632
void drizzle_close(DRIZZLE *drizzle)
634
if (drizzle) /* Some simple safety */
636
/* If connection is still up, send a QUIT message */
637
if (drizzle->net.vio != 0)
639
free_old_query(drizzle);
640
drizzle->status=DRIZZLE_STATUS_READY; /* Force command */
641
drizzle->reconnect=0;
642
simple_command(drizzle,COM_QUIT,(unsigned char*) 0,0,1);
643
drizzle_disconnect(drizzle); /* Sets drizzle->net.vio= 0 */
645
drizzle_close_free_options(drizzle);
646
drizzle_close_free(drizzle);
647
if (drizzle->free_me)
648
free((unsigned char*) drizzle);
654
bool cli_read_query_result(DRIZZLE *drizzle)
657
uint32_t field_count;
658
DRIZZLE_DATA *fields;
661
if ((length = cli_safe_read(drizzle)) == packet_error)
663
free_old_query(drizzle); /* Free old result */
665
pos=(unsigned char*) drizzle->net.read_pos;
666
if ((field_count= net_field_length(&pos)) == 0)
668
drizzle->affected_rows= net_field_length_ll(&pos);
669
drizzle->insert_id= net_field_length_ll(&pos);
671
drizzle->server_status= uint2korr(pos); pos+=2;
672
drizzle->warning_count= uint2korr(pos); pos+=2;
674
if (pos < drizzle->net.read_pos+length && net_field_length(&pos))
675
drizzle->info=(char*) pos;
678
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
682
if (!(drizzle->options.client_flag & CLIENT_LOCAL_FILES))
684
drizzle_set_error(drizzle, CR_MALFORMED_PACKET, sqlstate_get_unknown());
688
error= handle_local_infile(drizzle,(char*) pos);
689
if ((length= cli_safe_read(drizzle)) == packet_error || error)
691
goto get_info; /* Get info packet */
693
if (!(drizzle->server_status & SERVER_STATUS_AUTOCOMMIT))
694
drizzle->server_status|= SERVER_STATUS_IN_TRANS;
696
if (!(fields=cli_read_rows(drizzle,(DRIZZLE_FIELD*)0, 7)))
698
if (!(drizzle->fields= unpack_fields(fields, (uint) field_count, 0)))
700
drizzle->status= DRIZZLE_STATUS_GET_RESULT;
701
drizzle->field_count= (uint) field_count;
707
Send the query and return so we can do something else.
708
Needs to be followed by drizzle_read_query_result() when we want to
709
finish processing it.
713
drizzle_send_query(DRIZZLE *drizzle, const char* query, uint32_t length)
715
return(simple_command(drizzle, COM_QUERY, (unsigned char*) query, length, 1));
720
drizzle_real_query(DRIZZLE *drizzle, const char *query, uint32_t length)
722
if (drizzle_send_query(drizzle,query,length))
724
return((int) (*drizzle->methods->read_query_result)(drizzle));
728
/**************************************************************************
729
Alloc result struct for buffered results. All rows are read to buffer.
730
drizzle_data_seek may be used.
731
**************************************************************************/
733
DRIZZLE_RES * drizzle_store_result(DRIZZLE *drizzle)
737
if (!drizzle->fields)
739
if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
741
drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, sqlstate_get_unknown());
744
drizzle->status=DRIZZLE_STATUS_READY; /* server is ready */
745
if (!(result=(DRIZZLE_RES*) malloc((uint) (sizeof(DRIZZLE_RES)+
747
drizzle->field_count))))
749
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
752
memset(result, 0,(sizeof(DRIZZLE_RES)+ sizeof(uint32_t) *
753
drizzle->field_count));
754
result->methods= drizzle->methods;
755
result->eof= 1; /* Marker for buffered */
756
result->lengths= (uint32_t*) (result+1);
758
(*drizzle->methods->read_rows)(drizzle,drizzle->fields,drizzle->field_count)))
760
free((unsigned char*) result);
763
drizzle->affected_rows= result->row_count= result->data->rows;
764
result->data_cursor= result->data->data;
765
result->fields= drizzle->fields;
766
result->field_count= drizzle->field_count;
767
/* The rest of result members is zeroed in malloc */
768
drizzle->fields=0; /* fields is now in result */
769
/* just in case this was mistakenly called after drizzle_stmt_execute() */
770
drizzle->unbuffered_fetch_owner= 0;
771
return(result); /* Data fetched */
775
/**************************************************************************
776
Alloc struct for use with unbuffered reads. Data is fetched by domand
777
when calling to drizzle_fetch_row.
778
DRIZZLE_DATA_seek is a noop.
780
No other queries may be specified with the same DRIZZLE handle.
781
There shouldn't be much processing per row because DRIZZLE server shouldn't
782
have to wait for the client (and will not wait more than 30 sec/packet).
783
**************************************************************************/
785
DRIZZLE_RES * cli_use_result(DRIZZLE *drizzle)
789
if (!drizzle->fields)
791
if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
793
drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, sqlstate_get_unknown());
796
if (!(result=(DRIZZLE_RES*) malloc(sizeof(*result)+
797
sizeof(uint32_t)*drizzle->field_count)))
799
memset(result, 0, sizeof(*result)+ sizeof(uint32_t)*drizzle->field_count);
800
result->lengths=(uint32_t*) (result+1);
801
result->methods= drizzle->methods;
802
if (!(result->row=(DRIZZLE_ROW)
803
malloc(sizeof(result->row[0])*(drizzle->field_count+1))))
804
{ /* Ptrs: to one row */
805
free((unsigned char*) result);
808
result->fields= drizzle->fields;
809
result->field_count= drizzle->field_count;
810
result->current_field=0;
811
result->handle= drizzle;
812
result->current_row= 0;
813
drizzle->fields=0; /* fields is now in result */
814
drizzle->status=DRIZZLE_STATUS_USE_RESULT;
815
drizzle->unbuffered_fetch_owner= &result->unbuffered_fetch_cancelled;
816
return(result); /* Data is read to be fetched */
163
822
Set the internal error message to DRIZZLE handler