Mon Apr 30 07:46:02 2007

Asterisk developer's documentation


res_config_mysql.c File Reference

#include <asterisk.h>
#include <asterisk/channel.h>
#include <asterisk/logger.h>
#include <asterisk/config.h>
#include <asterisk/module.h>
#include <asterisk/lock.h>
#include <asterisk/options.h>
#include <asterisk/cli.h>
#include <asterisk/utils.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <mysql/mysql.h>
#include <mysql/mysql_version.h>
#include <mysql/errmsg.h>

Include dependency graph for res_config_mysql.c:

Go to the source code of this file.

Defines

#define AST_MODULE   "res_config_mysql"
#define RES_CONFIG_MYSQL_CONF   "res_mysql.conf"

Functions

 AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"MySQL RealTime Configuration Driver")
 AST_MUTEX_DEFINE_STATIC (mysql_lock)
static struct ast_configconfig_mysql (const char *database, const char *table, const char *file, struct ast_config *cfg, int withcomments)
static int load_module (void)
static int mysql_reconnect (const char *database)
static int parse_config (void)
static struct ast_configrealtime_multi_mysql (const char *database, const char *table, va_list ap)
static struct ast_variablerealtime_mysql (const char *database, const char *table, va_list ap)
static int realtime_mysql_status (int fd, int argc, char **argv)
static int reload (void)
static int unload_module (void)
static int update_mysql (const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap)

Variables

static struct ast_cli_entry cli_realtime_mysql_status
static char cli_realtime_mysql_status_usage []
static time_t connect_time
static int connected
static char dbhost [50]
static char dbname [50]
static char dbpass [50]
static int dbport
static char dbsock [50]
static char dbuser [50]
MYSQL mysql
static struct ast_config_engine mysql_engine


Define Documentation

#define AST_MODULE   "res_config_mysql"

Definition at line 62 of file res_config_mysql.c.

#define RES_CONFIG_MYSQL_CONF   "res_mysql.conf"

Definition at line 65 of file res_config_mysql.c.

Referenced by config_mysql(), and parse_config().


Function Documentation

AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY  ,
"MySQL RealTime Configuration Driver"   
)

AST_MUTEX_DEFINE_STATIC ( mysql_lock   ) 

static struct ast_config* config_mysql ( const char *  database,
const char *  table,
const char *  file,
struct ast_config cfg,
int  withcomments 
) [static]

Definition at line 386 of file res_config_mysql.c.

References ast_category_append(), ast_category_new(), ast_config_internal_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_variable_append(), ast_variable_new(), last, LOG_DEBUG, LOG_WARNING, mysql, mysql_reconnect(), RES_CONFIG_MYSQL_CONF, and result.

00387 {
00388    MYSQL_RES *result;
00389    MYSQL_ROW row;
00390    my_ulonglong num_rows;
00391    struct ast_variable *new_v;
00392    struct ast_category *cur_cat;
00393    char sql[250] = "";
00394    char last[80] = "";
00395    int last_cat_metric = 0;
00396 
00397    last[0] = '\0';
00398 
00399    if(!file || !strcmp(file, RES_CONFIG_MYSQL_CONF)) {
00400       ast_log(LOG_WARNING, "MySQL RealTime: Cannot configure myself.\n");
00401       return NULL;
00402    }
00403 
00404    snprintf(sql, sizeof(sql), "SELECT category, var_name, var_val, cat_metric FROM %s WHERE filename='%s' and commented=0 ORDER BY filename, cat_metric desc, var_metric asc, category, var_name, var_val, id", table, file);
00405 
00406    ast_log(LOG_DEBUG, "MySQL RealTime: Static SQL: %s\n", sql);
00407 
00408    /* We now have our complete statement; Lets connect to the server and execute it. */
00409    ast_mutex_lock(&mysql_lock);
00410    if(!mysql_reconnect(database)) {
00411       ast_mutex_unlock(&mysql_lock);
00412       return NULL;
00413    }
00414 
00415    if(mysql_real_query(&mysql, sql, strlen(sql))) {
00416       ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
00417       ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql);
00418       ast_log(LOG_DEBUG, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&mysql));
00419       ast_mutex_unlock(&mysql_lock);
00420       return NULL;
00421    }
00422 
00423    if((result = mysql_store_result(&mysql))) {
00424       num_rows = mysql_num_rows(result);
00425       ast_log(LOG_DEBUG, "MySQL RealTime: Found %llu rows.\n", num_rows);
00426 
00427       /* There might exist a better way to access the column names other than counting,
00428                    but I believe that would require another loop that we don't need. */
00429 
00430       while((row = mysql_fetch_row(result))) {
00431          if(!strcmp(row[1], "#include")) {
00432             if (!ast_config_internal_load(row[2], cfg, 0)) {
00433                mysql_free_result(result);
00434                ast_mutex_unlock(&mysql_lock);
00435                return NULL;
00436             }
00437             continue;
00438          }
00439 
00440          if(strcmp(last, row[0]) || last_cat_metric != atoi(row[3])) {
00441             cur_cat = ast_category_new(row[0]);
00442             if (!cur_cat) {
00443                ast_log(LOG_WARNING, "Out of memory!\n");
00444                break;
00445             }
00446             strcpy(last, row[0]);
00447             last_cat_metric = atoi(row[3]);
00448             ast_category_append(cfg, cur_cat);
00449          }
00450          new_v = ast_variable_new(row[1], row[2]);
00451          ast_variable_append(cur_cat, new_v);
00452       }
00453    } else {
00454       ast_log(LOG_WARNING, "MySQL RealTime: Could not find config '%s' in database.\n", file);
00455    }
00456 
00457    mysql_free_result(result);
00458    ast_mutex_unlock(&mysql_lock);
00459 
00460    return cfg;
00461 }

static int load_module ( void   )  [static]

Definition at line 471 of file res_config_mysql.c.

References ast_cli_register(), ast_config_engine_register(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), cli_realtime_mysql_status, LOG_DEBUG, LOG_WARNING, mysql, mysql_engine, mysql_reconnect(), option_verbose, and parse_config().

00472 {
00473    parse_config();
00474 
00475    ast_mutex_lock(&mysql_lock);
00476 
00477    if(!mysql_reconnect(NULL)) {
00478       ast_log(LOG_WARNING, "MySQL RealTime: Couldn't establish connection. Check debug.\n");
00479       ast_log(LOG_DEBUG, "MySQL RealTime: Cannot Connect: %s\n", mysql_error(&mysql));
00480    }
00481 
00482    ast_config_engine_register(&mysql_engine);
00483    if(option_verbose) {
00484       ast_verbose("MySQL RealTime driver loaded.\n");
00485    }
00486    ast_cli_register(&cli_realtime_mysql_status);
00487 
00488    ast_mutex_unlock(&mysql_lock);
00489 
00490    return 0;
00491 }

static int mysql_reconnect ( const char *  database  )  [static]

Definition at line 599 of file res_config_mysql.c.

References ast_log(), ast_strlen_zero(), connect_time, connected, dbhost, dbname, dbpass, dbport, dbsock, dbuser, LOG_DEBUG, LOG_ERROR, LOG_WARNING, and mysql.

Referenced by config_mysql(), load_module(), realtime_multi_mysql(), realtime_mysql(), realtime_mysql_status(), reload(), and update_mysql().

00600 {
00601    char my_database[50];
00602 #ifdef MYSQL_OPT_RECONNECT
00603    my_bool trueval = 1;
00604 #endif
00605 
00606    if(!database || ast_strlen_zero(database))
00607       ast_copy_string(my_database, dbname, sizeof(my_database));
00608    else
00609       ast_copy_string(my_database, database, sizeof(my_database));
00610 
00611    /* mutex lock should have been locked before calling this function. */
00612 
00613 reconnect_tryagain:
00614    if((!connected) && (dbhost || dbsock) && dbuser && dbpass && my_database) {
00615       if(!mysql_init(&mysql)) {
00616          ast_log(LOG_WARNING, "MySQL RealTime: Insufficient memory to allocate MySQL resource.\n");
00617          connected = 0;
00618          return 0;
00619       }
00620       if(mysql_real_connect(&mysql, dbhost, dbuser, dbpass, my_database, dbport, dbsock, 0)) {
00621 #ifdef MYSQL_OPT_RECONNECT
00622          /* The default is no longer to automatically reconnect on failure,
00623           * (as of 5.0.3) so we have to set that option here. */
00624          mysql_options(&mysql, MYSQL_OPT_RECONNECT, &trueval);
00625 #endif
00626          ast_log(LOG_DEBUG, "MySQL RealTime: Successfully connected to database.\n");
00627          connected = 1;
00628          connect_time = time(NULL);
00629          return 1;
00630       } else {
00631          ast_log(LOG_ERROR, "MySQL RealTime: Failed to connect database server %s on %s (err %d). Check debug for more info.\n", dbname, dbhost, mysql_errno(&mysql));
00632          ast_log(LOG_DEBUG, "MySQL RealTime: Cannot Connect (%d): %s\n", mysql_errno(&mysql), mysql_error(&mysql));
00633          connected = 0;
00634          return 0;
00635       }
00636    } else {
00637       /* MySQL likes to return an error, even if it reconnects successfully.
00638        * So the postman pings twice. */
00639       if (mysql_ping(&mysql) != 0 && mysql_ping(&mysql) != 0) {
00640          connected = 0;
00641          ast_log(LOG_ERROR, "MySQL RealTime: Ping failed (%d).  Trying an explicit reconnect.\n", mysql_errno(&mysql));
00642          ast_log(LOG_DEBUG, "MySQL RealTime: Server Error (%d): %s\n", mysql_errno(&mysql), mysql_error(&mysql));
00643          goto reconnect_tryagain;
00644       }
00645 
00646       connected = 1;
00647 
00648       if(mysql_select_db(&mysql, my_database) != 0) {
00649          ast_log(LOG_WARNING, "MySQL RealTime: Unable to select database: %s. Still Connected (%d).\n", my_database, mysql_errno(&mysql));
00650          ast_log(LOG_DEBUG, "MySQL RealTime: Database Select Failed (%d): %s\n", mysql_error(&mysql), mysql_errno(&mysql));
00651          return 0;
00652       }
00653 
00654       ast_log(LOG_DEBUG, "MySQL RealTime: Everything is fine.\n");
00655       return 1;
00656    }
00657 }

static int parse_config ( void   )  [static]

Definition at line 535 of file res_config_mysql.c.

References ast_config_destroy(), ast_config_load(), ast_log(), ast_variable_retrieve(), config, dbhost, dbname, dbpass, dbport, dbsock, dbuser, LOG_DEBUG, LOG_WARNING, RES_CONFIG_MYSQL_CONF, and s.

00536 {
00537    struct ast_config *config;
00538    const char *s;
00539 
00540    config = ast_config_load(RES_CONFIG_MYSQL_CONF);
00541 
00542    if(config) {
00543       if(!(s=ast_variable_retrieve(config, "general", "dbuser"))) {
00544          ast_log(LOG_WARNING, "MySQL RealTime: No database user found, using 'asterisk' as default.\n");
00545          strncpy(dbuser, "asterisk", sizeof(dbuser) - 1);
00546       } else {
00547          strncpy(dbuser, s, sizeof(dbuser) - 1);
00548       }
00549 
00550       if(!(s=ast_variable_retrieve(config, "general", "dbpass"))) {
00551                         ast_log(LOG_WARNING, "MySQL RealTime: No database password found, using 'asterisk' as default.\n");
00552                         strncpy(dbpass, "asterisk", sizeof(dbpass) - 1);
00553                 } else {
00554                         strncpy(dbpass, s, sizeof(dbpass) - 1);
00555                 }
00556 
00557       if(!(s=ast_variable_retrieve(config, "general", "dbhost"))) {
00558                         ast_log(LOG_WARNING, "MySQL RealTime: No database host found, using localhost via socket.\n");
00559          dbhost[0] = '\0';
00560                 } else {
00561                         strncpy(dbhost, s, sizeof(dbhost) - 1);
00562                 }
00563 
00564       if(!(s=ast_variable_retrieve(config, "general", "dbname"))) {
00565                         ast_log(LOG_WARNING, "MySQL RealTime: No database name found, using 'asterisk' as default.\n");
00566          strncpy(dbname, "asterisk", sizeof(dbname) - 1);
00567                 } else {
00568                         strncpy(dbname, s, sizeof(dbname) - 1);
00569                 }
00570 
00571       if(!(s=ast_variable_retrieve(config, "general", "dbport"))) {
00572                         ast_log(LOG_WARNING, "MySQL RealTime: No database port found, using 3306 as default.\n");
00573          dbport = 3306;
00574                 } else {
00575          dbport = atoi(s);
00576                 }
00577 
00578       if(dbhost && !(s=ast_variable_retrieve(config, "general", "dbsock"))) {
00579                         ast_log(LOG_WARNING, "MySQL RealTime: No database socket found, using '/tmp/mysql.sock' as default.\n");
00580                         strncpy(dbsock, "/tmp/mysql.sock", sizeof(dbsock) - 1);
00581                 } else {
00582                         strncpy(dbsock, s, sizeof(dbsock) - 1);
00583                 }
00584    }
00585    ast_config_destroy(config);
00586 
00587    if(dbhost) {
00588       ast_log(LOG_DEBUG, "MySQL RealTime Host: %s\n", dbhost);
00589       ast_log(LOG_DEBUG, "MySQL RealTime Port: %i\n", dbport);
00590    } else {
00591       ast_log(LOG_DEBUG, "MySQL RealTime Socket: %s\n", dbsock);
00592    }
00593    ast_log(LOG_DEBUG, "MySQL RealTime User: %s\n", dbuser);
00594    ast_log(LOG_DEBUG, "MySQL RealTime Password: %s\n", dbpass);
00595 
00596    return 1;
00597 }

static struct ast_config* realtime_multi_mysql ( const char *  database,
const char *  table,
va_list  ap 
) [static]

Definition at line 185 of file res_config_mysql.c.

References ast_category_append(), ast_category_new(), ast_category_rename(), ast_config_new(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_strlen_zero(), ast_variable_append(), ast_variable_new(), LOG_DEBUG, LOG_WARNING, mysql, mysql_reconnect(), name, result, strsep(), and var.

00186 {
00187    MYSQL_RES *result;
00188    MYSQL_ROW row;
00189    MYSQL_FIELD *fields;
00190    int numFields, i, valsz;
00191    char sql[512];
00192    char buf[511]; /* Keep this size uneven as it is 2n+1. */
00193    const char *initfield = NULL;
00194    char *stringp;
00195    char *chunk;
00196    char *op;
00197    const char *newparam, *newval;
00198    struct ast_realloca ra;
00199    struct ast_variable *var=NULL;
00200    struct ast_config *cfg = NULL;
00201    struct ast_category *cat = NULL;
00202 
00203    if(!table) {
00204       ast_log(LOG_WARNING, "MySQL RealTime: No table specified.\n");
00205       return NULL;
00206    }
00207    
00208    memset(&ra, 0, sizeof(ra));
00209 
00210    cfg = ast_config_new();
00211    if (!cfg) {
00212       /* If I can't alloc memory at this point, why bother doing anything else? */
00213       ast_log(LOG_WARNING, "Out of memory!\n");
00214       return NULL;
00215    }
00216 
00217    /* Get the first parameter and first value in our list of passed paramater/value pairs */
00218    newparam = va_arg(ap, const char *);
00219    newval = va_arg(ap, const char *);
00220    if(!newparam || !newval)  {
00221       ast_log(LOG_WARNING, "MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
00222       mysql_close(&mysql);
00223       return NULL;
00224    }
00225 
00226    initfield = ast_strdupa(newparam);
00227    if(initfield && (op = strchr(initfield, ' '))) {
00228       *op = '\0';
00229    }
00230 
00231    /* Must connect to the server before anything else, as the escape function requires the mysql handle. */
00232    ast_mutex_lock(&mysql_lock);
00233    if (!mysql_reconnect(database)) {
00234       ast_mutex_unlock(&mysql_lock);
00235       return NULL;
00236    }
00237 
00238    /* Create the first part of the query using the first parameter/value pairs we just extracted
00239       If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
00240 
00241    if(!strchr(newparam, ' ')) op = " ="; else op = "";
00242 
00243    if ((valsz = strlen (newval)) * 2 + 1 > sizeof(buf))
00244       valsz = (sizeof(buf) - 1) / 2;
00245    mysql_real_escape_string(&mysql, buf, newval, valsz);
00246    snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, buf);
00247    while((newparam = va_arg(ap, const char *))) {
00248       newval = va_arg(ap, const char *);
00249       if(!strchr(newparam, ' ')) op = " ="; else op = "";
00250       if ((valsz = strlen (newval)) * 2 + 1 > sizeof(buf))
00251          valsz = (sizeof(buf) - 1) / 2;
00252       mysql_real_escape_string(&mysql, buf, newval, valsz);
00253       snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, op, buf);
00254    }
00255 
00256    if(initfield) {
00257       snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " ORDER BY %s", initfield);
00258    }
00259 
00260    va_end(ap);
00261 
00262    ast_log(LOG_DEBUG, "MySQL RealTime: Retrieve SQL: %s\n", sql);
00263 
00264    /* Execution. */
00265    if(mysql_real_query(&mysql, sql, strlen(sql))) {
00266       ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
00267       ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql);
00268       ast_log(LOG_DEBUG, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&mysql));
00269       ast_mutex_unlock(&mysql_lock);
00270       return NULL;
00271    }
00272 
00273    if((result = mysql_store_result(&mysql))) {
00274       numFields = mysql_num_fields(result);
00275       fields = mysql_fetch_fields(result);
00276 
00277       while((row = mysql_fetch_row(result))) {
00278          var = NULL;
00279          cat = ast_category_new("");
00280          if(!cat) {
00281             ast_log(LOG_WARNING, "Out of memory!\n");
00282             continue;
00283          }
00284          for(i = 0; i < numFields; i++) {
00285             stringp = row[i];
00286             while(stringp) {
00287                chunk = strsep(&stringp, ";");
00288                if(chunk && !ast_strlen_zero(ast_strip(chunk))) {
00289                   if(initfield && !strcmp(initfield, fields[i].name)) {
00290                      ast_category_rename(cat, chunk);
00291                   }
00292                   var = ast_variable_new(fields[i].name, chunk);
00293                   ast_variable_append(cat, var);
00294                }
00295             }
00296          }
00297          ast_category_append(cfg, cat);
00298       }
00299    } else {
00300       ast_log(LOG_WARNING, "MySQL RealTime: Could not find any rows in table %s.\n", table);
00301    }
00302 
00303    ast_mutex_unlock(&mysql_lock);
00304    mysql_free_result(result);
00305 
00306    return cfg;
00307 }

static struct ast_variable* realtime_mysql ( const char *  database,
const char *  table,
va_list  ap 
) [static]

Definition at line 88 of file res_config_mysql.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_variable_new(), LOG_DEBUG, LOG_WARNING, mysql, mysql_reconnect(), name, ast_variable::next, result, strsep(), and var.

00089 {
00090    MYSQL_RES *result;
00091    MYSQL_ROW row;
00092    MYSQL_FIELD *fields;
00093    int numFields, i, valsz;
00094    char sql[512];
00095    char buf[511]; /* Keep this size uneven as it is 2n+1. */
00096    char *stringp;
00097    char *chunk;
00098    char *op;
00099    const char *newparam, *newval;
00100    struct ast_variable *var=NULL, *prev=NULL;
00101 
00102    if(!table) {
00103       ast_log(LOG_WARNING, "MySQL RealTime: No table specified.\n");
00104       return NULL;
00105    }
00106 
00107    /* Get the first parameter and first value in our list of passed paramater/value pairs */
00108    newparam = va_arg(ap, const char *);
00109    newval = va_arg(ap, const char *);
00110    if(!newparam || !newval)  {
00111       ast_log(LOG_WARNING, "MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
00112       mysql_close(&mysql);
00113       return NULL;
00114    }
00115 
00116    /* Must connect to the server before anything else, as the escape function requires the mysql handle. */
00117    ast_mutex_lock(&mysql_lock);
00118    if (!mysql_reconnect(database)) {
00119       ast_mutex_unlock(&mysql_lock);
00120       return NULL;
00121    }
00122 
00123    /* Create the first part of the query using the first parameter/value pairs we just extracted
00124       If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
00125 
00126    if(!strchr(newparam, ' ')) op = " ="; else op = "";
00127 
00128    if ((valsz = strlen (newval)) * 2 + 1 > sizeof(buf))
00129       valsz = (sizeof(buf) - 1) / 2;
00130    mysql_real_escape_string(&mysql, buf, newval, valsz);
00131    snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, buf);
00132    while((newparam = va_arg(ap, const char *))) {
00133       newval = va_arg(ap, const char *);
00134       if(!strchr(newparam, ' ')) op = " ="; else op = "";
00135       if ((valsz = strlen (newval)) * 2 + 1 > sizeof(buf))
00136          valsz = (sizeof(buf) - 1) / 2;
00137       mysql_real_escape_string(&mysql, buf, newval, valsz);
00138       snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, op, buf);
00139    }
00140    va_end(ap);
00141 
00142    ast_log(LOG_DEBUG, "MySQL RealTime: Retrieve SQL: %s\n", sql);
00143 
00144    /* Execution. */
00145    if(mysql_real_query(&mysql, sql, strlen(sql))) {
00146       ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
00147       ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql);
00148       ast_log(LOG_DEBUG, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&mysql));
00149       ast_mutex_unlock(&mysql_lock);
00150       return NULL;
00151    }
00152 
00153    if((result = mysql_store_result(&mysql))) {
00154       numFields = mysql_num_fields(result);
00155       fields = mysql_fetch_fields(result);
00156 
00157       while((row = mysql_fetch_row(result))) {
00158          for(i = 0; i < numFields; i++) {
00159             stringp = row[i];
00160             while(stringp) {
00161                chunk = strsep(&stringp, ";");
00162                if(chunk && !ast_strlen_zero(ast_strip(chunk))) {
00163                   if(prev) {
00164                      prev->next = ast_variable_new(fields[i].name, chunk);
00165                      if (prev->next) {
00166                         prev = prev->next;
00167                      }
00168                   } else {
00169                      prev = var = ast_variable_new(fields[i].name, chunk);
00170                   }
00171                }
00172             }
00173          }
00174       }
00175    } else {                                
00176       ast_log(LOG_WARNING, "MySQL RealTime: Could not find any rows in table %s.\n", table);
00177    }
00178 
00179    ast_mutex_unlock(&mysql_lock);
00180    mysql_free_result(result);
00181 
00182    return var;
00183 }

static int realtime_mysql_status ( int  fd,
int  argc,
char **  argv 
) [static]

Definition at line 659 of file res_config_mysql.c.

References ast_cli(), connect_time, dbhost, dbname, dbport, dbsock, dbuser, mysql_reconnect(), RESULT_FAILURE, and RESULT_SUCCESS.

00660 {
00661    char status[256], status2[100] = "";
00662    int ctime = time(NULL) - connect_time;
00663 
00664    if(mysql_reconnect(NULL)) {
00665       if(dbhost) {
00666          snprintf(status, 255, "Connected to %s@%s, port %d", dbname, dbhost, dbport);
00667       } else if(dbsock) {
00668          snprintf(status, 255, "Connected to %s on socket file %s", dbname, dbsock);
00669       } else {
00670          snprintf(status, 255, "Connected to %s@%s", dbname, dbhost);
00671       }
00672 
00673       if(dbuser && *dbuser) {
00674          snprintf(status2, 99, " with username %s", dbuser);
00675       }
00676 
00677       if (ctime > 31536000) {
00678          ast_cli(fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 31536000, (ctime % 31536000) / 86400, (ctime % 86400) / 3600, (ctime % 3600) / 60, ctime % 60);
00679       } else if (ctime > 86400) {
00680          ast_cli(fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 86400, (ctime % 86400) / 3600, (ctime % 3600) / 60, ctime % 60);
00681       } else if (ctime > 3600) {
00682          ast_cli(fd, "%s%s for %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 3600, (ctime % 3600) / 60, ctime % 60);
00683       } else if (ctime > 60) {
00684          ast_cli(fd, "%s%s for %d minutes, %d seconds.\n", status, status2, ctime / 60, ctime % 60);
00685       } else {
00686          ast_cli(fd, "%s%s for %d seconds.\n", status, status2, ctime);
00687       }
00688 
00689       return RESULT_SUCCESS;
00690    } else {
00691       return RESULT_FAILURE;
00692    }
00693 }

static int reload ( void   )  [static]

Definition at line 513 of file res_config_mysql.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), connected, LOG_DEBUG, LOG_WARNING, mysql, mysql_reconnect(), parse_config(), and VERBOSE_PREFIX_2.

00514 {
00515    /* Aquire control before doing anything to the module itself. */
00516    ast_mutex_lock(&mysql_lock);
00517 
00518    mysql_close(&mysql);
00519    connected = 0;
00520    parse_config();
00521 
00522    if(!mysql_reconnect(NULL)) {
00523       ast_log(LOG_WARNING, "MySQL RealTime: Couldn't establish connection. Check debug.\n");
00524       ast_log(LOG_DEBUG, "MySQL RealTime: Cannot Connect: %s\n", mysql_error(&mysql));
00525    }
00526 
00527    ast_verbose(VERBOSE_PREFIX_2 "MySQL RealTime reloaded.\n");
00528 
00529    /* Done reloading. Release lock so others can now use driver. */
00530    ast_mutex_unlock(&mysql_lock);
00531 
00532    return 0;
00533 }

static int unload_module ( void   )  [static]

Definition at line 493 of file res_config_mysql.c.

References ast_cli_unregister(), ast_config_engine_deregister(), ast_module_user_hangup_all, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), cli_realtime_mysql_status, mysql, mysql_engine, and option_verbose.

00494 {
00495    /* Aquire control before doing anything to the module itself. */
00496    ast_mutex_lock(&mysql_lock);
00497 
00498    mysql_close(&mysql);
00499    ast_cli_unregister(&cli_realtime_mysql_status);
00500    ast_config_engine_deregister(&mysql_engine);
00501    if(option_verbose) {
00502       ast_verbose("MySQL RealTime unloaded.\n");
00503    }
00504 
00505    ast_module_user_hangup_all();
00506 
00507    /* Unlock so something else can destroy the lock. */
00508    ast_mutex_unlock(&mysql_lock);
00509 
00510    return 0;
00511 }

static int update_mysql ( const char *  database,
const char *  table,
const char *  keyfield,
const char *  lookup,
va_list  ap 
) [static]

Definition at line 309 of file res_config_mysql.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_DEBUG, LOG_WARNING, mysql, and mysql_reconnect().

00310 {
00311    my_ulonglong numrows;
00312    char sql[512];
00313    char buf[511]; /* Keep this size uneven as it is 2n+1. */
00314    int valsz;
00315    const char *newparam, *newval;
00316 
00317    if(!table) {
00318       ast_log(LOG_WARNING, "MySQL RealTime: No table specified.\n");
00319                return -1;
00320    }
00321 
00322    /* Get the first parameter and first value in our list of passed paramater/value pairs */
00323    newparam = va_arg(ap, const char *);
00324    newval = va_arg(ap, const char *);
00325    if(!newparam || !newval)  {
00326       ast_log(LOG_WARNING, "MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
00327       mysql_close(&mysql);
00328                return -1;
00329    }
00330 
00331    /* Must connect to the server before anything else, as the escape function requires the mysql handle. */
00332    ast_mutex_lock(&mysql_lock);
00333    if (!mysql_reconnect(database)) {
00334       ast_mutex_unlock(&mysql_lock);
00335       return -1;
00336    }
00337 
00338    /* Create the first part of the query using the first parameter/value pairs we just extracted
00339       If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
00340 
00341    if ((valsz = strlen (newval)) * 1 + 1 > sizeof(buf))
00342       valsz = (sizeof(buf) - 1) / 2;
00343    mysql_real_escape_string(&mysql, buf, newval, valsz);
00344    snprintf(sql, sizeof(sql), "UPDATE %s SET %s = '%s'", table, newparam, buf);
00345    while((newparam = va_arg(ap, const char *))) {
00346       newval = va_arg(ap, const char *);
00347       if ((valsz = strlen (newval)) * 2 + 1 > sizeof(buf))
00348          valsz = (sizeof(buf) - 1) / 2;
00349       mysql_real_escape_string(&mysql, buf, newval, valsz);
00350       snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", %s = '%s'", newparam, buf);
00351    }
00352    va_end(ap);
00353    if ((valsz = strlen (lookup)) * 1 + 1 > sizeof(buf))
00354       valsz = (sizeof(buf) - 1) / 2;
00355    mysql_real_escape_string(&mysql, buf, lookup, valsz);
00356    snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s = '%s'", keyfield, buf);
00357 
00358    ast_log(LOG_DEBUG,"MySQL RealTime: Update SQL: %s\n", sql);
00359 
00360    /* Execution. */
00361    if(mysql_real_query(&mysql, sql, strlen(sql))) {
00362       ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
00363       ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql);
00364       ast_log(LOG_DEBUG, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&mysql));
00365       ast_mutex_unlock(&mysql_lock);
00366       return -1;
00367    }
00368 
00369    numrows = mysql_affected_rows(&mysql);
00370    ast_mutex_unlock(&mysql_lock);
00371 
00372    ast_log(LOG_DEBUG,"MySQL RealTime: Updated %llu rows on table: %s\n", numrows, table);
00373 
00374    /* From http://dev.mysql.com/doc/mysql/en/mysql-affected-rows.html
00375     * An integer greater than zero indicates the number of rows affected
00376     * Zero indicates that no records were updated
00377     * -1 indicates that the query returned an error (although, if the query failed, it should have been caught above.)
00378    */
00379 
00380    if(numrows >= 0)
00381       return (int)numrows;
00382 
00383    return -1;
00384 }


Variable Documentation

struct ast_cli_entry cli_realtime_mysql_status [static]

Initial value:

 {
        { "realtime", "mysql", "status", NULL }, realtime_mysql_status,
        "Shows connection information for the MySQL RealTime driver", cli_realtime_mysql_status_usage, NULL }

Definition at line 84 of file res_config_mysql.c.

Referenced by load_module(), and unload_module().

char cli_realtime_mysql_status_usage[] [static]

Initial value:

"Usage: realtime mysql status\n"
"       Shows connection information for the MySQL RealTime driver\n"

Definition at line 80 of file res_config_mysql.c.

time_t connect_time [static]

Definition at line 74 of file res_config_mysql.c.

int connected [static]

Definition at line 73 of file res_config_mysql.c.

char dbhost[50] [static]

Definition at line 67 of file res_config_mysql.c.

Referenced by aMYSQL_connect(), mysql_reconnect(), parse_config(), pgsql_reconnect(), realtime_mysql_status(), and realtime_pgsql_status().

char dbname[50] [static]

Definition at line 70 of file res_config_mysql.c.

char dbpass[50] [static]

Definition at line 69 of file res_config_mysql.c.

Referenced by aMYSQL_connect(), mysql_reconnect(), parse_config(), and pgsql_reconnect().

int dbport [static]

Definition at line 72 of file res_config_mysql.c.

char dbsock[50] [static]

Definition at line 71 of file res_config_mysql.c.

char dbuser[50] [static]

Definition at line 68 of file res_config_mysql.c.

MYSQL mysql

Definition at line 66 of file res_config_mysql.c.

struct ast_config_engine mysql_engine [static]

Definition at line 463 of file res_config_mysql.c.

Referenced by load_module(), and unload_module().


Generated on Mon Apr 30 07:46:03 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1