00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00044 #include <libdrizzle/common.h>
00045
00059 static drizzle_return_t _con_setsockopt(drizzle_con_st *con);
00060
00063
00064
00065
00066
00067 int drizzle_con_fd(const drizzle_con_st *con)
00068 {
00069 if (con == NULL)
00070 {
00071 return -1;
00072 }
00073
00074 return con->fd;
00075 }
00076
00077 drizzle_return_t drizzle_con_set_fd(drizzle_con_st *con, int fd)
00078 {
00079 drizzle_return_t ret;
00080 if (con == NULL)
00081 {
00082 return DRIZZLE_RETURN_INVALID_ARGUMENT;
00083 }
00084
00085 con->fd= fd;
00086
00087 ret= _con_setsockopt(con);
00088 if (ret != DRIZZLE_RETURN_OK)
00089 {
00090 con->drizzle->last_errno= errno;
00091 }
00092
00093 return ret;
00094 }
00095
00096 void drizzle_con_close(drizzle_con_st *con)
00097 {
00098 if (con == NULL)
00099 {
00100 return;
00101 }
00102
00103 if (con->fd == -1)
00104 {
00105 return;
00106 }
00107
00108 (void)closesocket(con->fd);
00109 con->fd= -1;
00110
00111 con->options&= int(~DRIZZLE_CON_READY);
00112 con->packet_number= 0;
00113 con->buffer_ptr= con->buffer;
00114 con->buffer_size= 0;
00115 con->events= 0;
00116 con->revents= 0;
00117
00118 drizzle_state_reset(con);
00119 }
00120
00121 drizzle_return_t drizzle_con_set_events(drizzle_con_st *con, short events)
00122 {
00123 drizzle_return_t ret;
00124
00125 if ((con->events | events) == con->events)
00126 {
00127 return DRIZZLE_RETURN_OK;
00128 }
00129
00130 con->events|= events;
00131
00132 if (con->drizzle->event_watch_fn != NULL)
00133 {
00134 ret= con->drizzle->event_watch_fn(con, con->events,
00135 con->drizzle->event_watch_context);
00136 if (ret != DRIZZLE_RETURN_OK)
00137 {
00138 drizzle_con_close(con);
00139 return ret;
00140 }
00141 }
00142
00143 return DRIZZLE_RETURN_OK;
00144 }
00145
00146 drizzle_return_t drizzle_con_set_revents(drizzle_con_st *con, short revents)
00147 {
00148 drizzle_return_t ret;
00149 if (con == NULL)
00150 {
00151 return DRIZZLE_RETURN_INVALID_ARGUMENT;
00152 }
00153
00154 if (revents != 0)
00155 con->options|= DRIZZLE_CON_IO_READY;
00156
00157 con->revents= revents;
00158
00159
00160
00161
00162
00163 if (revents & POLLOUT && !(con->events & POLLOUT) &&
00164 con->drizzle->event_watch_fn != NULL)
00165 {
00166 ret= con->drizzle->event_watch_fn(con, con->events,
00167 con->drizzle->event_watch_context);
00168 if (ret != DRIZZLE_RETURN_OK)
00169 {
00170 drizzle_con_close(con);
00171 return ret;
00172 }
00173 }
00174
00175 con->events&= (short)~revents;
00176
00177 return DRIZZLE_RETURN_OK;
00178 }
00179
00180 drizzle_st *drizzle_con_drizzle(const drizzle_con_st *con)
00181 {
00182 if (con == NULL)
00183 {
00184 return NULL;
00185 }
00186 return con->drizzle;
00187 }
00188
00189 const char *drizzle_con_error(const drizzle_con_st *con)
00190 {
00191 if (con == NULL)
00192 {
00193 return NULL;
00194 }
00195
00196 return drizzle_error(con->drizzle);
00197 }
00198
00199 int drizzle_con_errno(const drizzle_con_st *con)
00200 {
00201 if (con == NULL)
00202 {
00203 return 0;
00204 }
00205
00206 return drizzle_errno(con->drizzle);
00207 }
00208
00209 uint16_t drizzle_con_error_code(const drizzle_con_st *con)
00210 {
00211 if (con == NULL)
00212 {
00213 return 0;
00214 }
00215
00216 return drizzle_error_code(con->drizzle);
00217 }
00218
00219 const char *drizzle_con_sqlstate(const drizzle_con_st *con)
00220 {
00221 if (con == NULL)
00222 {
00223 return NULL;
00224 }
00225
00226 return drizzle_sqlstate(con->drizzle);
00227 }
00228
00229 drizzle_con_options_t drizzle_con_options(const drizzle_con_st *con)
00230 {
00231 if (con == NULL)
00232 {
00233 return drizzle_con_options_t();
00234 }
00235
00236 return drizzle_con_options_t(con->options);
00237 }
00238
00239 void drizzle_con_set_options(drizzle_con_st *con,
00240 drizzle_con_options_t options)
00241 {
00242 if (con == NULL)
00243 {
00244 return;
00245 }
00246
00247 con->options= options;
00248 }
00249
00250 void drizzle_con_add_options(drizzle_con_st *con,
00251 drizzle_con_options_t options)
00252 {
00253 if (con == NULL)
00254 {
00255 return;
00256 }
00257
00258 con->options|= options;
00259
00260
00261 if (con->options & DRIZZLE_CON_EXPERIMENTAL)
00262 {
00263 con->options&= int(~DRIZZLE_CON_MYSQL);
00264 }
00265 }
00266
00267 void drizzle_con_remove_options(drizzle_con_st *con,
00268 drizzle_con_options_t options)
00269 {
00270 if (con == NULL)
00271 {
00272 return;
00273 }
00274
00275 con->options&= ~options;
00276 }
00277
00278 const char *drizzle_con_host(const drizzle_con_st *con)
00279 {
00280 if (con == NULL)
00281 {
00282 return NULL;
00283 }
00284
00285 if (con->socket_type == DRIZZLE_CON_SOCKET_TCP)
00286 {
00287 if (con->socket.tcp.host == NULL && !(con->options & DRIZZLE_CON_LISTEN))
00288 return DRIZZLE_DEFAULT_TCP_HOST;
00289
00290 return con->socket.tcp.host;
00291 }
00292
00293 return NULL;
00294 }
00295
00296 in_port_t drizzle_con_port(const drizzle_con_st *con)
00297 {
00298 if (con and con->socket_type == DRIZZLE_CON_SOCKET_TCP)
00299 {
00300 if (con->socket.tcp.port != 0)
00301 {
00302 return con->socket.tcp.port;
00303 }
00304
00305 if (con->options & DRIZZLE_CON_MYSQL)
00306 {
00307 return DRIZZLE_DEFAULT_TCP_PORT_MYSQL;
00308 }
00309
00310 return DRIZZLE_DEFAULT_TCP_PORT;
00311 }
00312
00313 return in_port_t(0);
00314 }
00315
00316 void drizzle_con_set_tcp(drizzle_con_st *con, const char *host, in_port_t port)
00317 {
00318 if (con == NULL)
00319 {
00320 return;
00321 }
00322
00323 drizzle_con_reset_addrinfo(con);
00324
00325 con->socket_type= DRIZZLE_CON_SOCKET_TCP;
00326
00327 if (host == NULL)
00328 {
00329 con->socket.tcp.host= NULL;
00330 }
00331 else
00332 {
00333 con->socket.tcp.host= con->socket.tcp.host_buffer;
00334 strncpy(con->socket.tcp.host, host, NI_MAXHOST);
00335 con->socket.tcp.host[NI_MAXHOST - 1]= 0;
00336 }
00337
00338 con->socket.tcp.port= port;
00339 }
00340
00341 const char *drizzle_con_user(const drizzle_con_st *con)
00342 {
00343 if (con == NULL)
00344 {
00345 return NULL;
00346 }
00347
00348 return con->user;
00349 }
00350
00351 const char *drizzle_con_password(const drizzle_con_st *con)
00352 {
00353 if (con == NULL)
00354 {
00355 return NULL;
00356 }
00357
00358 return con->password;
00359 }
00360
00361 void drizzle_con_set_auth(drizzle_con_st *con, const char *user,
00362 const char *password)
00363 {
00364 if (con == NULL)
00365 {
00366 return;
00367 }
00368
00369 if (user == NULL)
00370 {
00371 con->user[0]= 0;
00372 }
00373 else
00374 {
00375 strncpy(con->user, user, DRIZZLE_MAX_USER_SIZE);
00376 con->user[DRIZZLE_MAX_USER_SIZE - 1]= 0;
00377 }
00378
00379 if (password == NULL)
00380 {
00381 con->password[0]= 0;
00382 }
00383 else
00384 {
00385 strncpy(con->password, password, DRIZZLE_MAX_PASSWORD_SIZE);
00386 con->password[DRIZZLE_MAX_PASSWORD_SIZE - 1]= 0;
00387 }
00388 }
00389
00390 const char *drizzle_con_db(const drizzle_con_st *con)
00391 {
00392 if (con == NULL)
00393 {
00394 return NULL;
00395 }
00396
00397 return con->db;
00398 }
00399
00400 void drizzle_con_set_db(drizzle_con_st *con, const char *db)
00401 {
00402 if (con == NULL)
00403 {
00404 return;
00405 }
00406
00407 if (db == NULL)
00408 {
00409 con->db[0]= 0;
00410 }
00411 else
00412 {
00413 strncpy(con->db, db, DRIZZLE_MAX_DB_SIZE);
00414 con->db[DRIZZLE_MAX_DB_SIZE - 1]= 0;
00415 }
00416 }
00417
00418 void *drizzle_con_context(const drizzle_con_st *con)
00419 {
00420 if (con == NULL)
00421 {
00422 return NULL;
00423 }
00424
00425 return con->context;
00426 }
00427
00428 void drizzle_con_set_context(drizzle_con_st *con, void *context)
00429 {
00430 if (con == NULL)
00431 {
00432 return;
00433 }
00434
00435 con->context= context;
00436 }
00437
00438 void drizzle_con_set_context_free_fn(drizzle_con_st *con,
00439 drizzle_con_context_free_fn *function)
00440 {
00441 if (con == NULL)
00442 {
00443 return;
00444 }
00445
00446 con->context_free_fn= function;
00447 }
00448
00449 uint8_t drizzle_con_protocol_version(const drizzle_con_st *con)
00450 {
00451 if (con == NULL)
00452 {
00453 return 0;
00454 }
00455
00456 return con->protocol_version;
00457 }
00458
00459 const char *drizzle_con_server_version(const drizzle_con_st *con)
00460 {
00461 if (con == NULL)
00462 {
00463 return NULL;
00464 }
00465
00466 return con->server_version;
00467 }
00468
00469 uint32_t drizzle_con_server_version_number(const drizzle_con_st *con)
00470 {
00471 if (con)
00472 {
00473 const char *current= con->server_version;
00474 char *end;
00475
00476 uint32_t major= (uint32_t)strtoul(current, &end, 10);
00477 current= end +1;
00478 uint32_t minor= (uint32_t)strtoul(current, &end, 10);
00479 current= end +1;
00480 uint32_t version= (uint32_t)strtoul(current, &end, 10);
00481
00482 return (major * 10000) +(minor * 100) +version;
00483 }
00484
00485 return 0;
00486 }
00487
00488 uint32_t drizzle_con_thread_id(const drizzle_con_st *con)
00489 {
00490 if (con == NULL)
00491 {
00492 return 0;
00493 }
00494
00495 return con->thread_id;
00496 }
00497
00498 const uint8_t *drizzle_con_scramble(const drizzle_con_st *con)
00499 {
00500 if (con == NULL)
00501 {
00502 return NULL;
00503 }
00504
00505 return con->scramble;
00506 }
00507
00508 drizzle_capabilities_t drizzle_con_capabilities(const drizzle_con_st *con)
00509 {
00510 if (con == NULL)
00511 {
00512 return drizzle_capabilities_t();
00513 }
00514
00515 return drizzle_capabilities_t(con->capabilities);
00516 }
00517
00518 drizzle_charset_t drizzle_con_charset(const drizzle_con_st *con)
00519 {
00520 if (con == NULL)
00521 {
00522 return drizzle_charset_t();
00523 }
00524
00525 return con->charset;
00526 }
00527
00528 drizzle_con_status_t drizzle_con_status(const drizzle_con_st *con)
00529 {
00530 if (con == NULL)
00531 {
00532 return drizzle_con_status_t();
00533 }
00534
00535 return con->status;
00536 }
00537
00538 uint32_t drizzle_con_max_packet_size(const drizzle_con_st *con)
00539 {
00540 if (con == NULL)
00541 {
00542 return 0;
00543 }
00544
00545 return con->max_packet_size;
00546 }
00547
00548
00549
00550
00551
00552 drizzle_return_t drizzle_con_connect(drizzle_con_st *con)
00553 {
00554 if (con == NULL)
00555 {
00556 return DRIZZLE_RETURN_INVALID_ARGUMENT;
00557 }
00558
00559 if (con->options & DRIZZLE_CON_READY)
00560 {
00561 return DRIZZLE_RETURN_OK;
00562 }
00563
00564 if (drizzle_state_none(con))
00565 {
00566 if (!(con->options & DRIZZLE_CON_RAW_PACKET))
00567 {
00568 drizzle_state_push(con, drizzle_state_handshake_server_read);
00569 drizzle_state_push(con, drizzle_state_packet_read);
00570 }
00571
00572 drizzle_state_push(con, drizzle_state_connect);
00573 drizzle_state_push(con, drizzle_state_addrinfo);
00574 }
00575
00576 return drizzle_state_loop(con);
00577 }
00578
00579 drizzle_result_st *drizzle_con_quit(drizzle_con_st *con,
00580 drizzle_result_st *result,
00581 drizzle_return_t *ret_ptr)
00582 {
00583 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUIT, NULL, 0,
00584 0, ret_ptr);
00585 }
00586
00587 drizzle_result_st *drizzle_quit(drizzle_con_st *con,
00588 drizzle_result_st *result,
00589 drizzle_return_t *ret_ptr)
00590 {
00591 return drizzle_con_quit(con, result, ret_ptr);
00592 }
00593
00594 drizzle_result_st *drizzle_con_select_db(drizzle_con_st *con,
00595 drizzle_result_st *result,
00596 const char *db,
00597 drizzle_return_t *ret_ptr)
00598 {
00599 drizzle_con_set_db(con, db);
00600 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_INIT_DB,
00601 db, strlen(db), strlen(db), ret_ptr);
00602 }
00603
00604 drizzle_result_st *drizzle_select_db(drizzle_con_st *con,
00605 drizzle_result_st *result,
00606 const char *db,
00607 drizzle_return_t *ret_ptr)
00608 {
00609 return drizzle_con_select_db(con, result, db, ret_ptr);
00610 }
00611
00612 drizzle_result_st *drizzle_con_shutdown(drizzle_con_st *con,
00613 drizzle_result_st *result,
00614 drizzle_return_t *ret_ptr)
00615 {
00616 drizzle_return_t unused;
00617 if (ret_ptr == NULL)
00618 {
00619 ret_ptr= &unused;
00620 }
00621
00622 if (con and con->options & DRIZZLE_CON_MYSQL)
00623 {
00624 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_SHUTDOWN,
00625 "0", 1, 1, ret_ptr);
00626 }
00627
00628 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_SHUTDOWN, NULL,
00629 0, 0, ret_ptr);
00630 }
00631
00632 drizzle_result_st *drizzle_shutdown(drizzle_con_st *con,
00633 drizzle_result_st *result, uint32_t,
00634 drizzle_return_t *ret_ptr)
00635 {
00636 return drizzle_con_shutdown(con, result, ret_ptr);
00637 }
00638
00639 drizzle_result_st *drizzle_kill(drizzle_con_st *con,
00640 drizzle_result_st *result,
00641 uint32_t query_id,
00642 drizzle_return_t *ret_ptr)
00643 {
00644 drizzle_return_t unused;
00645 if (ret_ptr == NULL)
00646 {
00647 ret_ptr= &unused;
00648 }
00649
00650 uint32_t sent= htonl(query_id);
00651 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_PROCESS_KILL,
00652 &sent, sizeof(uint32_t), sizeof(uint32_t), ret_ptr);
00653 }
00654
00655 drizzle_result_st *drizzle_con_ping(drizzle_con_st *con,
00656 drizzle_result_st *result,
00657 drizzle_return_t *ret_ptr)
00658 {
00659 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_PING, NULL, 0,
00660 0, ret_ptr);
00661 }
00662
00663 drizzle_result_st *drizzle_ping(drizzle_con_st *con,
00664 drizzle_result_st *result,
00665 drizzle_return_t *ret_ptr)
00666 {
00667 return drizzle_con_ping(con, result, ret_ptr);
00668 }
00669
00670 drizzle_result_st *drizzle_con_command_write(drizzle_con_st *con,
00671 drizzle_result_st *result,
00672 drizzle_command_t command,
00673 const void *data, size_t size,
00674 size_t total,
00675 drizzle_return_t *ret_ptr)
00676 {
00677 drizzle_return_t unused;
00678 if (ret_ptr == NULL)
00679 {
00680 ret_ptr= &unused;
00681 }
00682
00683 if (con == NULL)
00684 {
00685 *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
00686 return NULL;
00687 }
00688
00689 drizzle_result_st *old_result;
00690
00691 if (!(con->options & DRIZZLE_CON_READY))
00692 {
00693 if (con->options & DRIZZLE_CON_RAW_PACKET)
00694 {
00695 drizzle_set_error(con->drizzle, "drizzle_command_write",
00696 "connection not ready");
00697 *ret_ptr= DRIZZLE_RETURN_NOT_READY;
00698 return result;
00699 }
00700
00701 *ret_ptr= drizzle_con_connect(con);
00702 if (*ret_ptr != DRIZZLE_RETURN_OK)
00703 return result;
00704 }
00705
00706 if (drizzle_state_none(con))
00707 {
00708 if (con->options & (DRIZZLE_CON_RAW_PACKET | DRIZZLE_CON_NO_RESULT_READ))
00709 con->result= NULL;
00710 else
00711 {
00712 for (old_result= con->result_list; old_result != NULL; old_result= old_result->next)
00713 {
00714 if (result == old_result)
00715 {
00716 drizzle_set_error(con->drizzle, "drizzle_command_write", "result struct already in use");
00717 *ret_ptr= DRIZZLE_RETURN_INTERNAL_ERROR;
00718 return result;
00719 }
00720 }
00721
00722 con->result= drizzle_result_create(con, result);
00723 if (con->result == NULL)
00724 {
00725 *ret_ptr= DRIZZLE_RETURN_MEMORY;
00726 return NULL;
00727 }
00728 }
00729
00730 con->command= command;
00731 con->command_data= (uint8_t *)data;
00732 con->command_size= size;
00733 con->command_offset= 0;
00734 con->command_total= total;
00735
00736 drizzle_state_push(con, drizzle_state_command_write);
00737 }
00738 else if (con->command_data == NULL)
00739 {
00740 con->command_data= (uint8_t *)data;
00741 con->command_size= size;
00742 }
00743
00744 *ret_ptr= drizzle_state_loop(con);
00745 if (*ret_ptr == DRIZZLE_RETURN_PAUSE)
00746 *ret_ptr= DRIZZLE_RETURN_OK;
00747 else if (*ret_ptr != DRIZZLE_RETURN_OK &&
00748 *ret_ptr != DRIZZLE_RETURN_IO_WAIT &&
00749 *ret_ptr != DRIZZLE_RETURN_ERROR_CODE)
00750 {
00751 drizzle_result_free(con->result);
00752 con->result= result;
00753 }
00754
00755 return con->result;
00756 }
00757
00758
00759
00760
00761
00762 drizzle_return_t drizzle_con_listen(drizzle_con_st *con)
00763 {
00764 if (con == NULL)
00765 {
00766 return DRIZZLE_RETURN_INVALID_ARGUMENT;
00767 }
00768
00769 if (con->options & DRIZZLE_CON_READY)
00770 {
00771 return DRIZZLE_RETURN_OK;
00772 }
00773
00774 if (drizzle_state_none(con))
00775 {
00776 drizzle_state_push(con, drizzle_state_listen);
00777 drizzle_state_push(con, drizzle_state_addrinfo);
00778 }
00779
00780 return drizzle_state_loop(con);
00781 }
00782
00783 int drizzle_con_backlog(const drizzle_con_st *con)
00784 {
00785 if (con == NULL)
00786 {
00787 return 0;
00788 }
00789
00790 return con->backlog;
00791 }
00792
00793 void drizzle_con_set_backlog(drizzle_con_st *con, int backlog)
00794 {
00795 if (con == NULL)
00796 {
00797 return;
00798 }
00799
00800 con->backlog= backlog;
00801 }
00802
00803 void drizzle_con_set_protocol_version(drizzle_con_st *con,
00804 uint8_t protocol_version)
00805 {
00806 if (con == NULL)
00807 {
00808 return;
00809 }
00810
00811 con->protocol_version= protocol_version;
00812 }
00813
00814 void drizzle_con_set_server_version(drizzle_con_st *con,
00815 const char *server_version)
00816 {
00817 if (con == NULL)
00818 {
00819 return;
00820 }
00821
00822 if (server_version == NULL)
00823 {
00824 con->server_version[0]= 0;
00825 }
00826 else
00827 {
00828 strncpy(con->server_version, server_version,
00829 DRIZZLE_MAX_SERVER_VERSION_SIZE);
00830 con->server_version[DRIZZLE_MAX_SERVER_VERSION_SIZE - 1]= 0;
00831 }
00832 }
00833
00834 void drizzle_con_set_thread_id(drizzle_con_st *con, uint32_t thread_id)
00835 {
00836 if (con == NULL)
00837 {
00838 return;
00839 }
00840
00841 con->thread_id= thread_id;
00842 }
00843
00844 void drizzle_con_set_scramble(drizzle_con_st *con, const uint8_t *scramble)
00845 {
00846 if (con == NULL)
00847 {
00848 return;
00849 }
00850
00851 if (scramble == NULL)
00852 {
00853 con->scramble= NULL;
00854 }
00855 else
00856 {
00857 con->scramble= con->scramble_buffer;
00858 memcpy(con->scramble, scramble, DRIZZLE_MAX_SCRAMBLE_SIZE);
00859 }
00860 }
00861
00862 void drizzle_con_set_capabilities(drizzle_con_st *con,
00863 drizzle_capabilities_t capabilities)
00864 {
00865 if (con == NULL)
00866 {
00867 return;
00868 }
00869
00870 con->capabilities= capabilities;
00871 }
00872
00873 void drizzle_con_set_charset(drizzle_con_st *con, drizzle_charset_t charset)
00874 {
00875 if (con == NULL)
00876 {
00877 return;
00878 }
00879
00880 con->charset= charset;
00881 }
00882
00883 void drizzle_con_set_status(drizzle_con_st *con, drizzle_con_status_t status)
00884 {
00885 if (con == NULL)
00886 {
00887 return;
00888 }
00889
00890 con->status= status;
00891 }
00892
00893 void drizzle_con_set_max_packet_size(drizzle_con_st *con,
00894 uint32_t max_packet_size)
00895 {
00896 if (con == NULL)
00897 {
00898 return;
00899 }
00900
00901 con->max_packet_size= max_packet_size;
00902 }
00903
00904 void drizzle_con_copy_handshake(drizzle_con_st *con, drizzle_con_st *from)
00905 {
00906 drizzle_con_set_auth(con, from->user, NULL);
00907 drizzle_con_set_scramble(con, from->scramble);
00908 drizzle_con_set_db(con, from->db);
00909 drizzle_con_set_protocol_version(con, from->protocol_version);
00910 drizzle_con_set_server_version(con, from->server_version);
00911 drizzle_con_set_thread_id(con, from->thread_id);
00912 drizzle_con_set_scramble(con, from->scramble);
00913 drizzle_con_set_capabilities(con, drizzle_capabilities_t(from->capabilities));
00914 drizzle_con_set_charset(con, from->charset);
00915 drizzle_con_set_status(con, from->status);
00916 drizzle_con_set_max_packet_size(con, from->max_packet_size);
00917 }
00918
00919 void *drizzle_con_command_read(drizzle_con_st *con,
00920 drizzle_command_t *command, size_t *offset,
00921 size_t *size, size_t *total,
00922 drizzle_return_t *ret_ptr)
00923 {
00924 drizzle_return_t unused_ret;
00925 if (ret_ptr == NULL)
00926 {
00927 ret_ptr= &unused_ret;
00928 }
00929
00930 if (con == NULL)
00931 {
00932 *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
00933 return NULL;
00934 }
00935
00936 if (drizzle_state_none(con))
00937 {
00938 con->packet_number= 0;
00939 con->command_offset= 0;
00940 con->command_total= 0;
00941
00942 drizzle_state_push(con, drizzle_state_command_read);
00943 drizzle_state_push(con, drizzle_state_packet_read);
00944 }
00945
00946 if (offset)
00947 {
00948 *offset= con->command_offset;
00949 }
00950
00951 *ret_ptr= drizzle_state_loop(con);
00952 if (*ret_ptr == DRIZZLE_RETURN_PAUSE)
00953 {
00954 *ret_ptr= DRIZZLE_RETURN_OK;
00955 }
00956
00957 if (command)
00958 {
00959 *command= con->command;
00960 }
00961
00962 if (size)
00963 {
00964 *size= con->command_size;
00965 }
00966
00967 if (total)
00968 {
00969 *total= con->command_total;
00970 }
00971
00972 return con->command_data;
00973 }
00974
00975 void *drizzle_con_command_buffer(drizzle_con_st *con,
00976 drizzle_command_t *command, size_t *total,
00977 drizzle_return_t *ret_ptr)
00978 {
00979 size_t offset= 0;
00980 size_t size= 0;
00981
00982 drizzle_return_t unused_ret;
00983 if (ret_ptr == NULL)
00984 {
00985 ret_ptr= &unused_ret;
00986 }
00987
00988 size_t unused_total;
00989 if (total == NULL)
00990 {
00991 total= &unused_total;
00992 }
00993
00994 if (con == NULL)
00995 {
00996 *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
00997 return NULL;
00998 }
00999
01000 char *command_data= (char *)drizzle_con_command_read(con, command, &offset, &size, total, ret_ptr);
01001 if (*ret_ptr != DRIZZLE_RETURN_OK)
01002 {
01003 return NULL;
01004 }
01005
01006 if (command_data == NULL)
01007 {
01008 *total= 0;
01009 return NULL;
01010 }
01011
01012 if (con->command_buffer == NULL)
01013 {
01014 con->command_buffer= (uint8_t*)realloc(NULL, (*total) +1);
01015 if (con->command_buffer == NULL)
01016 {
01017 drizzle_set_error(con->drizzle, __func__, "Failed to allocate.");
01018 *ret_ptr= DRIZZLE_RETURN_MEMORY;
01019 return NULL;
01020 }
01021 }
01022
01023 memcpy(con->command_buffer + offset, command_data, size);
01024
01025 while ((offset + size) != (*total))
01026 {
01027 command_data= (char *)drizzle_con_command_read(con, command, &offset, &size, total, ret_ptr);
01028 if (*ret_ptr != DRIZZLE_RETURN_OK)
01029 {
01030 return NULL;
01031 }
01032
01033 memcpy(con->command_buffer + offset, command_data, size);
01034 }
01035
01036 command_data= (char *)con->command_buffer;
01037 con->command_buffer= NULL;
01038 command_data[*total]= 0;
01039
01040 return command_data;
01041 }
01042
01043
01044
01045
01046
01047 void drizzle_con_reset_addrinfo(drizzle_con_st *con)
01048 {
01049 if (con == NULL)
01050 {
01051 return;
01052 }
01053
01054 switch (con->socket_type)
01055 {
01056 case DRIZZLE_CON_SOCKET_TCP:
01057 if (con->socket.tcp.addrinfo != NULL)
01058 {
01059 freeaddrinfo(con->socket.tcp.addrinfo);
01060 con->socket.tcp.addrinfo= NULL;
01061 }
01062 break;
01063
01064 case DRIZZLE_CON_SOCKET_UDS:
01065 con->socket.uds.addrinfo.ai_addr= NULL;
01066 break;
01067
01068 default:
01069 break;
01070 }
01071
01072 con->addrinfo_next= NULL;
01073 }
01074
01075
01076
01077
01078
01079 drizzle_return_t drizzle_state_addrinfo(drizzle_con_st *con)
01080 {
01081 drizzle_con_tcp_st *tcp;
01082 const char *host;
01083 char port[NI_MAXSERV];
01084 struct addrinfo ai;
01085 int ret;
01086
01087 if (con == NULL)
01088 {
01089 return DRIZZLE_RETURN_INVALID_ARGUMENT;
01090 }
01091
01092 drizzle_log_debug(con->drizzle, __func__);
01093
01094 switch (con->socket_type)
01095 {
01096 case DRIZZLE_CON_SOCKET_TCP:
01097 tcp= &(con->socket.tcp);
01098
01099 if (tcp->addrinfo != NULL)
01100 {
01101 freeaddrinfo(tcp->addrinfo);
01102 tcp->addrinfo= NULL;
01103 }
01104
01105 if (tcp->port != 0)
01106 {
01107 snprintf(port, NI_MAXSERV, "%u", tcp->port);
01108 }
01109 else if (con->options & DRIZZLE_CON_MYSQL)
01110 {
01111 snprintf(port, NI_MAXSERV, "%u", DRIZZLE_DEFAULT_TCP_PORT_MYSQL);
01112 }
01113 else
01114 {
01115 snprintf(port, NI_MAXSERV, "%u", DRIZZLE_DEFAULT_TCP_PORT);
01116 }
01117 port[NI_MAXSERV-1]= 0;
01118
01119 memset(&ai, 0, sizeof(struct addrinfo));
01120 ai.ai_socktype= SOCK_STREAM;
01121 ai.ai_protocol= IPPROTO_TCP;
01122 ai.ai_flags = AI_PASSIVE;
01123 ai.ai_family = AF_UNSPEC;
01124
01125 if (con->options & DRIZZLE_CON_LISTEN)
01126 {
01127 host= tcp->host;
01128 }
01129 else
01130 {
01131 if (tcp->host == NULL)
01132 {
01133 host= DRIZZLE_DEFAULT_TCP_HOST;
01134 }
01135 else
01136 {
01137 host= tcp->host;
01138 }
01139 }
01140
01141 ret= getaddrinfo(host, port, &ai, &(tcp->addrinfo));
01142 if (ret != 0)
01143 {
01144 drizzle_set_error(con->drizzle, "drizzle_state_addrinfo", "getaddrinfo:%s", gai_strerror(ret));
01145 return DRIZZLE_RETURN_GETADDRINFO;
01146 }
01147
01148 con->addrinfo_next= tcp->addrinfo;
01149
01150 break;
01151
01152 case DRIZZLE_CON_SOCKET_UDS:
01153 con->addrinfo_next= &(con->socket.uds.addrinfo);
01154 break;
01155
01156 default:
01157 break;
01158 }
01159
01160 drizzle_state_pop(con);
01161 return DRIZZLE_RETURN_OK;
01162 }
01163
01164 drizzle_return_t drizzle_state_connect(drizzle_con_st *con)
01165 {
01166 int ret;
01167 drizzle_return_t dret;
01168
01169 if (con == NULL)
01170 {
01171 return DRIZZLE_RETURN_INVALID_ARGUMENT;
01172 }
01173
01174 drizzle_log_debug(con->drizzle, "drizzle_state_connect");
01175
01176 if (con->fd != -1)
01177 {
01178 (void)closesocket(con->fd);
01179 con->fd= -1;
01180 }
01181
01182 if (con->addrinfo_next == NULL)
01183 {
01184 drizzle_set_error(con->drizzle, __func__, "could not connect");
01185 drizzle_state_reset(con);
01186 return DRIZZLE_RETURN_COULD_NOT_CONNECT;
01187 }
01188
01189 con->fd= socket(con->addrinfo_next->ai_family,
01190 con->addrinfo_next->ai_socktype,
01191 con->addrinfo_next->ai_protocol);
01192 if (con->fd == -1)
01193 {
01194 drizzle_set_error(con->drizzle, __func__, "socket:%s", strerror(errno));
01195 con->drizzle->last_errno= errno;
01196 return DRIZZLE_RETURN_COULD_NOT_CONNECT;
01197 }
01198
01199 dret= _con_setsockopt(con);
01200 if (dret != DRIZZLE_RETURN_OK)
01201 {
01202 con->drizzle->last_errno= errno;
01203 return DRIZZLE_RETURN_COULD_NOT_CONNECT;
01204 }
01205
01206 while (1)
01207 {
01208 ret= connect(con->fd, con->addrinfo_next->ai_addr,
01209 con->addrinfo_next->ai_addrlen);
01210
01211 #ifdef _WIN32
01212 errno = WSAGetLastError();
01213 switch(errno) {
01214 case WSAEINVAL:
01215 case WSAEALREADY:
01216 case WSAEWOULDBLOCK:
01217 errno= EINPROGRESS;
01218 break;
01219 case WSAECONNREFUSED:
01220 errno= ECONNREFUSED;
01221 break;
01222 case WSAENETUNREACH:
01223 errno= ENETUNREACH;
01224 break;
01225 case WSAETIMEDOUT:
01226 errno= ETIMEDOUT;
01227 break;
01228 case WSAECONNRESET:
01229 errno= ECONNRESET;
01230 break;
01231 case WSAEADDRINUSE:
01232 errno= EADDRINUSE;
01233 break;
01234 case WSAEOPNOTSUPP:
01235 errno= EOPNOTSUPP;
01236 break;
01237 case WSAENOPROTOOPT:
01238 errno= ENOPROTOOPT;
01239 break;
01240 default:
01241 break;
01242 }
01243 #endif
01244
01245 drizzle_log_crazy(con->drizzle, "connect return=%d errno=%s", ret, strerror(errno));
01246
01247 if (ret == 0)
01248 {
01249 con->addrinfo_next= NULL;
01250 break;
01251 }
01252
01253 if (errno == EAGAIN || errno == EINTR)
01254 {
01255 continue;
01256 }
01257
01258 if (errno == EINPROGRESS)
01259 {
01260 drizzle_state_pop(con);
01261 drizzle_state_push(con, drizzle_state_connecting);
01262 return DRIZZLE_RETURN_OK;
01263 }
01264
01265 if (errno == ECONNREFUSED || errno == ENETUNREACH || errno == ETIMEDOUT)
01266 {
01267 con->addrinfo_next= con->addrinfo_next->ai_next;
01268 return DRIZZLE_RETURN_OK;
01269 }
01270
01271 drizzle_set_error(con->drizzle, __func__, "connect:%s", strerror(errno));
01272 con->drizzle->last_errno= errno;
01273 return DRIZZLE_RETURN_COULD_NOT_CONNECT;
01274 }
01275
01276 drizzle_state_pop(con);
01277
01278 return DRIZZLE_RETURN_OK;
01279 }
01280
01281 drizzle_return_t drizzle_state_connecting(drizzle_con_st *con)
01282 {
01283 drizzle_return_t ret;
01284
01285 if (con == NULL)
01286 {
01287 return DRIZZLE_RETURN_INVALID_ARGUMENT;
01288 }
01289
01290 drizzle_log_debug(con->drizzle, "drizzle_state_connecting");
01291
01292 while (1)
01293 {
01294 int error;
01295 if (con->revents & POLLOUT)
01296 {
01297 drizzle_state_pop(con);
01298 return DRIZZLE_RETURN_OK;
01299 socklen_t error_length= sizeof(error);
01300 int getsockopt_error;
01301 if ((getsockopt_error= getsockopt(con->fd, SOL_SOCKET, SO_ERROR, (void*)&error, &error_length)) < 1)
01302 {
01303 drizzle_set_error(con->drizzle, __func__, strerror(getsockopt_error));
01304 return DRIZZLE_RETURN_COULD_NOT_CONNECT;
01305 }
01306
01307 if (error == 0)
01308 {
01309 drizzle_state_pop(con);
01310 return DRIZZLE_RETURN_OK;
01311 }
01312 }
01313 else if (con->revents & (POLLERR | POLLHUP | POLLNVAL))
01314 {
01315 error= 1;
01316 }
01317
01318 if (error)
01319 {
01320 con->revents= 0;
01321 drizzle_state_pop(con);
01322 drizzle_state_push(con, drizzle_state_connect);
01323 con->addrinfo_next= con->addrinfo_next->ai_next;
01324 return DRIZZLE_RETURN_OK;
01325 }
01326
01327 ret= drizzle_con_set_events(con, POLLOUT);
01328 if (ret != DRIZZLE_RETURN_OK)
01329 {
01330 return ret;
01331 }
01332
01333 if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
01334 {
01335 return DRIZZLE_RETURN_IO_WAIT;
01336 }
01337
01338 ret= drizzle_con_wait(con->drizzle);
01339 if (ret != DRIZZLE_RETURN_OK)
01340 {
01341 return ret;
01342 }
01343 }
01344 }
01345
01346 drizzle_return_t drizzle_state_read(drizzle_con_st *con)
01347 {
01348 drizzle_return_t ret;
01349 ssize_t read_size;
01350
01351 if (con == NULL)
01352 {
01353 return DRIZZLE_RETURN_INVALID_ARGUMENT;
01354 }
01355
01356 drizzle_log_debug(con->drizzle, "drizzle_state_read");
01357
01358 if (con->buffer_size == 0)
01359 con->buffer_ptr= con->buffer;
01360 else if ((con->buffer_ptr - con->buffer) > (DRIZZLE_MAX_BUFFER_SIZE / 2))
01361 {
01362 memmove(con->buffer, con->buffer_ptr, con->buffer_size);
01363 con->buffer_ptr= con->buffer;
01364 }
01365
01366 if ((con->revents & POLLIN) == 0 &&
01367 (con->drizzle->options & DRIZZLE_NON_BLOCKING))
01368 {
01369
01370
01371
01372 ret= drizzle_con_set_events(con, POLLIN);
01373 if (ret != DRIZZLE_RETURN_OK)
01374 return ret;
01375 return DRIZZLE_RETURN_IO_WAIT;
01376 }
01377
01378 while (1)
01379 {
01380 size_t available_buffer= (size_t)DRIZZLE_MAX_BUFFER_SIZE -
01381 ((size_t)(con->buffer_ptr - con->buffer) + con->buffer_size);
01382 read_size = recv(con->fd, (char *)con->buffer_ptr + con->buffer_size,
01383 available_buffer, 0);
01384 #ifdef _WIN32
01385 errno = WSAGetLastError();
01386 switch(errno) {
01387 case WSAENOTCONN:
01388 case WSAEWOULDBLOCK:
01389 errno= EAGAIN;
01390 break;
01391 case WSAEINVAL:
01392 case WSAEALREADY:
01393 errno= EINPROGRESS;
01394 break;
01395 case WSAECONNREFUSED:
01396 errno= ECONNREFUSED;
01397 break;
01398 case WSAENETUNREACH:
01399 errno= ENETUNREACH;
01400 break;
01401 case WSAETIMEDOUT:
01402 errno= ETIMEDOUT;
01403 break;
01404 case WSAECONNRESET:
01405 errno= ECONNRESET;
01406 break;
01407 case WSAEADDRINUSE:
01408 errno= EADDRINUSE;
01409 break;
01410 case WSAEOPNOTSUPP:
01411 errno= EOPNOTSUPP;
01412 break;
01413 case WSAENOPROTOOPT:
01414 errno= ENOPROTOOPT;
01415 break;
01416 default:
01417 break;
01418 }
01419 #endif
01420 drizzle_log_crazy(con->drizzle, "read fd=%d return=%zd errno=%s", con->fd,
01421 read_size, strerror(errno));
01422
01423 if (read_size == 0)
01424 {
01425 drizzle_set_error(con->drizzle, "drizzle_state_read",
01426 "lost connection to server (EOF)");
01427 return DRIZZLE_RETURN_LOST_CONNECTION;
01428 }
01429 else if (read_size == -1)
01430 {
01431 if (errno == EAGAIN)
01432 {
01433
01434 con->revents&= ~POLLIN;
01435 ret= drizzle_con_set_events(con, POLLIN);
01436 if (ret != DRIZZLE_RETURN_OK)
01437 return ret;
01438
01439 if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
01440 return DRIZZLE_RETURN_IO_WAIT;
01441
01442 ret= drizzle_con_wait(con->drizzle);
01443 if (ret != DRIZZLE_RETURN_OK)
01444 return ret;
01445
01446 continue;
01447 }
01448 else if (errno == ECONNREFUSED)
01449 {
01450 con->revents= 0;
01451 drizzle_state_pop(con);
01452 drizzle_state_push(con, drizzle_state_connect);
01453 con->addrinfo_next= con->addrinfo_next->ai_next;
01454 return DRIZZLE_RETURN_OK;
01455 }
01456 else if (errno == EINTR)
01457 {
01458 continue;
01459 }
01460 else if (errno == EPIPE || errno == ECONNRESET)
01461 {
01462 drizzle_set_error(con->drizzle, __func__,
01463 "lost connection to server (%s)", strerror(errno));
01464 return DRIZZLE_RETURN_LOST_CONNECTION;
01465 }
01466
01467 drizzle_set_error(con->drizzle, __func__, "read:%s", strerror(errno));
01468 con->drizzle->last_errno= errno;
01469 return DRIZZLE_RETURN_ERRNO;
01470 }
01471
01472
01473 if ((size_t) read_size < available_buffer)
01474 {
01475 con->revents&= ~POLLIN;
01476 }
01477 con->buffer_size+= (size_t)read_size;
01478 break;
01479 }
01480
01481 drizzle_state_pop(con);
01482
01483 return DRIZZLE_RETURN_OK;
01484 }
01485
01486 drizzle_return_t drizzle_state_write(drizzle_con_st *con)
01487 {
01488 drizzle_return_t ret;
01489 ssize_t write_size;
01490
01491 if (con == NULL)
01492 {
01493 return DRIZZLE_RETURN_INVALID_ARGUMENT;
01494 }
01495
01496 drizzle_log_debug(con->drizzle, "drizzle_state_write");
01497
01498 while (con->buffer_size != 0)
01499 {
01500
01501 write_size = send(con->fd,(char *) con->buffer_ptr, con->buffer_size, 0);
01502
01503 #ifdef _WIN32
01504 errno = WSAGetLastError();
01505 switch(errno) {
01506 case WSAENOTCONN:
01507 case WSAEWOULDBLOCK:
01508 errno= EAGAIN;
01509 break;
01510 case WSAEINVAL:
01511 case WSAEALREADY:
01512 errno= EINPROGRESS;
01513 break;
01514 case WSAECONNREFUSED:
01515 errno= ECONNREFUSED;
01516 break;
01517 case WSAENETUNREACH:
01518 errno= ENETUNREACH;
01519 break;
01520 case WSAETIMEDOUT:
01521 errno= ETIMEDOUT;
01522 break;
01523 case WSAECONNRESET:
01524 errno= ECONNRESET;
01525 break;
01526 case WSAEADDRINUSE:
01527 errno= EADDRINUSE;
01528 break;
01529 case WSAEOPNOTSUPP:
01530 errno= EOPNOTSUPP;
01531 break;
01532 case WSAENOPROTOOPT:
01533 errno= ENOPROTOOPT;
01534 break;
01535 default:
01536 break;
01537 }
01538 #endif
01539
01540 drizzle_log_crazy(con->drizzle, "write fd=%d return=%zd errno=%s", con->fd,
01541 write_size, strerror(errno));
01542
01543 if (write_size == 0)
01544 {
01545 drizzle_set_error(con->drizzle, __func__, "lost connection to server (EOF)");
01546 return DRIZZLE_RETURN_LOST_CONNECTION;
01547 }
01548 else if (write_size == -1)
01549 {
01550 if (errno == EAGAIN)
01551 {
01552 ret= drizzle_con_set_events(con, POLLOUT);
01553 if (ret != DRIZZLE_RETURN_OK)
01554 return ret;
01555
01556 if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
01557 return DRIZZLE_RETURN_IO_WAIT;
01558
01559 ret= drizzle_con_wait(con->drizzle);
01560 if (ret != DRIZZLE_RETURN_OK)
01561 return ret;
01562
01563 continue;
01564 }
01565 else if (errno == EINTR)
01566 {
01567 continue;
01568 }
01569 else if (errno == EPIPE || errno == ECONNRESET)
01570 {
01571 drizzle_set_error(con->drizzle, __func__, "lost connection to server (%s)", strerror(errno));
01572 return DRIZZLE_RETURN_LOST_CONNECTION;
01573 }
01574
01575 drizzle_set_error(con->drizzle, "drizzle_state_write", "write:%s", strerror(errno));
01576 con->drizzle->last_errno= errno;
01577 return DRIZZLE_RETURN_ERRNO;
01578 }
01579
01580 con->buffer_ptr+= write_size;
01581 con->buffer_size-= (size_t)write_size;
01582 if (con->buffer_size == 0)
01583 break;
01584 }
01585
01586 con->buffer_ptr= con->buffer;
01587
01588 drizzle_state_pop(con);
01589
01590 return DRIZZLE_RETURN_OK;
01591 }
01592
01593 drizzle_return_t drizzle_state_listen(drizzle_con_st *con)
01594 {
01595 char host[NI_MAXHOST];
01596 char port[NI_MAXSERV];
01597 int fd;
01598 int opt;
01599 drizzle_con_st *new_con;
01600
01601 if (con == NULL)
01602 {
01603 return DRIZZLE_RETURN_INVALID_ARGUMENT;
01604 }
01605
01606 for (; con->addrinfo_next != NULL;
01607 con->addrinfo_next= con->addrinfo_next->ai_next)
01608 {
01609 int ret= getnameinfo(con->addrinfo_next->ai_addr,
01610 con->addrinfo_next->ai_addrlen, host, NI_MAXHOST, port,
01611 NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV);
01612 if (ret != 0)
01613 {
01614 drizzle_set_error(con->drizzle, __func__, "getnameinfo:%s", gai_strerror(ret));
01615 return DRIZZLE_RETURN_GETADDRINFO;
01616 }
01617
01618
01619 fd= socket(con->addrinfo_next->ai_family, con->addrinfo_next->ai_socktype,
01620 con->addrinfo_next->ai_protocol);
01621 if (fd == -1)
01622 {
01623 drizzle_log_info(con->drizzle, "could not listen on %s:%s", host, port);
01624 drizzle_set_error(con->drizzle, __func__, "socket:%s", strerror(errno));
01625 continue;
01626 }
01627
01628 opt= 1;
01629 #ifdef _WIN32
01630 ret= setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,(const char*) &opt, sizeof(opt));
01631 #else
01632 ret= setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
01633 #endif
01634 if (ret == -1)
01635 {
01636 closesocket(fd);
01637 drizzle_set_error(con->drizzle, __func__, "setsockopt:%s", strerror(errno));
01638 return DRIZZLE_RETURN_COULD_NOT_CONNECT;
01639 }
01640
01641 ret= bind(fd, con->addrinfo_next->ai_addr, con->addrinfo_next->ai_addrlen);
01642 if (ret == -1)
01643 {
01644 closesocket(fd);
01645 drizzle_set_error(con->drizzle, __func__, "bind:%s", strerror(errno));
01646 if (errno == EADDRINUSE)
01647 {
01648 if (con->fd == -1)
01649 {
01650 drizzle_log_info(con->drizzle, "could not listen on %s:%s", host,
01651 port);
01652 }
01653
01654 continue;
01655 }
01656
01657 return DRIZZLE_RETURN_ERRNO;
01658 }
01659
01660 if (listen(fd, con->backlog) == -1)
01661 {
01662 closesocket(fd);
01663 drizzle_set_error(con->drizzle, __func__, "listen:%s", strerror(errno));
01664 return DRIZZLE_RETURN_COULD_NOT_CONNECT;
01665 }
01666
01667 if (con->fd == -1)
01668 {
01669 con->fd= fd;
01670 new_con= con;
01671 }
01672 else
01673 {
01674 new_con= drizzle_con_clone(con->drizzle, NULL, con);
01675 if (new_con == NULL)
01676 {
01677 closesocket(fd);
01678 return DRIZZLE_RETURN_MEMORY;
01679 }
01680
01681 new_con->fd= fd;
01682 }
01683
01684
01685 drizzle_return_t local_ret= drizzle_con_set_events(new_con, POLLIN);
01686 if (local_ret != DRIZZLE_RETURN_OK)
01687 {
01688 drizzle_con_free(new_con);
01689 return local_ret;
01690 }
01691
01692 drizzle_log_info(con->drizzle, "listening on %s:%s", host, port);
01693 }
01694
01695
01696 if (con->fd == -1)
01697 {
01698 return DRIZZLE_RETURN_COULD_NOT_CONNECT;
01699 }
01700
01701 drizzle_state_pop(con);
01702
01703 return DRIZZLE_RETURN_OK;
01704 }
01705
01706
01707
01708
01709
01710 static drizzle_return_t _con_setsockopt(drizzle_con_st *con)
01711 {
01712 struct linger linger;
01713 struct timeval waittime;
01714
01715 assert(con);
01716
01717 int ret= 1;
01718
01719 #ifdef _WIN32
01720 ret= setsockopt(con->fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&ret, (socklen_t)sizeof(int));
01721 #else
01722 ret= setsockopt(con->fd, IPPROTO_TCP, TCP_NODELAY, &ret, (socklen_t)sizeof(int));
01723 #endif
01724
01725 if (ret == -1 && errno != EOPNOTSUPP)
01726 {
01727 drizzle_set_error(con->drizzle, __func__, "setsockopt:TCP_NODELAY:%s", strerror(errno));
01728 return DRIZZLE_RETURN_ERRNO;
01729 }
01730
01731 linger.l_onoff= 1;
01732 linger.l_linger= DRIZZLE_DEFAULT_SOCKET_TIMEOUT;
01733
01734 #ifdef _WIN32
01735 ret= setsockopt(con->fd, SOL_SOCKET, SO_LINGER, (const char*)&linger,
01736 (socklen_t)sizeof(struct linger));
01737 #else
01738 ret= setsockopt(con->fd, SOL_SOCKET, SO_LINGER, &linger,
01739 (socklen_t)sizeof(struct linger));
01740 #endif
01741
01742 if (ret == -1)
01743 {
01744 drizzle_set_error(con->drizzle, __func__, "setsockopt:SO_LINGER:%s", strerror(errno));
01745 return DRIZZLE_RETURN_ERRNO;
01746 }
01747
01748 waittime.tv_sec= DRIZZLE_DEFAULT_SOCKET_TIMEOUT;
01749 waittime.tv_usec= 0;
01750
01751 #ifdef _WIN32
01752 ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&waittime,
01753 (socklen_t)sizeof(struct timeval));
01754 #else
01755 ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDTIMEO, &waittime,
01756 (socklen_t)sizeof(struct timeval));
01757 #endif
01758
01759 if (ret == -1 && errno != ENOPROTOOPT)
01760 {
01761 drizzle_set_error(con->drizzle, __func__, "setsockopt:SO_SNDTIMEO:%s", strerror(errno));
01762 return DRIZZLE_RETURN_ERRNO;
01763 }
01764
01765 #ifdef _WIN32
01766 ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&waittime,
01767 (socklen_t)sizeof(struct timeval));
01768 #else
01769 ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVTIMEO, &waittime,
01770 (socklen_t)sizeof(struct timeval));
01771 #endif
01772
01773 if (ret == -1 && errno != ENOPROTOOPT)
01774 {
01775 drizzle_set_error(con->drizzle, __func__,
01776 "setsockopt:SO_RCVTIMEO:%s", strerror(errno));
01777 return DRIZZLE_RETURN_ERRNO;
01778 }
01779
01780 ret= DRIZZLE_DEFAULT_SOCKET_SEND_SIZE;
01781 #ifdef _WIN32
01782 ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDBUF, (const char*)&ret, (socklen_t)sizeof(int));
01783 #else
01784 ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDBUF, &ret, (socklen_t)sizeof(int));
01785 #endif
01786 if (ret == -1)
01787 {
01788 drizzle_set_error(con->drizzle, __func__, "setsockopt:SO_SNDBUF:%s", strerror(errno));
01789 return DRIZZLE_RETURN_ERRNO;
01790 }
01791
01792 ret= DRIZZLE_DEFAULT_SOCKET_RECV_SIZE;
01793 #ifdef _WIN32
01794 ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVBUF, (const char*)&ret, (socklen_t)sizeof(int));
01795 #else
01796 ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVBUF, &ret, (socklen_t)sizeof(int));
01797 #endif
01798 if (ret == -1)
01799 {
01800 drizzle_set_error(con->drizzle, __func__, "setsockopt:SO_RCVBUF:%s", strerror(errno));
01801 return DRIZZLE_RETURN_ERRNO;
01802 }
01803
01804 #if defined (_WIN32)
01805 {
01806 unsigned long asyncmode;
01807 asyncmode= 1;
01808 ioctlsocket(con->fd, FIONBIO, &asyncmode);
01809 }
01810 #else
01811 ret= fcntl(con->fd, F_GETFL, 0);
01812 if (ret == -1)
01813 {
01814 drizzle_set_error(con->drizzle, __func__, "fcntl:F_GETFL:%s", strerror(errno));
01815 return DRIZZLE_RETURN_ERRNO;
01816 }
01817
01818 ret= fcntl(con->fd, F_SETFL, ret | O_NONBLOCK);
01819 if (ret == -1)
01820 {
01821 drizzle_set_error(con->drizzle, __func__, "fcntl:F_SETFL:%s", strerror(errno));
01822 return DRIZZLE_RETURN_ERRNO;
01823 }
01824 #endif
01825
01826 return DRIZZLE_RETURN_OK;
01827 }