Drizzled Public API Documentation

drizzle.cc
Go to the documentation of this file.
00001 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00002  *
00003  * Drizzle Client & Protocol Library
00004  *
00005  * Copyright (C) 2008 Eric Day (eday@oddments.org)
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are
00010  * met:
00011  *
00012  *     * Redistributions of source code must retain the above copyright
00013  * notice, this list of conditions and the following disclaimer.
00014  *
00015  *     * Redistributions in binary form must reproduce the above
00016  * copyright notice, this list of conditions and the following disclaimer
00017  * in the documentation and/or other materials provided with the
00018  * distribution.
00019  *
00020  *     * The names of its contributors may not be used to endorse or
00021  * promote products derived from this software without specific prior
00022  * written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00027  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00028  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00029  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00030  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00031  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00032  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00033  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  */
00037 
00043 #include <libdrizzle/common.h>
00044 
00054 static const char *_verbose_name[DRIZZLE_VERBOSE_MAX]=
00055 {
00056   "NEVER",
00057   "FATAL",
00058   "ERROR",
00059   "INFO",
00060   "DEBUG",
00061   "CRAZY"
00062 };
00063 
00066 /*
00067  * Common Definitions
00068  */
00069 
00070 const char *drizzle_version(void)
00071 {
00072   return PACKAGE_VERSION;
00073 }
00074 
00075 const char *drizzle_bugreport(void)
00076 {
00077   return PACKAGE_BUGREPORT;
00078 }
00079 
00080 const char *drizzle_verbose_name(drizzle_verbose_t verbose)
00081 {
00082   if (verbose >= DRIZZLE_VERBOSE_MAX)
00083   {
00084     return "UNKNOWN";
00085   }
00086 
00087   return _verbose_name[verbose];
00088 }
00089 
00090 drizzle_st *drizzle_create(drizzle_st *drizzle)
00091 {
00092 #if defined(_WIN32)
00093   /* if it is MS windows, invoke WSAStartup */
00094   WSADATA wsaData;
00095   if ( WSAStartup( MAKEWORD(2,2), &wsaData ) != 0 )
00096     printf("Error at WSAStartup()\n");
00097 #else
00098   struct sigaction act;
00099   memset(&act, 0, sizeof(act));
00100 
00101   act.sa_handler = SIG_IGN;
00102   sigaction(SIGPIPE, &act, NULL);
00103 #endif
00104 
00105   if (drizzle == NULL)
00106   {
00107     drizzle= new (std::nothrow) drizzle_st;
00108     if (drizzle == NULL)
00109     {
00110       return NULL;
00111     }
00112 
00113     drizzle->options= DRIZZLE_ALLOCATED;
00114   }
00115   else
00116   {
00117     drizzle->options= DRIZZLE_NONE;
00118   }
00119 
00120   /* @todo remove this default free flag with new API. */
00121   drizzle->options|= DRIZZLE_FREE_OBJECTS;
00122   drizzle->error_code= 0;
00123   /* drizzle->options set above */
00124   drizzle->verbose= DRIZZLE_VERBOSE_NEVER;
00125   drizzle->con_count= 0;
00126   drizzle->pfds_size= 0;
00127   drizzle->query_count= 0;
00128   drizzle->query_new= 0;
00129   drizzle->query_running= 0;
00130   drizzle->last_errno= 0;
00131   drizzle->timeout= -1;
00132   drizzle->con_list= NULL;
00133   drizzle->context= NULL;
00134   drizzle->context_free_fn= NULL;
00135   drizzle->event_watch_fn= NULL;
00136   drizzle->event_watch_context= NULL;
00137   drizzle->log_fn= NULL;
00138   drizzle->log_context= NULL;
00139   drizzle->pfds= NULL;
00140   drizzle->query_list= NULL;
00141   drizzle->sqlstate[0]= 0;
00142   drizzle->last_error[0]= 0;
00143 
00144   return drizzle;
00145 }
00146 
00147 drizzle_st *drizzle_clone(drizzle_st *drizzle, const drizzle_st *from)
00148 {
00149   drizzle= drizzle_create(drizzle);
00150   if (drizzle == NULL)
00151   {
00152     return NULL;
00153   }
00154 
00155   drizzle->options|= (from->options & int(~DRIZZLE_ALLOCATED));
00156 
00157   for (drizzle_con_st *con= from->con_list; con != NULL; con= con->next)
00158   {
00159     if (drizzle_con_clone(drizzle, NULL, con) == NULL)
00160     {
00161       drizzle_free(drizzle);
00162       return NULL;
00163     }
00164   }
00165 
00166   return drizzle;
00167 }
00168 
00169 void drizzle_free(drizzle_st *drizzle)
00170 {
00171   if (drizzle == NULL)
00172   {
00173     return;
00174   }
00175 
00176   if (drizzle->context != NULL && drizzle->context_free_fn != NULL)
00177   {
00178     drizzle->context_free_fn(drizzle, drizzle->context);
00179   }
00180 
00181   if (drizzle->options & DRIZZLE_FREE_OBJECTS)
00182   {
00183     drizzle_con_free_all(drizzle);
00184     drizzle_query_free_all(drizzle);
00185   }
00186   else if (drizzle->options & DRIZZLE_ASSERT_DANGLING)
00187   {
00188     assert(drizzle->con_list == NULL);
00189     assert(drizzle->query_list == NULL);
00190   }
00191 
00192   free(drizzle->pfds);
00193 
00194   if (drizzle->options & DRIZZLE_ALLOCATED)
00195   {
00196     delete drizzle;
00197   }
00198 #if defined(_WIN32)
00199   /* if it is MS windows, invoke WSACleanup() at the end*/
00200   WSACleanup();
00201 #endif
00202 }
00203 
00204 const char *drizzle_error(const drizzle_st *drizzle)
00205 {
00206   if (drizzle == NULL)
00207   {
00208     return NULL;
00209   }
00210 
00211   return (const char *)drizzle->last_error;
00212 }
00213 
00214 int drizzle_errno(const drizzle_st *drizzle)
00215 {
00216   if (drizzle == NULL)
00217   {
00218     return 0;
00219   }
00220 
00221   return drizzle->last_errno;
00222 }
00223 
00224 uint16_t drizzle_error_code(const drizzle_st *drizzle)
00225 {
00226   if (drizzle == NULL)
00227   {
00228     return 0;
00229   }
00230 
00231   return drizzle->error_code;
00232 }
00233 
00234 const char *drizzle_sqlstate(const drizzle_st *drizzle)
00235 {
00236   if (drizzle == NULL)
00237   {
00238     return NULL;
00239   }
00240 
00241   return drizzle->sqlstate;
00242 }
00243 
00244 drizzle_options_t drizzle_options(const drizzle_st *drizzle)
00245 {
00246   if (drizzle == NULL)
00247   {
00248     return drizzle_options_t();
00249   }
00250 
00251   return drizzle_options_t(drizzle->options);
00252 }
00253 
00254 void drizzle_set_options(drizzle_st *drizzle, drizzle_options_t options)
00255 {
00256   if (drizzle == NULL)
00257   {
00258     return;
00259   }
00260 
00261   drizzle->options= options;
00262 }
00263 
00264 void drizzle_add_options(drizzle_st *drizzle, drizzle_options_t options)
00265 {
00266   if (drizzle == NULL)
00267   {
00268     return;
00269   }
00270 
00271   drizzle->options|= options;
00272 }
00273 
00274 void drizzle_remove_options(drizzle_st *drizzle, drizzle_options_t options)
00275 {
00276   if (drizzle == NULL)
00277   {
00278     return;
00279   }
00280 
00281   drizzle->options&= ~options;
00282 }
00283 
00284 void *drizzle_context(const drizzle_st *drizzle)
00285 {
00286   if (drizzle == NULL)
00287   {
00288     return NULL;
00289   }
00290 
00291   return drizzle->context;
00292 }
00293 
00294 void drizzle_set_context(drizzle_st *drizzle, void *context)
00295 {
00296   if (drizzle == NULL)
00297   {
00298     return;
00299   }
00300 
00301   drizzle->context= context;
00302 }
00303 
00304 void drizzle_set_context_free_fn(drizzle_st *drizzle,
00305                                  drizzle_context_free_fn *function)
00306 {
00307   if (drizzle == NULL)
00308   {
00309     return;
00310   }
00311 
00312   drizzle->context_free_fn= function;
00313 }
00314 
00315 int drizzle_timeout(const drizzle_st *drizzle)
00316 {
00317   if (drizzle == NULL)
00318   {
00319     return -1;
00320   }
00321 
00322   return drizzle->timeout;
00323 }
00324 
00325 void drizzle_set_timeout(drizzle_st *drizzle, int timeout)
00326 {
00327   if (drizzle == NULL)
00328   {
00329     return;
00330   }
00331 
00332   drizzle->timeout= timeout;
00333 }
00334 
00335 drizzle_verbose_t drizzle_verbose(const drizzle_st *drizzle)
00336 {
00337   if (drizzle == NULL)
00338   {
00339     return drizzle_verbose_t();
00340   }
00341 
00342   return drizzle->verbose;
00343 }
00344 
00345 void drizzle_set_verbose(drizzle_st *drizzle, drizzle_verbose_t verbose)
00346 {
00347   if (drizzle == NULL)
00348   {
00349     return;
00350   }
00351 
00352   drizzle->verbose= verbose;
00353 }
00354 
00355 void drizzle_set_log_fn(drizzle_st *drizzle, drizzle_log_fn *function,
00356                         void *context)
00357 {
00358   if (drizzle == NULL)
00359   {
00360     return;
00361   }
00362 
00363   drizzle->log_fn= function;
00364   drizzle->log_context= context;
00365 }
00366 
00367 void drizzle_set_event_watch_fn(drizzle_st *drizzle,
00368                                 drizzle_event_watch_fn *function,
00369                                 void *context)
00370 {
00371   if (drizzle == NULL)
00372   {
00373     return;
00374   }
00375 
00376   drizzle->event_watch_fn= function;
00377   drizzle->event_watch_context= context;
00378 }
00379 
00380 drizzle_con_st *drizzle_con_create(drizzle_st *drizzle, drizzle_con_st *con)
00381 {
00382   if (drizzle == NULL)
00383   {
00384     return NULL;
00385   }
00386 
00387   if (con == NULL)
00388   {
00389     con= new (std::nothrow) drizzle_con_st;
00390     if (con == NULL)
00391     {
00392       if (drizzle != NULL)
00393       {
00394         drizzle_set_error(drizzle, __func__, "Failed to allocate.");
00395       }
00396 
00397       return NULL;
00398     }
00399 
00400     con->options= DRIZZLE_CON_ALLOCATED;
00401   }
00402   else
00403   {
00404     con->options= 0;
00405   }
00406 
00407   if (drizzle->con_list != NULL)
00408   {
00409     drizzle->con_list->prev= con;
00410   }
00411   con->next= drizzle->con_list;
00412   con->prev= NULL;
00413   drizzle->con_list= con;
00414   drizzle->con_count++;
00415 
00416   con->packet_number= 0;
00417   con->protocol_version= 0;
00418   con->state_current= 0;
00419   con->events= 0;
00420   con->revents= 0;
00421   con->capabilities= DRIZZLE_CAPABILITIES_NONE;
00422   con->charset= 0;
00423   con->command= drizzle_command_t();
00424   con->options|= DRIZZLE_CON_MYSQL;
00425   con->socket_type= DRIZZLE_CON_SOCKET_TCP;
00426   con->status= DRIZZLE_CON_STATUS_NONE;
00427   con->max_packet_size= DRIZZLE_MAX_PACKET_SIZE;
00428   con->result_count= 0;
00429   con->thread_id= 0;
00430   con->backlog= DRIZZLE_DEFAULT_BACKLOG;
00431   con->fd= -1;
00432   con->buffer_size= 0;
00433   con->command_offset= 0;
00434   con->command_size= 0;
00435   con->command_total= 0;
00436   con->packet_size= 0;
00437   con->addrinfo_next= NULL;
00438   con->buffer_ptr= con->buffer;
00439   con->command_buffer= NULL;
00440   con->command_data= NULL;
00441   con->context= NULL;
00442   con->context_free_fn= NULL;
00443   con->drizzle= drizzle;
00444   /* con->next set above */
00445   /* con->prev set above */
00446   con->query= NULL;
00447   /* con->result doesn't need to be set */
00448   con->result_list= NULL;
00449   con->scramble= NULL;
00450   con->socket.tcp.addrinfo= NULL;
00451   con->socket.tcp.host= NULL;
00452   con->socket.tcp.port= 0;
00453   /* con->buffer doesn't need to be set */
00454   con->db[0]= 0;
00455   con->password[0]= 0;
00456   /* con->scramble_buffer doesn't need to be set */
00457   con->server_version[0]= 0;
00458   /* con->state_stack doesn't need to be set */
00459   con->user[0]= 0;
00460 
00461   return con;
00462 }
00463 
00464 drizzle_con_st *drizzle_con_clone(drizzle_st *drizzle, drizzle_con_st *con,
00465                                   const drizzle_con_st *from)
00466 {
00467   if (drizzle == NULL)
00468   {
00469     return NULL;
00470   }
00471 
00472   con= drizzle_con_create(drizzle, con);
00473   if (con == NULL)
00474   {
00475     return NULL;
00476   }
00477 
00478   /* Clear "operational" options such as IO status. */
00479   con->options|= (from->options & int(~(
00480                   DRIZZLE_CON_ALLOCATED|DRIZZLE_CON_READY|
00481                   DRIZZLE_CON_NO_RESULT_READ|DRIZZLE_CON_IO_READY|
00482                   DRIZZLE_CON_LISTEN)));
00483   con->backlog= from->backlog;
00484   strcpy(con->db, from->db);
00485   strcpy(con->password, from->password);
00486   strcpy(con->user, from->user);
00487 
00488   switch (from->socket_type)
00489   {
00490   case DRIZZLE_CON_SOCKET_TCP:
00491     drizzle_con_set_tcp(con, from->socket.tcp.host, from->socket.tcp.port);
00492     break;
00493 
00494   case DRIZZLE_CON_SOCKET_UDS:
00495     drizzle_con_set_uds(con, from->socket.uds.sockaddr.sun_path);
00496     break;
00497 
00498   default:
00499     break;
00500   }
00501 
00502   return con;
00503 }
00504 
00505 void drizzle_con_free(drizzle_con_st *con)
00506 {
00507   if (con == NULL)
00508   {
00509     return;
00510   }
00511 
00512   if (con->context != NULL and con->context_free_fn != NULL)
00513   {
00514     con->context_free_fn(con, con->context);
00515   }
00516 
00517   if (con->drizzle->options & DRIZZLE_FREE_OBJECTS)
00518   {
00519     drizzle_result_free_all(con);
00520   }
00521   else if (con->drizzle->options & DRIZZLE_ASSERT_DANGLING)
00522   {
00523     assert(con->result_list == NULL);
00524   }
00525 
00526   if (con->fd != -1)
00527   {
00528     drizzle_con_close(con);
00529   }
00530 
00531   drizzle_con_reset_addrinfo(con);
00532 
00533   if (con->drizzle->con_list == con)
00534     con->drizzle->con_list= con->next;
00535 
00536   if (con->prev != NULL)
00537     con->prev->next= con->next;
00538 
00539   if (con->next != NULL)
00540     con->next->prev= con->prev;
00541 
00542   con->drizzle->con_count--;
00543 
00544   if (con->options & DRIZZLE_CON_ALLOCATED)
00545   {
00546     delete con;
00547   }
00548 }
00549 
00550 void drizzle_con_free_all(drizzle_st *drizzle)
00551 {
00552   while (drizzle->con_list != NULL)
00553     drizzle_con_free(drizzle->con_list);
00554 }
00555 
00556 drizzle_return_t drizzle_con_wait(drizzle_st *drizzle)
00557 {
00558   if (drizzle == NULL)
00559   {
00560     return DRIZZLE_RETURN_INVALID_ARGUMENT;
00561   }
00562 
00563   struct pollfd *pfds;
00564   if (drizzle->pfds_size < drizzle->con_count)
00565   {
00566     pfds= (struct pollfd *)realloc(drizzle->pfds, drizzle->con_count * sizeof(struct pollfd));
00567     if (pfds == NULL)
00568     {
00569       drizzle_set_error(drizzle, __func__, "Failed to realloc file descriptors.");
00570       return DRIZZLE_RETURN_MEMORY;
00571     }
00572 
00573     drizzle->pfds= pfds;
00574     drizzle->pfds_size= drizzle->con_count;
00575   }
00576   else
00577   {
00578     pfds= drizzle->pfds;
00579   }
00580 
00581   uint32_t x= 0;
00582   for (drizzle_con_st *con= drizzle->con_list; con != NULL; con= con->next)
00583   {
00584     if (con->events == 0)
00585     {
00586       continue;
00587     }
00588 
00589     pfds[x].fd= con->fd;
00590     pfds[x].events= con->events;
00591     pfds[x].revents= 0;
00592     x++;
00593   }
00594 
00595   if (x == 0)
00596   {
00597     drizzle_set_error(drizzle, __func__, "no active file descriptors");
00598     return DRIZZLE_RETURN_NO_ACTIVE_CONNECTIONS;
00599   }
00600 
00601   int ret;
00602   while (1)
00603   {
00604     drizzle_log_crazy(drizzle, "poll count=%d timeout=%d", x,
00605                       drizzle->timeout);
00606 
00607     ret= poll(pfds, x, drizzle->timeout);
00608 
00609     drizzle_log_crazy(drizzle, "poll return=%d errno=%d", ret, errno);
00610 
00611     if (ret == -1)
00612     {
00613       if (errno == EINTR)
00614       {
00615         continue;
00616       }
00617 
00618       drizzle_set_error(drizzle, "drizzle_con_wait", "poll:%d", errno);
00619       drizzle->last_errno= errno;
00620       return DRIZZLE_RETURN_ERRNO;
00621     }
00622 
00623     break;
00624   }
00625 
00626   if (ret == 0)
00627   {
00628     drizzle_set_error(drizzle, "drizzle_con_wait", "timeout reached");
00629     return DRIZZLE_RETURN_TIMEOUT;
00630   }
00631 
00632   x= 0;
00633   for (drizzle_con_st *con= drizzle->con_list; con != NULL; con= con->next)
00634   {
00635     if (con->events == 0)
00636     {
00637       continue;
00638     }
00639 
00640     drizzle_return_t dret= drizzle_con_set_revents(con, pfds[x].revents);
00641     if (dret != DRIZZLE_RETURN_OK)
00642     {
00643       return dret;
00644     }
00645 
00646     x++;
00647   }
00648 
00649   return DRIZZLE_RETURN_OK;
00650 }
00651 
00652 drizzle_con_st *drizzle_con_ready(drizzle_st *drizzle)
00653 {
00654   if (drizzle == NULL)
00655   {
00656     return NULL;
00657   }
00658 
00659   /* We can't keep state between calls since connections may be removed during
00660      processing. If this list ever gets big, we may want something faster. */
00661 
00662   for (drizzle_con_st *con= drizzle->con_list; con != NULL; con= con->next)
00663   {
00664     if (con->options & DRIZZLE_CON_IO_READY)
00665     {
00666       con->options&= int(~DRIZZLE_CON_IO_READY);
00667       return con;
00668     }
00669   }
00670 
00671   return NULL;
00672 }
00673 
00674 drizzle_con_st *drizzle_con_ready_listen(drizzle_st *drizzle)
00675 {
00676   if (drizzle == NULL)
00677   {
00678     return NULL;
00679   }
00680 
00681   /* We can't keep state between calls since connections may be removed during
00682      processing. If this list ever gets big, we may want something faster. */
00683 
00684   for (drizzle_con_st *con= drizzle->con_list; con != NULL; con= con->next)
00685   {
00686     if ((con->options & (DRIZZLE_CON_IO_READY | DRIZZLE_CON_LISTEN)) ==
00687         (DRIZZLE_CON_IO_READY | DRIZZLE_CON_LISTEN))
00688     {
00689       con->options&= int(~DRIZZLE_CON_IO_READY);
00690       return con;
00691     }
00692   }
00693 
00694   return NULL;
00695 }
00696 
00697 /*
00698  * Client Definitions
00699  */
00700 
00701 drizzle_con_st *drizzle_con_add_tcp(drizzle_st *drizzle, drizzle_con_st *con,
00702                                     const char *host, in_port_t port,
00703                                     const char *user, const char *password,
00704                                     const char *db,
00705                                     drizzle_con_options_t options)
00706 {
00707   if (drizzle == NULL)
00708   {
00709     return NULL;
00710   }
00711 
00712   con= drizzle_con_create(drizzle, con);
00713   if (con == NULL)
00714   {
00715     return NULL;
00716   }
00717 
00718   drizzle_con_set_tcp(con, host, port);
00719   drizzle_con_set_auth(con, user, password);
00720   drizzle_con_set_db(con, db);
00721   drizzle_con_add_options(con, options);
00722 
00723   return con;
00724 }
00725 
00726 drizzle_con_st *drizzle_con_add_uds(drizzle_st *drizzle, drizzle_con_st *con,
00727                                     const char *uds, const char *user,
00728                                     const char *password, const char *db,
00729                                     drizzle_con_options_t options)
00730 {
00731   if (drizzle == NULL)
00732   {
00733     return NULL;
00734   }
00735 
00736   con= drizzle_con_create(drizzle, con);
00737   if (con == NULL)
00738   {
00739     return NULL;
00740   }
00741 
00742   drizzle_con_set_uds(con, uds);
00743   drizzle_con_set_auth(con, user, password);
00744   drizzle_con_set_db(con, db);
00745   drizzle_con_add_options(con, options);
00746 
00747   return con;
00748 }
00749 
00750 /*
00751  * Server Definitions
00752  */
00753 
00754 drizzle_con_st *drizzle_con_add_tcp_listen(drizzle_st *drizzle,
00755                                            drizzle_con_st *con,
00756                                            const char *host, in_port_t port,
00757                                            int backlog,
00758                                            drizzle_con_options_t options)
00759 {
00760   if (drizzle == NULL)
00761   {
00762     return NULL;
00763   }
00764 
00765   con= drizzle_con_create(drizzle, con);
00766   if (con == NULL)
00767   {
00768     return NULL;
00769   }
00770 
00771   drizzle_con_set_tcp(con, host, port);
00772   drizzle_con_set_backlog(con, backlog);
00773   drizzle_con_add_options(con, drizzle_con_options_t(DRIZZLE_CON_LISTEN | int(options)));
00774 
00775   return con;
00776 }
00777 
00778 drizzle_con_st *drizzle_con_add_uds_listen(drizzle_st *drizzle,
00779                                            drizzle_con_st *con,
00780                                            const char *uds, int backlog,
00781                                            drizzle_con_options_t options)
00782 {
00783   if (drizzle == NULL)
00784   {
00785     return NULL;
00786   }
00787 
00788   con= drizzle_con_create(drizzle, con);
00789   if (con == NULL)
00790   {
00791     return NULL;
00792   }
00793 
00794   drizzle_con_set_uds(con, uds);
00795   drizzle_con_set_backlog(con, backlog);
00796   drizzle_con_add_options(con, drizzle_con_options_t(DRIZZLE_CON_LISTEN | int(options)));
00797 
00798   return con;
00799 }
00800 
00801 drizzle_con_st *drizzle_con_accept(drizzle_st *drizzle, drizzle_con_st *con,
00802                                    drizzle_return_t *ret_ptr)
00803 {
00804   drizzle_return_t unused_ret;
00805   if (ret_ptr == NULL)
00806   {
00807     ret_ptr= &unused_ret;
00808   }
00809 
00810   if (drizzle == NULL)
00811   {
00812     return NULL;
00813   }
00814 
00815   while (1)
00816   {
00817     drizzle_con_st *ready;
00818 
00819     if ((ready= drizzle_con_ready_listen(drizzle)) != NULL)
00820     {
00821       int fd= accept(ready->fd, NULL, NULL);
00822 
00823       con= drizzle_con_create(drizzle, con);
00824       if (con == NULL)
00825       {
00826         (void)closesocket(fd);
00827         *ret_ptr= DRIZZLE_RETURN_MEMORY;
00828         return NULL;
00829       }
00830 
00831       *ret_ptr= drizzle_con_set_fd(con, fd);
00832       if (*ret_ptr != DRIZZLE_RETURN_OK)
00833       {
00834         (void)closesocket(fd);
00835         return NULL;
00836       }
00837 
00838       if (ready->options & DRIZZLE_CON_MYSQL)
00839         drizzle_con_add_options(con, DRIZZLE_CON_MYSQL);
00840 
00841       *ret_ptr= DRIZZLE_RETURN_OK;
00842       return con;
00843     }
00844 
00845     if (drizzle->options & DRIZZLE_NON_BLOCKING)
00846     {
00847       *ret_ptr= DRIZZLE_RETURN_IO_WAIT;
00848       return NULL;
00849     }
00850 
00851     for (ready= drizzle->con_list; ready != NULL; ready= ready->next)
00852     {
00853       if (ready->options & DRIZZLE_CON_LISTEN)
00854         drizzle_con_set_events(ready, POLLIN);
00855     }
00856 
00857     *ret_ptr= drizzle_con_wait(drizzle);
00858     if (*ret_ptr != DRIZZLE_RETURN_OK)
00859       return NULL;
00860   }
00861 }
00862 
00863 /*
00864  * Local Definitions
00865  */
00866 
00867 void drizzle_set_error(drizzle_st *drizzle, const char *function,
00868                        const char *format, ...)
00869 {
00870   if (drizzle == NULL)
00871   {
00872     return;
00873   }
00874 
00875   size_t size;
00876   int written;
00877   char log_buffer[DRIZZLE_MAX_ERROR_SIZE];
00878   va_list args;
00879 
00880   size= strlen(function);
00881   char *ptr= (char *)memcpy(log_buffer, function, size);
00882   ptr+= size;
00883   ptr[0]= ':';
00884   size++;
00885   ptr++;
00886 
00887   va_start(args, format);
00888   written= vsnprintf(ptr, DRIZZLE_MAX_ERROR_SIZE - size, format, args);
00889   va_end(args);
00890 
00891   if (written < 0)
00892   {
00893     size= DRIZZLE_MAX_ERROR_SIZE;
00894   }
00895   else
00896   {
00897     size+= written;
00898   }
00899 
00900   if (size >= DRIZZLE_MAX_ERROR_SIZE)
00901   {
00902     size= DRIZZLE_MAX_ERROR_SIZE - 1;
00903   }
00904   log_buffer[size]= 0;
00905 
00906   if (drizzle->log_fn == NULL)
00907   {
00908     memcpy(drizzle->last_error, log_buffer, size + 1);
00909   }
00910   else
00911   {
00912     drizzle->log_fn(log_buffer, DRIZZLE_VERBOSE_ERROR, drizzle->log_context);
00913   }
00914 }
00915 
00916 void drizzle_log(drizzle_st *drizzle, drizzle_verbose_t verbose,
00917                  const char *format, va_list args)
00918 {
00919   if (drizzle == NULL)
00920   {
00921     return;
00922   }
00923 
00924   char log_buffer[DRIZZLE_MAX_ERROR_SIZE];
00925 
00926   if (drizzle->log_fn == NULL)
00927   {
00928     printf("%5s: ", drizzle_verbose_name(verbose));
00929     vprintf(format, args);
00930     printf("\n");
00931   }
00932   else
00933   {
00934     vsnprintf(log_buffer, DRIZZLE_MAX_ERROR_SIZE, format, args);
00935     log_buffer[DRIZZLE_MAX_ERROR_SIZE-1]= 0;
00936     drizzle->log_fn(log_buffer, verbose, drizzle->log_context);
00937   }
00938 }