Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

mysql.c

Go to the documentation of this file.
00001 /*! \file mysql.c
00002           Simple interface to MySql.
00003  */ 
00004 
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <stdarg.h>
00008 #include <unistd.h>
00009 #include <string.h>
00010 #include <mysql/errmsg.h>
00011 #include "config.h"        /* EXT, from the common-c-lib */ 
00012 #include "mysql_header.h"  /* INT                        */
00013 #include "strings_utils.h"
00014 #include "mysqld_error.h"
00015 
00016 
00017 
00018 static void set_last_error (struct smysql *mysql_info);
00019 static void clear_error_reporting (struct smysql *mysql_info);
00020 static void copy_error (struct smysql *mysql_info, char *m);
00021 static int standard_query (struct smysql *mysql_info, char* query);
00022 
00023 /*! \brief Last MySql error message.
00024  */
00025 
00026 char mysql_error_str[MYSQL_MAX_ERROR_SIZE];
00027 
00028 /*! \brief Last MySql error code.
00029  */
00030 
00031 int  mysql_error_errno;
00032 
00033 /*! \brief This is a handler to a fake loggin service. It is used if no logging service is specified in the
00034            MySql configuration handler.
00035  */
00036 
00037 static int my_fake_syslog (const char *file, const char * fmt,...) { return 0; }
00038 
00039 /*! \brief Assign a logging service to a given MySql handler.
00040     \author Denis BEURIVE
00041     \param logger Pointer to a guven logging service.
00042     \param mysql_info Pointer  to a MySql handler.
00043     \remark To desactivate logging, just set the value of 'logger' to NULL.
00044     \warning Unless you call load_mysql_configuration_from_file(), you MUST call mysql_set_logger() first!
00045              Failing to initialize the logging service may lead to process segmentation fault.
00046  */ 
00047 
00048 void mysql_set_logger (int (*logger) (const char *file, const char * fmt,...), struct smysql *mysql_info)
00049 { mysql_info->my_syslog = logger; } 
00050 
00051 /*! \brief Clear all error reporting data.
00052     \author Denis BEURIVE
00053  */
00054 
00055 static void clear_error_reporting (struct smysql *mysql_info)
00056 {
00057   mysql_info->last_error_int = 0;
00058   memset ((void*)mysql_info->last_error_str, 0, MYSQL_MAX_ERROR_SIZE);
00059   mysql_error_errno = 0;
00060   memset ((void*)mysql_error_str, 0, MYSQL_MAX_ERROR_SIZE);
00061 }
00062 
00063 /*! \brief Safely copy error message from MySql.
00064     \author Denis BEURIVE
00065     \param mysql_info Pointer to a Mysql management structure.
00066  */
00067 
00068 static void set_last_error (struct smysql *mysql_info)
00069 {
00070   const char *err;
00071   int        merror;
00072 
00073   err    = NULL;
00074   merror = 0;
00075 
00076   clear_error_reporting (mysql_info);
00077 
00078   merror = mysql_errno(mysql_info->handler);
00079   err    = mysql_error(mysql_info->handler);
00080  
00081   mysql_info->last_error_int = merror;
00082 
00083   if (err != NULL) { strncpy (mysql_info->last_error_str, err, MYSQL_MAX_ERROR_SIZE); }
00084   else             { strncpy (mysql_info->last_error_str, "No error message available", MYSQL_MAX_ERROR_SIZE); }
00085 
00086   mysql_error_errno = mysql_info->last_error_int;
00087   strcpy (mysql_error_str, mysql_info->last_error_str);
00088  
00089   return;
00090 }
00091 
00092 /*! \brief Safely copy a specific error message to the error reporting system. This function is intended to
00093            set functional error message (that does not have MySql system error defined).
00094     \author Denis BEURIVE
00095     \param mysql_info mysql_info Pointer to a Mysql management structure.
00096     \param m Pointer to zero terminated string of characters that represents the error message to report.
00097  */
00098 
00099 static void copy_error (struct smysql *mysql_info, char *m)
00100 {
00101   clear_error_reporting (mysql_info);
00102   mysql_info->last_error_int = 0;
00103   mysql_error_errno          = 0;
00104   strncpy (mysql_info->last_error_str, m, MYSQL_MAX_ERROR_SIZE); 
00105   strcpy (mysql_error_str, mysql_info->last_error_str);
00106 }
00107 
00108 
00109 /*! \brief Initialise the Mysql management structure.
00110     \author Denis BEURIVE
00111     \param mysql_info Pointer to a Mysql management structure.
00112  */
00113 
00114 void init_mysql_structure (struct smysql *mysql_info)
00115 {
00116   mysql_info->handler                   = NULL;
00117   mysql_info->result                    = NULL;
00118   mysql_info->num_fields                = -1;
00119   mysql_info->num_rows                  = -1;
00120   mysql_info->last_connection_timestamp = 0;
00121   mysql_info->connected                 = 0;
00122 
00123   clear_error_reporting (mysql_info);
00124 }
00125 
00126 /*! \brief Connect to Mysql server.
00127     \author Denis BEURIVE
00128     \param mysql_info Pointer to a Mysql management structure that contains all the configuration for the
00129            connection.
00130     \return Upon successful completion, the function returns the value 0. 
00131             Otherwise it returns the value 1.
00132     \warning <UL>
00133                <LI>You must call the function init_mysql_structure() first.
00134                <LI>Then you may:
00135                    <UL>
00136                       <LI>Call load_mysql_configuration_from_file() if you want to load the configuration
00137                           from a file.
00138                       <LI>Initialize the MySql configuration data structure yourself and call
00139                           mysql_set_logger().
00140                    </UL>
00141                <LI>Don't forget to call disconnect_from_mysql() in order to free the allocated memory.
00142                <LI>We use the option CLIENT_FOUND_ROWS which modify the behavior of the function
00143                    mysql_affected_raws(). With this option, the function mysql_affected_raws() returns the
00144                    number of rows that matched the "WHERE" statement. In standard mode, the function
00145                    mysql_affected_raws() returns the number of rows that have been changed.
00146              </UL>
00147  */
00148 
00149 int connect_to_mysql (struct smysql *mysql_info)
00150 {
00151   MYSQL *connect_res;
00152   int   retry;
00153   int   (*my_syslog)(const char *file, const char * fmt,...);
00154 
00155   if ((mysql_info->my_syslog != NULL) && (mysql_info->log_file[0] != 0))
00156   { my_syslog = mysql_info->my_syslog; }
00157   else { my_syslog = my_fake_syslog; }
00158 
00159 
00160   retry = 0;
00161   clear_error_reporting(mysql_info);
00162 
00163   while (retry <= mysql_info->connect_retry)
00164   {
00165     /* ----------------------------------------------- */
00166     /* Free allocated memory, if necessary             */
00167     /* ----------------------------------------------- */
00168 
00169     if (mysql_info->handler != NULL) { mysql_close(mysql_info->handler); mysql_info->handler = NULL; }
00170 
00171     /* ----------------------------------------------- */
00172     /* Initialize the handler structure                */
00173     /* ----------------------------------------------- */
00174 
00175     mysql_info->handler = mysql_init(mysql_info->handler);
00176     if (mysql_info->handler == NULL)
00177     {
00178       set_last_error (mysql_info);
00179       mysql_info->connected = 0;
00180       return 1;
00181     } 
00182 
00183     /* ----------------------------------------------- */
00184     /* Set the connection timeout                      */
00185     /* ----------------------------------------------- */
00186 
00187     if (mysql_options(
00188                        mysql_info->handler,
00189                        MYSQL_OPT_CONNECT_TIMEOUT,
00190                        (char*)&(mysql_info->connect_timeout)) != 0)
00191     {
00192       set_last_error (mysql_info);
00193       mysql_info->connected = 0;
00194       return 1;
00195     }
00196 
00197     /* ----------------------------------------------- */
00198     /* Connect to mysql server                         */
00199     /* Note: the option CLIENT_FOUND_ROWS modify the   */
00200     /* behavior of function mysql_affected_rows().     */
00201     /* ----------------------------------------------- */
00202 
00203     connect_res = mysql_real_connect (  
00204                                        mysql_info->handler,
00205                                        mysql_info->host,
00206                                        mysql_info->user,
00207                                        mysql_info->passwd,
00208                                        mysql_info->db,
00209                                        mysql_info->port,
00210                                        mysql_info->socket,
00211                                        CLIENT_FOUND_ROWS
00212                                      );
00213 
00214     if (connect_res != NULL) { break; }
00215 
00216     /* ----------------------------------------------- */
00217     /* Could not connect to server, try again          */
00218     /* ----------------------------------------------- */
00219 
00220     my_syslog (mysql_info->log_file, "[WARNING] [%s:%d] Try to reconnect to MySql server (%d / %d)",
00221                __FILE__, __LINE__,
00222                retry,
00223                mysql_info->connect_retry);
00224 
00225     sleep (mysql_info->connect_sleep);
00226 
00227     retry++;
00228   }
00229 
00230   /* ------------------------------------------------- */
00231   /* We may not be connected ...                       */
00232   /* ------------------------------------------------- */
00233 
00234   if (retry > mysql_info->connect_retry)
00235   {
00236     set_last_error (mysql_info);
00237     mysql_info->connected = 0;
00238     return 1;
00239   } 
00240 
00241   my_syslog (mysql_info->log_file,
00242              "[INFO] [%s:%d] Connection successfully established with MySql server", __FILE__, __LINE__);
00243 
00244   mysql_info->connected = 1;
00245   return 0;
00246 }
00247 
00248 /*! \brief Close the connection with the Mysql server and free allocated memory.
00249     \author Denis BEURIVE
00250     \param mysql_info Pointer to a Mysql management structure.
00251  */
00252 
00253 void disconnect_from_mysql(struct smysql *mysql_info)
00254 { if (mysql_info->handler != NULL) { mysql_close(mysql_info->handler); mysql_info->handler = NULL; } }
00255 
00256 /*! \brief Execute SQL statements that does not return data (UPDATE, DELETE, INSERT, REPLACE and otjer).
00257     \author Denis BEURIVE
00258     \param mysql_info Pointer to a Mysql management structure.
00259     \param query SQL statement to execute.
00260     \return Upon successful completion, the function returns the number of rows matched by the "WHERE" statement.
00261             Otherwize, the function may return one of the following values:
00262             <UL>
00263                <LI>MYSQL_REQUEST_SKIPED
00264                <LI>MYSQL_CONNECTION_LOST
00265                <LI>MYSQL_RECONNECTION_FAILED
00266                <LI>MYSQL_SQL_PROBLEM
00267                <LI>MYSQL_UNEXPECTED_ERROR
00268             </UL>
00269     \warning <UL>
00270                 <LI>Keep in mind that the function does __NOT__ return the number of rows that have been changed
00271                     by the request. The function returns the number of rows that matched the "WHERE" statement
00272                     (which may be different).
00273                 <LI>If the connection to the MySql server is lost, then the client tries to reconnect. If it
00274                     can not reconnect, then the function returns on failure.
00275              </UL>
00276  */
00277 
00278 static int standard_query (struct smysql *mysql_info, char* query)
00279 {
00280   int   cr, n, err;
00281   int   (*my_syslog)(const char *file, const char * fmt,...);
00282 
00283   if ((mysql_info->my_syslog != NULL) && (mysql_info->log_file[0] != 0))
00284   { my_syslog = mysql_info->my_syslog; }
00285   else { my_syslog = my_fake_syslog; }
00286 
00287 
00288   #ifdef TEST_MYSQL_STANDART_QUERY
00289     fprintf (stdout, "Testing mysql.c::standard_query()\n");
00290     fprintf (stdout, "  Next action: <1> Test the connection state (UP/DOWN).\n"); 
00291     fprintf (stdout, "  Next action: <2> If status is DOWN, test the delay since last disconnection.\n");
00292     fprintf (stdout, "  Next action: <3> If status is DOWN, skip request or try to reconnect.\n");
00293     fprintf (stdout, "\n");
00294     fprintf (stdout, "  Press any key to continue.");
00295     getchar();
00296     fprintf (stdout, "\n\n");
00297   #endif
00298 
00299   clear_error_reporting(mysql_info);
00300 
00301   /* ------------------------------------------------- */
00302   /* If connection is down, skip request OR try to     */
00303   /* reconnect.                                        */
00304   /* ------------------------------------------------- */
00305 
00306   if (! mysql_info->connected)
00307   {
00308     time_t delta = time(NULL) - mysql_info->last_connection_timestamp;
00309     if (mysql_info->reconnection_delay == 0) { delta = 0; } 
00310 
00311     my_syslog (mysql_info->log_file,
00312                "[INFO] [%s:%d] MySql connection is down since %u seconds",
00313                __FILE__, __LINE__, delta);
00314 
00315     if ((delta > mysql_info->reconnection_delay) || (mysql_info->reconnection_delay == 0))
00316     {
00317          my_syslog (mysql_info->log_file,
00318                     "[INFO] [%s:%d] %u > %u => Try to reconnect to MySql server",
00319                     __FILE__, __LINE__, 
00320                     delta, mysql_info->reconnection_delay);
00321 
00322          /* ------------------------------------------ */
00323          /* Try to reconnect                           */
00324          /* ------------------------------------------ */
00325 
00326          disconnect_from_mysql (mysql_info);
00327          if (connect_to_mysql(mysql_info) == 1)
00328          {
00329            my_syslog (mysql_info->log_file,
00330            "[WARNING] [%s:%d] Could not reconnect to MySql", __FILE__, __LINE__);
00331 
00332            /* ---------------------------------------- */
00333            /* Connection to the server is down         */
00334            /* ---------------------------------------- */
00335 
00336            mysql_info->last_connection_timestamp = time(NULL);
00337            mysql_info->connected = 0;
00338 
00339            copy_error (mysql_info, "Could not reconnect to MySql"); 
00340            return MYSQL_RECONNECTION_FAILED;
00341          }
00342          else
00343          {
00344            mysql_info->last_connection_timestamp = 0;
00345            mysql_info->connected = 1;
00346          }
00347     }
00348     else {
00349            my_syslog (mysql_info->log_file,
00350            "[INFO] [%s:%d] %u < %u => Do not try to reconnect. Skip SQL request",
00351            __FILE__, __LINE__, 
00352            delta, mysql_info->reconnection_delay);
00353            copy_error (mysql_info, "SQL request skiped (this is normal, see configuration)");
00354            return MYSQL_REQUEST_SKIPED;
00355          }
00356   }
00357 
00358   /* ------------------------------------------------- */
00359   /* At this point, the connection should be up        */
00360   /* ------------------------------------------------- */
00361 
00362   #ifdef TEST_MYSQL_STANDART_QUERY
00363     fprintf (stdout, "Testing mysql.c::standard_query()\n");
00364     fprintf (stdout, "  Next action: <1> Perform the SQL query\n");
00365     fprintf (stdout, "\n");
00366     fprintf (stdout, "  Press any key to continue.");
00367     getchar();
00368     fprintf (stdout, "\n\n");
00369   #endif
00370 
00371 
00372 
00373   while (1)
00374   {
00375      clear_error_reporting(mysql_info);
00376      
00377      /* ------------------------------------------------- */
00378      /* Make sure that we are connected                   */
00379      /* ------------------------------------------------- */
00380      
00381      if (mysql_info->handler == NULL)
00382      { set_last_error (mysql_info); return MYSQL_UNEXPECTED_ERROR; }
00383      
00384      /* ------------------------------------------------- */
00385      /* Send the request to mysql server                  */
00386      /* ------------------------------------------------- */
00387      
00388      cr = mysql_query(mysql_info->handler, query);
00389      if (cr != 0)
00390      {
00391        set_last_error (mysql_info);
00392 
00393        my_syslog (mysql_info->log_file,
00394        "[INFO] [%s:%d] Query [%s] failed: %s (%d -- CR_SERVER_GONE_ERROR=%d, CR_SERVER_LOST=%d, CR_CONNECTION_ERROR=%d, ER_SERVER_SHUTDOWN=%d)",
00395                   __FILE__, __LINE__,
00396                   query,
00397                   mysql_info->last_error_str,
00398                   mysql_info->last_error_int,
00399                   CR_SERVER_GONE_ERROR,
00400                   CR_SERVER_LOST,
00401                   CR_CONNECTION_ERROR,
00402                   ER_SERVER_SHUTDOWN);
00403    
00404        /* ----------------------------------------------- */
00405        /* The server may have gone away...                */
00406        /* ----------------------------------------------- */
00407    
00408        err = mysql_errno(mysql_info->handler);
00409    
00410        if ((err == CR_SERVER_GONE_ERROR) || (err == CR_SERVER_LOST) || (err == CR_CONNECTION_ERROR) ||
00411            (err == ER_SERVER_SHUTDOWN))
00412        {
00413          my_syslog (mysql_info->log_file,
00414                     "[WARNING] [%s:%d] Connection lost with MySql server", __FILE__, __LINE__);
00415 
00416          disconnect_from_mysql (mysql_info);
00417          if (connect_to_mysql(mysql_info) == 1)
00418          {
00419            my_syslog (mysql_info->log_file, 
00420            "[WARNING] [%s:%d] Could not reconnect to MySql", __FILE__, __LINE__);
00421 
00422            /* ------------------------------------------- */
00423            /* Connection to the server is down            */
00424            /* ------------------------------------------- */
00425 
00426            mysql_info->last_connection_timestamp = time(NULL);
00427            mysql_info->connected = 0;
00428            set_last_error (mysql_info);
00429            return MYSQL_CONNECTION_LOST;
00430          }
00431 
00432          my_syslog (mysql_info->log_file,
00433                     "[INFO] [%s:%d] Connection successfully established with MySql", __FILE__, __LINE__);
00434 
00435          mysql_info->last_connection_timestamp = 0;
00436          mysql_info->connected = 1;
00437 
00438          continue;
00439        }
00440        else {
00441                my_syslog (mysql_info->log_file,
00442                "[INFO] [%s:%d] Some SQL error occured", __FILE__, __LINE__);
00443                set_last_error (mysql_info);
00444                return MYSQL_SQL_PROBLEM;
00445             }
00446      }
00447 
00448      break;
00449   }
00450 
00451   /* ------------------------------------------------- */
00452   /* Get the number of affected rows                   */
00453   /* ------------------------------------------------- */
00454 
00455   n = mysql_affected_rows(mysql_info->handler);
00456 
00457   return n;
00458 }
00459 
00460 /*! \brief Execute an UPDATE SQL statement.
00461     \author Denis BEURIVE
00462     \param mysql_info Pointer to a Mysql management structure.
00463     \param query SQL statement to execute.
00464     \return Upon successful completion, the function returns the number of rows matched by the "WHERE"
00465             statement.
00466             Otherwize, the function may return one of the following values:
00467             <UL>
00468                <LI>MYSQL_REQUEST_SKIPED
00469                <LI>MYSQL_CONNECTION_LOST
00470                <LI>MYSQL_RECONNECTION_FAILED
00471                <LI>MYSQL_SQL_PROBLEM
00472                <LI>MYSQL_UNEXPECTED_ERROR
00473             </UL>
00474     \warning Keep in mind that the function does __NOT__ return the number of rows that have been changed by
00475              the request. The function returns the number of rows that matched the "WHERE" statement
00476              (which may be different). 
00477  */
00478 
00479 int sql_update (struct smysql *mysql_info, char* query) { return standard_query (mysql_info, query); }
00480 
00481 /*! \brief Execute an INSERT SQL statement.
00482     \author Denis BEURIVE
00483     \param mysql_info Pointer to a Mysql management structure.
00484     \param query SQL statement to execute.
00485     \return Upon successful completion, the function returns the number of rows matched by the "WHERE"
00486             statement.
00487             Otherwize, the function may return one of the following values:
00488             <UL>
00489                <LI>MYSQL_REQUEST_SKIPED
00490                <LI>MYSQL_CONNECTION_LOST
00491                <LI>MYSQL_RECONNECTION_FAILED
00492                <LI>MYSQL_SQL_PROBLEM
00493                <LI>MYSQL_UNEXPECTED_ERROR
00494             </UL>
00495     \warning Keep in mind that the function does __NOT__ return the number of rows that have been changed by
00496              the request. The function returns the number of rows that matched the "WHERE" statement
00497              (which may be different). 
00498  */
00499 
00500 int sql_insert (struct smysql *mysql_info, char* query) { return standard_query (mysql_info, query); }
00501 
00502 /*! \brief Execute a REPLACE SQL statement.
00503     \author Denis BEURIVE
00504     \param mysql_info Pointer to a Mysql management structure.
00505     \param query SQL statement to execute.
00506     \return Upon successful completion, the function returns the number of rows matched by the "WHERE"
00507             statement.
00508             Otherwize, the function may return one of the following values:
00509             <UL>
00510                <LI>MYSQL_REQUEST_SKIPED
00511                <LI>MYSQL_CONNECTION_LOST
00512                <LI>MYSQL_RECONNECTION_FAILED
00513                <LI>MYSQL_SQL_PROBLEM
00514                <LI>MYSQL_UNEXPECTED_ERROR
00515             </UL>
00516     \warning Keep in mind that the function does __NOT__ return the number of rows that have been changed by
00517              the request. The function returns the number of rows that matched the "WHERE" statement
00518              (which may be different).
00519  */
00520 
00521 int sql_replace (struct smysql *mysql_info, char* query) { return standard_query (mysql_info, query); }
00522 
00523 /*! \brief Execute a DELETE SQL statement.
00524     \author Denis BEURIVE
00525     \param mysql_info Pointer to a Mysql management structure.
00526     \param query SQL statement to execute.
00527     \return Upon successful completion, the function returns the number of rows matched by the "WHERE"
00528             statement.
00529             Otherwize, the function may return one of the following values:
00530             <UL>
00531                <LI>MYSQL_REQUEST_SKIPED
00532                <LI>MYSQL_CONNECTION_LOST
00533                <LI>MYSQL_RECONNECTION_FAILED
00534                <LI>MYSQL_SQL_PROBLEM
00535                <LI>MYSQL_UNEXPECTED_ERROR
00536             </UL>
00537     \warning Keep in mind that the function does __NOT__ return the number of rows that have been changed by
00538              the request. The function returns the number of rows that matched the "WHERE" statement
00539              (which may be different). 
00540  */
00541 
00542 int sql_delete (struct smysql *mysql_info, char* query) { return standard_query (mysql_info, query); }
00543 
00544 /*! \brief Execute a SELECT SQL statement.
00545     \author Denis BEURIVE
00546     \param mysql_info Pointer to a Mysql management structure.
00547     \param query SQL statement to execute.
00548     \return Upon successful completion, the function returns the number of selected items.
00549             Otherwize, the function may return one of the following values:
00550             <UL>
00551                <LI>MYSQL_REQUEST_SKIPED
00552                <LI>MYSQL_CONNECTION_LOST
00553                <LI>MYSQL_RECONNECTION_FAILED
00554                <LI>MYSQL_SQL_PROBLEM
00555                <LI>MYSQL_UNEXPECTED_ERROR
00556             </UL>
00557     \warning Upon successful completion, the fonction stores results into the MySql data structure
00558              <I>mysql_info->result</I>. You must call the function mysql_free_result() in order to
00559              free all allocated memory. Note that if an error occured, you must <B>__NOT__</B> call 
00560              mysql_free_result().
00561  */
00562 
00563 int sql_select (struct smysql *mysql_info, char* query)
00564 {
00565   int cr, err;
00566   int (*my_syslog)(const char *file, const char * fmt,...);
00567 
00568   if ((mysql_info->my_syslog != NULL) && (mysql_info->log_file[0] != 0))
00569   { my_syslog = mysql_info->my_syslog; }
00570   else { my_syslog = my_fake_syslog; }
00571   
00572   clear_error_reporting (mysql_info);
00573 
00574   /* ------------------------------------------------- */
00575   /* If connection is down, skip request OR try to     */
00576   /* reconnect.                                        */
00577   /* ------------------------------------------------- */
00578 
00579 
00580   #ifdef TEST_MYSQL_STANDART_QUERY
00581     fprintf (stdout, "Testing mysql.c::sql_select()\n");
00582     fprintf (stdout, "  Next action: <1> Test the connection state (UP/DOWN).\n");
00583     fprintf (stdout, "  Next action: <2> If status is DOWN, test the delay since last disconnection.\n");
00584     fprintf (stdout, "  Next action: <3> If status is DOWN, skip request or try to reconnect.\n");
00585     fprintf (stdout, "\n");
00586     fprintf (stdout, "  Press any key to continue.");
00587     getchar();
00588     fprintf (stdout, "\n\n");
00589   #endif
00590 
00591   if (! mysql_info->connected)
00592   {
00593     time_t delta = time(NULL) - mysql_info->last_connection_timestamp;
00594     if (mysql_info->reconnection_delay == 0) { delta = 0; }
00595 
00596     my_syslog (mysql_info->log_file,
00597                "[INFO] [%s:%d] MySql connection down since %u seconds", __FILE__, __LINE__, delta);
00598 
00599     if ((delta > mysql_info->reconnection_delay) || (mysql_info->reconnection_delay == 0))
00600     {
00601          my_syslog (mysql_info->log_file,
00602                     "[INFO] [%s:%d] %u > %u => Try to reconnect",
00603                     __FILE__, __LINE__,
00604                     delta, mysql_info->reconnection_delay);
00605                  
00606 
00607          /* ------------------------------------------ */
00608          /* Try to reconnect                           */
00609          /* ------------------------------------------ */
00610 
00611          disconnect_from_mysql (mysql_info);
00612          if (connect_to_mysql(mysql_info) == 1)
00613          {
00614            my_syslog (mysql_info->log_file,
00615            "[WARNING] [%s:%d] Could not reconnect to MySql", __FILE__, __LINE__);
00616 
00617            /* ------------------------------------------- */
00618            /* Connection to the server is down            */
00619            /* ------------------------------------------- */
00620 
00621            mysql_info->last_connection_timestamp = time(NULL);
00622            mysql_info->connected = 0;
00623 
00624            copy_error (mysql_info, "Could not reconnect to database");
00625            return MYSQL_RECONNECTION_FAILED;
00626          }
00627          else
00628          {
00629            mysql_info->last_connection_timestamp = 0;
00630            mysql_info->connected = 1;
00631          }
00632     }
00633     else {
00634            my_syslog (mysql_info->log_file,
00635            "[INFO] [%s:%d] %u < %u => Do not try to reconnect. Skip SQL request",
00636            __FILE__, __LINE__,
00637            delta, mysql_info->reconnection_delay);
00638 
00639            copy_error (mysql_info, "SQL request skiped (this is normal - see configuration)");
00640            return MYSQL_REQUEST_SKIPED;
00641          }
00642   }
00643 
00644   /* ------------------------------------------------- */
00645   /* At this point, the connection should be up        */
00646   /* ------------------------------------------------- */
00647 
00648   #ifdef TEST_MYSQL_STANDART_QUERY
00649     fprintf (stdout, "Testing mysql.c::sql_select()\n");
00650     fprintf (stdout, "  Next action: <1> Perform the SQL query.\n");
00651     fprintf (stdout, "\n");
00652     fprintf (stdout, "  Press any key to continue.");
00653     getchar();
00654     fprintf (stdout, "\n\n");
00655   #endif
00656 
00657   while (1)
00658   {
00659     mysql_info->num_fields = -1;
00660     mysql_info->num_rows   = -1;
00661 
00662     clear_error_reporting(mysql_info);
00663   
00664     /* ------------------------------------------------- */
00665     /* Make sure that we are connected                   */
00666     /* ------------------------------------------------- */
00667   
00668     if (mysql_info->handler == NULL) { set_last_error (mysql_info); return MYSQL_UNEXPECTED_ERROR; }
00669   
00670     /* ------------------------------------------------- */
00671     /* Send the request to mysql server                  */
00672     /* ------------------------------------------------- */
00673   
00674     cr = mysql_query(mysql_info->handler, query);
00675     if (cr != 0)
00676     {
00677       set_last_error (mysql_info);
00678 
00679        my_syslog (mysql_info->log_file,
00680        "[INFO] [%s:%d] Query [%s] failed: %s (%d -- CR_SERVER_GONE_ERROR=%d, CR_SERVER_LOST=%d, CR_CONNECTION_ERROR=%d, ER_SERVER_SHUTDOWN=%d)",
00681                   __FILE__, __LINE__,
00682                   query,
00683                   mysql_info->last_error_str,
00684                   mysql_info->last_error_int,
00685                   CR_SERVER_GONE_ERROR,
00686                   CR_SERVER_LOST,
00687                   CR_CONNECTION_ERROR,
00688                   ER_SERVER_SHUTDOWN);
00689 
00690       /* ----------------------------------------------- */
00691       /* The server may have gone away                   */
00692       /* ----------------------------------------------- */
00693 
00694       err = mysql_errno(mysql_info->handler);
00695 
00696       if ((err == CR_SERVER_GONE_ERROR) || (err == CR_SERVER_LOST) || (err == CR_CONNECTION_ERROR) ||
00697           (err == ER_SERVER_SHUTDOWN))
00698       {
00699          my_syslog (mysql_info->log_file,
00700          "[WARNING] [%s:%d] Connection lost with MySql server", __FILE__, __LINE__);
00701 
00702          disconnect_from_mysql (mysql_info);
00703          if (connect_to_mysql(mysql_info) == 1)
00704          {
00705            my_syslog (mysql_info->log_file,
00706            "[WARNING] [%s:%d] Could not reconnect to MySql", __FILE__, __LINE__);
00707 
00708            /* ------------------------------------------- */
00709            /* Connection to the server is down            */
00710            /* ------------------------------------------- */
00711 
00712            mysql_info->last_connection_timestamp = time(NULL);
00713            mysql_info->connected = 0;
00714 
00715            copy_error (mysql_info, "Could not reconnect to the database");
00716            return MYSQL_RECONNECTION_FAILED;
00717          }
00718 
00719          my_syslog (mysql_info->log_file,
00720          "[INFO] [%s:%d] Connection successfully established with MySql", __FILE__, __LINE__);
00721 
00722          mysql_info->last_connection_timestamp = time(NULL);
00723          mysql_info->connected = 0;
00724 
00725          continue;
00726       }
00727       else {
00728               my_syslog (mysql_info->log_file,
00729               "[INFO] [%s:%d] Some SQL error occured", __FILE__, __LINE__);
00730 
00731               set_last_error (mysql_info);
00732               return MYSQL_SQL_PROBLEM;
00733            }
00734     }
00735 
00736     break;
00737   }
00738 
00739   /* ------------------------------------------------- */
00740   /* Get selected data                                 */
00741   /* ------------------------------------------------- */
00742 
00743   mysql_info->result = mysql_store_result(mysql_info->handler);
00744   if (mysql_info->result)
00745   {
00746     mysql_info->num_rows   = mysql_num_rows   (mysql_info->result);
00747     mysql_info->num_fields = mysql_num_fields (mysql_info->result);
00748   }
00749   else
00750   { set_last_error (mysql_info); return MYSQL_UNEXPECTED_ERROR; }
00751 
00752   return mysql_info->num_rows;
00753 }
00754 
00755 /*! \brief Load MySql configuration from a given configuration file.
00756     \author Denis BEURIVE
00757     \param path Path to the configuration file to parse.
00758     \param mysql_info Pointer to a MySql configuration data structure unsed to store the loaded configuration.
00759     \param tags Pointer to an array of zero terminated strinfs of characters. Each string represents one tag
00760            to load from the configuration file. Tags must be written in the following order:
00761            <UL>
00762               <LI>0  - Host name of the server that runs the database server.
00763               <LI>1  - User used to log to the database server.
00764               <LI>2  - Password used to log to the database server.
00765               <LI>3  - Name of the database.
00766               <LI>4  - TCP port number use to connect to the database server.
00767               <LI>5  - Path to the UNIX socket used for local connection to the database server.
00768               <LI>6  - Number of connection retry.
00769               <LI>7  - Connection timeout in seconds.
00770               <LI>8  - Delay of inactivity between 2 connection attempts.
00771               <LI>9  - Debug verbosity level.
00772               <LI>10 - Path to the log file used to log debug messages.
00773               <LI>11 - Number of seconds between 2 reconnection attempts.
00774            </UL><P>
00775            The size of the array is MYSQL_CONFIGURATION_TAG_NUMBER.
00776     \param logger Pointer to a logging function used to log message, if required. The function' signature 
00777            must be:<P>
00778            int (*logger) (const char *file, const char * fmt,...)<P>
00779            If NULL, then logging is not activated (no matter if a log file is defined).
00780     \return Upon successful completion, the function returns the value 0.
00781             Otherwize, the function returns the value 1.
00782     \warning If you do not want to specify a log file in the configuration file, then set the value of the
00783              tag "log-file" (index 10 in the array 'tags') to "desactivate logs".
00784  */
00785 
00786 int load_mysql_configuration_from_file (
00787                                          char *path,
00788                                          struct smysql *mysql_info,
00789                                          char *tags[MYSQL_CONFIGURATION_TAG_NUMBER],
00790                                          int (*logger) (const char *file, const char * fmt,...)
00791                                        )
00792 {
00793   int   res, e;
00794   char  *value;
00795   int   (*my_syslog)(const char *file, const char * fmt,...);
00796 
00797   /* ------------------------------------------------- */
00798   /* Manage logging service                            */
00799   /* ------------------------------------------------- */
00800 
00801   mysql_set_logger (logger, mysql_info);
00802 
00803   /* ------------------------------------------------- */
00804   /* Clear error reporting service                     */
00805   /* ------------------------------------------------- */
00806 
00807   clear_error_reporting(mysql_info);
00808 
00809   /* ------------------------------------------------- */
00810   /* Load the configuration file into memory           */
00811   /* ------------------------------------------------- */
00812 
00813   if (parse_configuration_file (path, &e) != PARSE_CONFIGURATION_OK)
00814   {
00815     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00816               "Could not load the configuration file <%s> - %s",
00817               path,
00818               strerror(e));
00819     return 1;
00820   }
00821 
00822   /* ------------------------------------------------- */
00823   /* Set defaults                                      */
00824   /* ------------------------------------------------- */
00825 
00826   memset ((void*)mysql_info->host,      0, DB_HOST_MAX_SIZE);
00827   memset ((void*)mysql_info->user,      0, DB_USER_MAX_SIZE);
00828   memset ((void*)mysql_info->passwd,    0, DB_PASSWD_MAX_SIZE);
00829   memset ((void*)mysql_info->db,        0, DB_NAME_MAX_SIZE);
00830   memset ((void*)mysql_info->socket,    0, MYSQL_SOCKET_FILE_MAX_SIZE);
00831   memset ((void*)mysql_info->log_file,  0, MYSQL_DEBUG_FILE_MAX_SIZE);
00832 
00833   mysql_info->port               = 0;
00834   mysql_info->connect_retry      = 0;
00835   mysql_info->connect_timeout    = 0;
00836   mysql_info->connect_sleep      = 0;
00837   mysql_info->debug              = 0;
00838   mysql_info->reconnection_delay = 0;
00839 
00840   /* ------------------------------------------------- */
00841   /* Get the Host name                                 */
00842   /* ------------------------------------------------- */
00843 
00844   res = get_value (tags[0], &value);
00845 
00846   if (res == 0)
00847   {
00848     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00849               "<%s>: tag '%s' is missing",
00850               path,
00851               tags[0]);
00852     return 1;
00853   }
00854 
00855   if (res == -1)
00856   {
00857     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00858              "<%s>: Unexpected error while checking tag '%s'",
00859              path,
00860              tags[0]);
00861     return 1;
00862   }
00863 
00864   if (strlen(value) >= DB_HOST_MAX_SIZE)
00865   {
00866     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00867              "<%s>: Tag '%s' is too long (buffer overflow avoided!)",
00868              path,
00869              tags[0]);
00870     return 1;
00871   }
00872 
00873   strcpy (mysql_info->host, value);
00874 
00875   /* ------------------------------------------------- */
00876   /* Get the user name                                 */
00877   /* ------------------------------------------------- */
00878 
00879   res = get_value (tags[1], &value);
00880 
00881   if (res == 0)
00882   {
00883     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00884               "<%s>: tag '%s' is missing",
00885               path,
00886               tags[1]);
00887     return 1;
00888   }
00889 
00890   if (res == -1)
00891   {
00892     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00893              "<%s>: Unexpected error while checking tag '%s'",
00894              path,
00895              tags[1]);
00896     return 1;
00897   }
00898 
00899   if (strlen(value) >= DB_USER_MAX_SIZE)
00900   {
00901     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00902              "<%s>: Tag '%s' is too long (buffer overflow avoided!)",
00903              path,
00904              tags[1]);
00905     return 1;
00906   }
00907 
00908   strcpy (mysql_info->user, value);
00909 
00910   /* ------------------------------------------------- */
00911   /* Get the password                                  */
00912   /* ------------------------------------------------- */
00913 
00914   res = get_value (tags[2], &value);
00915 
00916   if (res == 0)
00917   {
00918     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00919               "<%s>: tag '%s' is missing",
00920               path,
00921               tags[2]);
00922     return 1;
00923   }
00924 
00925   if (res == -1)
00926   {
00927     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00928              "<%s>: Unexpected error while checking tag '%s'",
00929              path,
00930              tags[2]);
00931     return 1;
00932   }
00933 
00934   if (strlen(value) >= DB_PASSWD_MAX_SIZE)
00935   {
00936     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00937              "<%s>: Tag '%s' is too long (buffer overflow avoided!)",
00938              path,
00939              tags[2]);
00940     return 1;
00941   }
00942 
00943   strcpy (mysql_info->passwd, value);
00944 
00945   /* ------------------------------------------------- */
00946   /* Get the database name                             */
00947   /* ------------------------------------------------- */
00948 
00949   res = get_value (tags[3], &value);
00950 
00951   if (res == 0)
00952   {
00953     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00954               "<%s>: tag '%s' is missing",
00955               path,
00956               tags[3]);
00957     return 1;
00958   }
00959 
00960   if (res == -1)
00961   {
00962     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00963              "<%s>: Unexpected error while checking tag '%s'",
00964              path,
00965              tags[3]);
00966     return 1;
00967   }
00968 
00969   if (strlen(value) >= DB_NAME_MAX_SIZE)
00970   {
00971     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00972              "<%s>: Tag '%s' is too long (buffer overflow avoided!)",
00973              path,
00974              tags[3]);
00975     return 1;
00976   }
00977 
00978   strcpy (mysql_info->db, value);
00979 
00980   /* ------------------------------------------------- */
00981   /* Get the TCP port number                           */
00982   /* ------------------------------------------------- */
00983 
00984   res = get_value (tags[4], &value);
00985 
00986   if (res == 0)
00987   {
00988     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00989               "<%s>: tag '%s' is missing",
00990               path,
00991               tags[4]);
00992     return 1;
00993   }
00994 
00995   if (res == -1)
00996   {
00997     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
00998              "<%s>: Unexpected error while checking tag '%s'",
00999              path,
01000              tags[4]);
01001     return 1;
01002   }
01003 
01004   mysql_info->port = atoi(value);
01005 
01006   /* ------------------------------------------------- */
01007   /* Get the UNIX socket path                          */
01008   /* ------------------------------------------------- */
01009 
01010   res = get_value (tags[5], &value);
01011 
01012   if (res == 0)
01013   {
01014     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01015               "<%s>: tag '%s' is missing",
01016               path,
01017               tags[5]);
01018     return 1;
01019   }
01020 
01021   if (res == -1)
01022   {
01023     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01024              "<%s>: Unexpected error while checking tag '%s'",
01025              path,
01026              tags[5]);
01027     return 1;
01028   }
01029 
01030   if (strlen(value) >= MYSQL_SOCKET_FILE_MAX_SIZE)
01031   {
01032     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01033              "<%s>: Tag '%s' is too long (buffer overflow avoided!)",
01034              path,
01035              tags[5]);
01036     return 1;
01037   }
01038 
01039   strcpy (mysql_info->socket, value);
01040 
01041   /* ------------------------------------------------- */
01042   /* Get number of connect retries                     */
01043   /* ------------------------------------------------- */
01044 
01045   res = get_value (tags[6], &value);
01046 
01047   if (res == 0)
01048   {
01049     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01050               "<%s>: tag '%s' is missing",
01051               path,
01052               tags[6]);
01053     return 1;
01054   }
01055 
01056   if (res == -1)
01057   {
01058     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01059              "<%s>: Unexpected error while checking tag '%s'",
01060              path,
01061              tags[6]);
01062     return 1;
01063   }
01064 
01065   mysql_info->connect_retry = atoi(value);
01066 
01067   /* ------------------------------------------------- */
01068   /* Get the connect timout                            */
01069   /* ------------------------------------------------- */
01070 
01071   res = get_value (tags[7], &value);
01072 
01073   if (res == 0)
01074   {
01075     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01076               "<%s>: tag '%s' is missing",
01077               path,
01078               tags[7]);
01079     return 1;
01080   }
01081 
01082   if (res == -1)
01083   {
01084     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01085              "<%s>: Unexpected error while checking tag '%s'",
01086              path,
01087              tags[7]);
01088     return 1;
01089   }
01090 
01091   mysql_info->connect_timeout = atoi(value);
01092 
01093   /* ------------------------------------------------- */
01094   /* Get the inactivity period between 2 connections   */
01095   /* ------------------------------------------------- */
01096 
01097   res = get_value (tags[8], &value);
01098 
01099   if (res == 0)
01100   {
01101     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01102               "<%s>: tag '%s' is missing",
01103               path,
01104               tags[8]);
01105     return 1;
01106   }
01107 
01108   if (res == -1)
01109   {
01110     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01111              "<%s>: Unexpected error while checking tag '%s'",
01112              path,
01113              tags[8]);
01114     return 1;
01115   }
01116 
01117   mysql_info->connect_sleep = atoi(value);
01118 
01119   /* ------------------------------------------------- */
01120   /* Get the debug verbosity level                     */
01121   /* ------------------------------------------------- */
01122 
01123   res = get_value (tags[9], &value);
01124 
01125   if (res == 0)
01126   {
01127     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01128               "<%s>: tag '%s' is missing",
01129               path,
01130               tags[9]);
01131     return 1;
01132   }
01133 
01134   if (res == -1)
01135   {
01136     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01137              "<%s>: Unexpected error while checking tag '%s'",
01138              path,
01139              tags[9]);
01140     return 1;
01141   }
01142 
01143   mysql_info->debug = atoi(value);
01144 
01145   /* ------------------------------------------------- */
01146   /* Get the path to the log file                      */
01147   /* ------------------------------------------------- */
01148 
01149   res = get_value (tags[10], &value);
01150 
01151   if (res == 0)
01152   {
01153     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01154               "<%s>: tag '%s' is missing",
01155               path,
01156               tags[10]);
01157     return 1;
01158   }
01159 
01160   if (res == -1)
01161   {
01162     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01163              "<%s>: Unexpected error while checking tag '%s'",
01164              path,
01165              tags[10]);
01166     return 1;
01167   }
01168 
01169   if (strlen(value) >= MYSQL_DEBUG_FILE_MAX_SIZE)
01170   {
01171     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01172              "<%s>: Tag '%s' is too long (buffer overflow avoided!)",
01173              path,
01174              tags[10]);
01175     return 1;
01176   }
01177 
01178   if ((strcmp(value, "desactivate logs") != 0) || (mysql_info->debug == 0))
01179      { strcpy (mysql_info->log_file, value); }
01180 
01181   /* ------------------------------------------------- */
01182   /* Get the reconnection delay                        */
01183   /* ------------------------------------------------- */
01184 
01185   res = get_value (tags[11], &value);
01186 
01187   if (res == 0)
01188   {
01189     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01190               "<%s>: tag '%s' is missing",
01191               path,
01192               tags[11]);
01193     return 1;
01194   }
01195 
01196   if (res == -1)
01197   {
01198     snprintf (mysql_info->last_error_str, MYSQL_MAX_ERROR_SIZE,
01199              "<%s>: Unexpected error while checking tag '%s'",
01200              path,
01201              tags[11]);
01202     return 1;
01203   }
01204 
01205   mysql_info->reconnection_delay = atoi(value);
01206 
01207   /* ------------------------------------------------- */
01208   /* Log DEBUG data, if required                       */
01209   /* ------------------------------------------------- */
01210 
01211   if ((mysql_info->my_syslog != NULL) && (mysql_info->log_file[0] != 0))
01212   { my_syslog = mysql_info->my_syslog; }
01213   else { my_syslog = my_fake_syslog; }
01214 
01215   if (mysql_info->debug > 0)
01216   {
01217     char big_buffer[8000];
01218 
01219     snprintf (big_buffer, 8000,
01220               "host='%s', user='%s', passwd='%s', dbname='%s', port='%u', socket='%s', connect_retry='%d', connect_timeout='%d', connect_sleep='%d', debug='%d', log_file='%s', reconnection_delay='%lu'",
01221               mysql_info->host,
01222               mysql_info->user,
01223               mysql_info->passwd,
01224               mysql_info->db,
01225               mysql_info->port,
01226               mysql_info->socket,
01227               mysql_info->connect_retry,
01228               mysql_info->connect_timeout,
01229               mysql_info->connect_sleep,
01230               mysql_info->debug,
01231               mysql_info->log_file,
01232               mysql_info->reconnection_delay);
01233 
01234     my_syslog (mysql_info->log_file, "[DEBUG] [%s:%d] %s",
01235                __FILE__, __LINE__,
01236                big_buffer);
01237   }
01238 
01239   return 0;
01240 }
01241 
01242 /*! \brief Return the UNIX timestamp of the MySql server.
01243     \author Denis BEURIVE
01244     \param mysql_info Pointer to a 'struct smysql' that contains the Mysql configuration.
01245     \param error Pointer to an integer used to store an error code.
01246            Upon successful completion, the value pointed by 'error' is set to 0. 
01247            Otherwise, the value pointed by 'error' could be:
01248            <UL>
01249               <LI>MYSQL_REQUEST_SKIPED
01250               <LI>MYSQL_CONNECTION_LOST
01251               <LI>MYSQL_RECONNECTION_FAILED
01252               <LI>MYSQL_SQL_PROBLEM
01253               <LI>MYSQL_UNEXPECTED_ERROR
01254               <LI>MYSQL_NO_TIMESTAMP
01255            </UL>
01256     \return Upon successful completion (the value pointed by 'error' is set to 0), then the function
01257             returns the current UNIX timestamp of the MySql server. Otherwize, the function returns the
01258             value 0.
01259  */
01260 
01261 time_t get_unix_timestamp (struct smysql *mysql_info, int *error)
01262 {
01263   char               sql[] = "select UNIX_TIMESTAMP(now())";
01264   char               integer1[32];
01265   int                n, e;
01266   MYSQL_ROW          row;
01267   unsigned long int  *length;
01268   time_t             ttstp;
01269   int                (*my_syslog)(const char *file, const char * fmt,...);
01270 
01271   if ((mysql_info->my_syslog != NULL) && (mysql_info->log_file[0] != 0))
01272   { my_syslog = mysql_info->my_syslog; }
01273   else { my_syslog = my_fake_syslog; }
01274 
01275 
01276 
01277   if (mysql_info->debug > 1)
01278   { my_syslog (mysql_info->log_file, "[DEBUG] [%s,%d] SQL '%s'", __FILE__, __LINE__, sql); }
01279 
01280   *error = 0;
01281 
01282   /* ----------------------------------------------------- */
01283   /* Send request to MySql server                          */
01284   /* ----------------------------------------------------- */
01285 
01286   n = sql_select (mysql_info, sql);
01287 
01288   switch (n)
01289   {
01290     case MYSQL_REQUEST_SKIPED:
01291          my_syslog (mysql_info->log_file, "[WARNING] [%s,%d] Request skiped", __FILE__, __LINE__);
01292          *error = MYSQL_REQUEST_SKIPED;
01293          return 0;
01294     case MYSQL_CONNECTION_LOST:
01295          my_syslog (mysql_info->log_file, "[WARNING] [%s,%d] Coonection lost", __FILE__, __LINE__);
01296          *error = MYSQL_CONNECTION_LOST;
01297          return 0;
01298     case MYSQL_RECONNECTION_FAILED:
01299          my_syslog (mysql_info->log_file, "[WARNING] [%s,%d] Could not reconnect", __FILE__, __LINE__);
01300          *error = MYSQL_RECONNECTION_FAILED;
01301          return 0;
01302     case MYSQL_SQL_PROBLEM:
01303          my_syslog (mysql_info->log_file, "[ERROR] [%s,%d] Some SQL error", __FILE__, __LINE__);
01304          *error = MYSQL_SQL_PROBLEM; 
01305          return 0;
01306     case MYSQL_UNEXPECTED_ERROR:
01307          my_syslog (mysql_info->log_file, "[ERROR] [%s,%d] Unexpected error", __FILE__, __LINE__);
01308          *error = MYSQL_UNEXPECTED_ERROR;
01309          return 0;
01310     case 0:
01311          my_syslog (mysql_info->log_file, "[ERROR] [%s,%d] Could not get UNIX timestamp", __FILE__, __LINE__);
01312          *error = MYSQL_NO_TIMESTAMP;
01313          mysql_free_result(mysql_info->result);
01314          return 0;
01315   }
01316 
01317   if (mysql_info->debug > 1)
01318   { my_syslog (mysql_info->log_file, "[DEBUG] [%s,%d] Got %d result(s)", __FILE__, __LINE__, n); }
01319 
01320   /* ----------------------------------------------------- */
01321   /* Copy the result                                       */
01322   /* ----------------------------------------------------- */
01323 
01324   row    = mysql_fetch_row (mysql_info->result);
01325   length = mysql_fetch_lengths (mysql_info->result);
01326 
01327   if (mysql_info->debug > 1)
01328   {
01329     my_syslog (mysql_info->log_file,
01330     "[DEBUG] [%s,%d] Lengthes are: timestamp[%d]",
01331     __FILE__, __LINE__,
01332     length[0]);
01333   }
01334 
01335   memset ((void*)integer1, 0, 32);
01336   memcpy ((void*)integer1, (void*)row[0],
01337           (length[0] < 32) ? length[0] : 31);
01338 
01339   ttstp = (time_t)(string2unsigned_int (integer1, &e));
01340 
01341   mysql_free_result(mysql_info->result);
01342   return ttstp;
01343 }
01344 
01345 
01346 
01347 

Generated on Mon Jun 19 12:31:06 2006 for MyDhcp_V2 by doxygen1.2.15