00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <asterisk.h>
00045
00046 #include <asterisk/channel.h>
00047 #include <asterisk/logger.h>
00048 #include <asterisk/config.h>
00049 #include <asterisk/module.h>
00050 #include <asterisk/lock.h>
00051 #include <asterisk/options.h>
00052 #include <asterisk/cli.h>
00053 #include <asterisk/utils.h>
00054 #include <stdlib.h>
00055 #include <stdio.h>
00056 #include <string.h>
00057 #include <stdio.h>
00058 #include <mysql/mysql.h>
00059 #include <mysql/mysql_version.h>
00060 #include <mysql/errmsg.h>
00061
00062 #define AST_MODULE "res_config_mysql"
00063
00064 AST_MUTEX_DEFINE_STATIC(mysql_lock);
00065 #define RES_CONFIG_MYSQL_CONF "res_mysql.conf"
00066 MYSQL mysql;
00067 static char dbhost[50];
00068 static char dbuser[50];
00069 static char dbpass[50];
00070 static char dbname[50];
00071 static char dbsock[50];
00072 static int dbport;
00073 static int connected;
00074 static time_t connect_time;
00075
00076 static int parse_config(void);
00077 static int mysql_reconnect(const char *database);
00078 static int realtime_mysql_status(int fd, int argc, char **argv);
00079
00080 static char cli_realtime_mysql_status_usage[] =
00081 "Usage: realtime mysql status\n"
00082 " Shows connection information for the MySQL RealTime driver\n";
00083
00084 static struct ast_cli_entry cli_realtime_mysql_status = {
00085 { "realtime", "mysql", "status", NULL }, realtime_mysql_status,
00086 "Shows connection information for the MySQL RealTime driver", cli_realtime_mysql_status_usage, NULL };
00087
00088 static struct ast_variable *realtime_mysql(const char *database, const char *table, va_list ap)
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];
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
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
00116 ast_mutex_lock(&mysql_lock);
00117 if (!mysql_reconnect(database)) {
00118 ast_mutex_unlock(&mysql_lock);
00119 return NULL;
00120 }
00121
00122
00123
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
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 }
00183
00184 static struct ast_config *realtime_multi_mysql(const char *database, const char *table, va_list ap)
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];
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
00212 ast_log(LOG_WARNING, "Out of memory!\n");
00213 return NULL;
00214 }
00215
00216
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
00231 ast_mutex_lock(&mysql_lock);
00232 if (!mysql_reconnect(database)) {
00233 ast_mutex_unlock(&mysql_lock);
00234 return NULL;
00235 }
00236
00237
00238
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
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 }
00308
00309 static int update_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap)
00310 {
00311 my_ulonglong numrows;
00312 char sql[512];
00313 char buf[511];
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
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
00331 ast_mutex_lock(&mysql_lock);
00332 if (!mysql_reconnect(database)) {
00333 ast_mutex_unlock(&mysql_lock);
00334 return -1;
00335 }
00336
00337
00338
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
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
00374
00375
00376
00377
00378
00379 if(numrows >= 0)
00380 return (int)numrows;
00381
00382 return -1;
00383 }
00384
00385 static struct ast_config *config_mysql(const char *database, const char *table, const char *file, struct ast_config *cfg, int withcomments)
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
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
00427
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 }
00461
00462 static struct ast_config_engine mysql_engine = {
00463 .name = "mysql",
00464 .load_func = config_mysql,
00465 .realtime_func = realtime_mysql,
00466 .realtime_multi_func = realtime_multi_mysql,
00467 .update_func = update_mysql
00468 };
00469
00470 static int load_module(void)
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 }
00491
00492 static int unload_module(void)
00493 {
00494
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
00507 ast_mutex_unlock(&mysql_lock);
00508
00509 return 0;
00510 }
00511
00512 static int reload(void)
00513 {
00514
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
00529 ast_mutex_unlock(&mysql_lock);
00530
00531 return 0;
00532 }
00533
00534 static int parse_config (void)
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 }
00597
00598 static int mysql_reconnect(const char *database)
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
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
00622
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
00637
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 connect_time = time(NULL);
00647
00648 if(mysql_select_db(&mysql, my_database) != 0) {
00649 ast_log(LOG_WARNING, "MySQL RealTime: Unable to select database: %s. Still Connected (%u).\n", my_database, mysql_errno(&mysql));
00650 ast_log(LOG_DEBUG, "MySQL RealTime: Database Select Failed (%u): %s\n", mysql_errno(&mysql), mysql_error(&mysql));
00651 return 0;
00652 }
00653
00654 ast_log(LOG_DEBUG, "MySQL RealTime: Everything is fine.\n");
00655 return 1;
00656 }
00657 }
00658
00659 static int realtime_mysql_status(int fd, int argc, char **argv)
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 }
00694
00695 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "MySQL RealTime Configuration Driver");