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 mysql_close(&mysql);
00113 return NULL;
00114 }
00115
00116
00117 ast_mutex_lock(&mysql_lock);
00118 if (!mysql_reconnect(database)) {
00119 ast_mutex_unlock(&mysql_lock);
00120 return NULL;
00121 }
00122
00123
00124
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
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 }
00184
00185 static struct ast_config *realtime_multi_mysql(const char *database, const char *table, va_list ap)
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];
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
00213 ast_log(LOG_WARNING, "Out of memory!\n");
00214 return NULL;
00215 }
00216
00217
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
00232 ast_mutex_lock(&mysql_lock);
00233 if (!mysql_reconnect(database)) {
00234 ast_mutex_unlock(&mysql_lock);
00235 return NULL;
00236 }
00237
00238
00239
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
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 }
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 mysql_close(&mysql);
00328 return -1;
00329 }
00330
00331
00332 ast_mutex_lock(&mysql_lock);
00333 if (!mysql_reconnect(database)) {
00334 ast_mutex_unlock(&mysql_lock);
00335 return -1;
00336 }
00337
00338
00339
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
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
00375
00376
00377
00378
00379
00380 if(numrows >= 0)
00381 return (int)numrows;
00382
00383 return -1;
00384 }
00385
00386 static struct ast_config *config_mysql(const char *database, const char *table, const char *file, struct ast_config *cfg, int withcomments)
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
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
00428
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 }
00462
00463 static struct ast_config_engine mysql_engine = {
00464 .name = "mysql",
00465 .load_func = config_mysql,
00466 .realtime_func = realtime_mysql,
00467 .realtime_multi_func = realtime_multi_mysql,
00468 .update_func = update_mysql
00469 };
00470
00471 static int load_module(void)
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 }
00492
00493 static int unload_module(void)
00494 {
00495
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
00508 ast_mutex_unlock(&mysql_lock);
00509
00510 return 0;
00511 }
00512
00513 static int reload(void)
00514 {
00515
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
00530 ast_mutex_unlock(&mysql_lock);
00531
00532 return 0;
00533 }
00534
00535 static int parse_config (void)
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 }
00598
00599 static int mysql_reconnect(const char *database)
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
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
00623
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
00638
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 }
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");