Mon May 14 04:52:23 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 385 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.

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

static int load_module ( void   )  [static]

Definition at line 470 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().

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

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

Definition at line 598 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().

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

static int parse_config ( void   )  [static]

Definition at line 534 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.

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

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

Definition at line 184 of file res_config_mysql.c.

References ast_category_append(), ast_category_new(), ast_category_rename(), ast_config_destroy(), 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.

00185 {
00186    MYSQL_RES *result;
00187    MYSQL_ROW row;
00188    MYSQL_FIELD *fields;
00189    int numFields, i, valsz;
00190    char sql[512];
00191    char buf[511]; /* Keep this size uneven as it is 2n+1. */
00192    const char *initfield = NULL;
00193    char *stringp;
00194    char *chunk;
00195    char *op;
00196    const char *newparam, *newval;
00197    struct ast_realloca ra;
00198    struct ast_variable *var=NULL;
00199    struct ast_config *cfg = NULL;
00200    struct ast_category *cat = NULL;
00201 
00202    if(!table) {
00203       ast_log(LOG_WARNING, "MySQL RealTime: No table specified.\n");
00204       return NULL;
00205    }
00206    
00207    memset(&ra, 0, sizeof(ra));
00208 
00209    cfg = ast_config_new();
00210    if (!cfg) {
00211       /* If I can't alloc memory at this point, why bother doing anything else? */
00212       ast_log(LOG_WARNING, "Out of memory!\n");
00213       return NULL;
00214    }
00215 
00216    /* Get the first parameter and first value in our list of passed paramater/value pairs */
00217    newparam = va_arg(ap, const char *);
00218    newval = va_arg(ap, const char *);
00219    if(!newparam || !newval)  {
00220       ast_log(LOG_WARNING, "MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
00221       ast_config_destroy(cfg);
00222       return NULL;
00223    }
00224 
00225    initfield = ast_strdupa(newparam);
00226    if(initfield && (op = strchr(initfield, ' '))) {
00227       *op = '\0';
00228    }
00229 
00230    /* Must connect to the server before anything else, as the escape function requires the mysql handle. */
00231    ast_mutex_lock(&mysql_lock);
00232    if (!mysql_reconnect(database)) {
00233       ast_mutex_unlock(&mysql_lock);
00234       return NULL;
00235    }
00236 
00237    /* Create the first part of the query using the first parameter/value pairs we just extracted
00238       If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
00239 
00240    if(!strchr(newparam, ' ')) op = " ="; else op = "";
00241 
00242    if ((valsz = strlen (newval)) * 2 + 1 > sizeof(buf))
00243       valsz = (sizeof(buf) - 1) / 2;
00244    mysql_real_escape_string(&mysql, buf, newval, valsz);
00245    snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, buf);
00246    while((newparam = va_arg(ap, const char *))) {
00247       newval = va_arg(ap, const char *);
00248       if(!strchr(newparam, ' ')) op = " ="; else op = "";
00249       if ((valsz = strlen (newval)) * 2 + 1 > sizeof(buf))
00250          valsz = (sizeof(buf) - 1) / 2;
00251       mysql_real_escape_string(&mysql, buf, newval, valsz);
00252       snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, op, buf);
00253    }
00254 
00255    if(initfield) {
00256       snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " ORDER BY %s", initfield);
00257    }
00258 
00259    va_end(ap);
00260 
00261    ast_log(LOG_DEBUG, "MySQL RealTime: Retrieve SQL: %s\n", sql);
00262 
00263    /* Execution. */
00264    if(mysql_real_query(&mysql, sql, strlen(sql))) {
00265       ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
00266       ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql);
00267       ast_log(LOG_DEBUG, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&mysql));
00268       ast_mutex_unlock(&mysql_lock);
00269       ast_config_destroy(cfg);
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       return NULL;
00113    }
00114 
00115    /* Must connect to the server before anything else, as the escape function requires the mysql handle. */
00116    ast_mutex_lock(&mysql_lock);
00117    if (!mysql_reconnect(database)) {
00118       ast_mutex_unlock(&mysql_lock);
00119       return NULL;
00120    }
00121 
00122    /* Create the first part of the query using the first parameter/value pairs we just extracted
00123       If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
00124 
00125    if(!strchr(newparam, ' ')) op = " ="; else op = "";
00126 
00127    if ((valsz = strlen (newval)) * 2 + 1 > sizeof(buf))
00128       valsz = (sizeof(buf) - 1) / 2;
00129    mysql_real_escape_string(&mysql, buf, newval, valsz);
00130    snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, buf);
00131    while((newparam = va_arg(ap, const char *))) {
00132       newval = va_arg(ap, const char *);
00133       if(!strchr(newparam, ' ')) op = " ="; else op = "";
00134       if ((valsz = strlen (newval)) * 2 + 1 > sizeof(buf))
00135          valsz = (sizeof(buf) - 1) / 2;
00136       mysql_real_escape_string(&mysql, buf, newval, valsz);
00137       snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, op, buf);
00138    }
00139    va_end(ap);
00140 
00141    ast_log(LOG_DEBUG, "MySQL RealTime: Retrieve SQL: %s\n", sql);
00142 
00143    /* Execution. */
00144    if(mysql_real_query(&mysql, sql, strlen(sql))) {
00145       ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
00146       ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql);
00147       ast_log(LOG_DEBUG, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&mysql));
00148       ast_mutex_unlock(&mysql_lock);
00149       return NULL;
00150    }
00151 
00152    if((result = mysql_store_result(&mysql))) {
00153       numFields = mysql_num_fields(result);
00154       fields = mysql_fetch_fields(result);
00155 
00156       while((row = mysql_fetch_row(result))) {
00157          for(i = 0; i < numFields; i++) {
00158             stringp = row[i];
00159             while(stringp) {
00160                chunk = strsep(&stringp, ";");
00161                if(chunk && !ast_strlen_zero(ast_strip(chunk))) {
00162                   if(prev) {
00163                      prev->next = ast_variable_new(fields[i].name, chunk);
00164                      if (prev->next) {
00165                         prev = prev->next;
00166                      }
00167                   } else {
00168                      prev = var = ast_variable_new(fields[i].name, chunk);
00169                   }
00170                }
00171             }
00172          }
00173       }
00174    } else {                                
00175       ast_log(LOG_WARNING, "MySQL RealTime: Could not find any rows in table %s.\n", table);
00176    }
00177 
00178    ast_mutex_unlock(&mysql_lock);
00179    mysql_free_result(result);
00180 
00181    return var;
00182 }

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

Definition at line 658 of file res_config_mysql.c.

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

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

static int reload ( void   )  [static]

Definition at line 512 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.

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

static int unload_module ( void   )  [static]

Definition at line 492 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.

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

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


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 462 of file res_config_mysql.c.

Referenced by load_module(), and unload_module().


Generated on Mon May 14 04:52:24 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1