[asterisk-addons-commits] russell: trunk r391 -
/trunk/cdr_addon_mysql.c
asterisk-addons-commits at lists.digium.com
asterisk-addons-commits at lists.digium.com
Fri Jun 8 08:24:44 MST 2007
Author: russell
Date: Fri Jun 8 10:24:44 2007
New Revision: 391
URL: http://svn.digium.com/view/asterisk-addons?view=rev&rev=391
Log:
Make field names configurable for cdr_addon_mysql and convert string handling
to use the Asterisk strings API.
(issue #8594, initial patch submitted by afshin, mostly rewritten by bbryant)
Modified:
trunk/cdr_addon_mysql.c
Modified: trunk/cdr_addon_mysql.c
URL: http://svn.digium.com/view/asterisk-addons/trunk/cdr_addon_mysql.c?view=diff&rev=391&r1=390&r2=391
==============================================================================
--- trunk/cdr_addon_mysql.c (original)
+++ trunk/cdr_addon_mysql.c Fri Jun 8 10:24:44 2007
@@ -29,6 +29,8 @@
#include <asterisk/module.h>
#include <asterisk/logger.h>
#include <asterisk/cli.h>
+#include <asterisk/strings.h>
+#include <asterisk/linkedlists.h>
#include <stdio.h>
#include <string.h>
@@ -47,12 +49,15 @@
#define AST_MODULE "cdr_addon_mysql"
#define DATE_FORMAT "%Y-%m-%d %T"
-
static char *desc = "MySQL CDR Backend";
static char *name = "mysql";
static char *config = "cdr_mysql.conf";
-static char *hostname = NULL, *dbname = NULL, *dbuser = NULL, *password = NULL, *dbsock = NULL, *dbtable = NULL;
-static int hostname_alloc = 0, dbname_alloc = 0, dbuser_alloc = 0, password_alloc = 0, dbsock_alloc = 0, dbtable_alloc = 0;
+
+static struct ast_str *hostname = NULL, *dbname = NULL, *dbuser = NULL, *password = NULL, *dbsock = NULL, *dbtable = NULL,
+ *calldate_field = NULL, *clid_field = NULL, *src_field = NULL, *dst_field = NULL, *dcontext_field = NULL, *channel_field = NULL,
+ *dstchannel_field = NULL, *lastapp_field = NULL, *lastdata_field = NULL, *duration_field = NULL, *billsec_field =NULL,
+ *disposition_field = NULL, *amaflags_field = NULL, *accountcode_field = NULL, *userfield_field = NULL, *uniqueid_field = NULL;
+
static int dbport = 0;
static int connected = 0;
static time_t connect_time = 0;
@@ -63,6 +68,13 @@
AST_MUTEX_DEFINE_STATIC(mysql_lock);
+struct unload_string {
+ AST_LIST_ENTRY(unload_string) entry;
+ struct ast_str *str;
+};
+
+static AST_LIST_HEAD_STATIC(unload_strings, unload_string);
+
static MYSQL mysql;
static char cdr_mysql_status_help[] =
@@ -75,16 +87,16 @@
char status[256], status2[100] = "";
int ctime = time(NULL) - connect_time;
if (dbport)
- snprintf(status, 255, "Connected to %s@%s, port %d", dbname, hostname, dbport);
+ snprintf(status, 255, "Connected to %s@%s, port %d", dbname->str, hostname, dbport);
else if (dbsock)
- snprintf(status, 255, "Connected to %s on socket file %s", dbname, dbsock);
+ snprintf(status, 255, "Connected to %s on socket file %s", dbname->str, dbsock);
else
- snprintf(status, 255, "Connected to %s@%s", dbname, hostname);
-
- if (dbuser && *dbuser)
- snprintf(status2, 99, " with username %s", dbuser);
- if (dbtable && *dbtable)
- snprintf(status2, 99, " using table %s", dbtable);
+ snprintf(status, 255, "Connected to %s@%s", dbname->str, hostname);
+
+ if (!ast_strlen_zero(dbuser->str))
+ snprintf(status2, 99, " with username %s", dbuser->str);
+ if (!ast_strlen_zero(dbtable->str))
+ snprintf(status2, 99, " using table %s", dbtable->str);
if (ctime > 31536000) {
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);
} else if (ctime > 86400) {
@@ -119,7 +131,7 @@
struct ast_module_user *u;
char *userfielddata = NULL;
char sqlcmd[2048], timestr[128];
- char *clid=NULL, *dcontext=NULL, *channel=NULL, *dstchannel=NULL, *lastapp=NULL, *lastdata=NULL;
+ char *clid=NULL, *dcontext=NULL, *channel=NULL, *dstchannel=NULL, *lastapp=NULL, *lastdata=NULL, *tmp;
int retries = 5;
#ifdef MYSQL_LOGUNIQUEID
char *uniqueid = NULL;
@@ -140,7 +152,8 @@
if (timeout && mysql_options(&mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *)&timeout)!=0) {
ast_log(LOG_ERROR, "cdr_mysql: mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));
}
- if (mysql_real_connect(&mysql, hostname, dbuser, password, dbname, dbport, dbsock, 0)) {
+ tmp = dbsock ? dbsock->str : NULL;
+ if (mysql_real_connect(&mysql, hostname->str, dbuser->str, password->str, dbname->str, dbport, tmp, 0)) {
connected = 1;
connect_time = time(NULL);
records = 0;
@@ -211,15 +224,15 @@
if (userfield && userfielddata) {
#ifdef MYSQL_LOGUNIQUEID
- sprintf(sqlcmd, "INSERT INTO %s (calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield) VALUES ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%i,%i,'%s',%i,'%s','%s','%s')", dbtable, timestr, clid, cdr->src, cdr->dst, dcontext, channel, dstchannel, lastapp, lastdata, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), cdr->amaflags, cdr->accountcode, uniqueid, userfielddata);
+ snprintf(sqlcmd, sizeof(sqlcmd), "INSERT INTO %s (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) VALUES ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%i,%i,'%s',%i,'%s','%s','%s')", dbtable->str, calldate_field->str, clid_field->str, src_field->str, dst_field->str, dcontext_field->str, channel_field->str, dstchannel_field->str, lastapp_field->str, lastdata_field->str, duration_field->str, billsec_field->str, disposition_field->str, amaflags_field->str, accountcode_field->str, uniqueid_field->str, userfield_field->str, timestr, clid, cdr->src, cdr->dst, dcontext, channel, dstchannel, lastapp, lastdata, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), cdr->amaflags, cdr->accountcode, uniqueid, userfielddata);
#else
- sprintf(sqlcmd, "INSERT INTO %s (calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,duration,billsec,disposition,amaflags,accountcode,userfield) VALUES ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%i,%i,'%s',%i,'%s','%s')", dbtable, timestr, clid, cdr->src, cdr->dst, dcontext,channel, dstchannel, lastapp, lastdata, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), cdr->amaflags, cdr->accountcode, userfielddata);
+ snprintf(sqlcmd, sizeof(sqlcmd), "INSERT INTO %s (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) VALUES ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%i,%i,'%s',%i,'%s','%s')", dbtable->str, calldate_field->str, clid_field->str, src_field->str, dst_field->str, dcontext_field->str, channel_field->str, dstchannel_field->str, lastapp_field->str, lastdata_field->str, duration_field->str, billsec_field->str, disposition_field->str, amaflags_field->str, accountcode_field->str, userfield_field->str, timestr, clid, cdr->src, cdr->dst, dcontext, channel, dstchannel, lastapp, lastdata, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), cdr->amaflags, cdr->accountcode, userfielddata);
#endif
} else {
#ifdef MYSQL_LOGUNIQUEID
- sprintf(sqlcmd, "INSERT INTO %s (calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid) VALUES ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%i,%i,'%s',%i,'%s','%s')", dbtable, timestr, clid, cdr->src, cdr->dst, dcontext,channel, dstchannel, lastapp, lastdata, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), cdr->amaflags, cdr->accountcode, uniqueid);
+ snprintf(sqlcmd, sizeof(sqlcmd), "INSERT INTO %s (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) VALUES ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%i,%i,'%s',%i,'%s','%s')", dbtable->str, calldate_field->str, clid_field->str, src_field->str, dst_field->str, dcontext_field->str, channel_field->str, dstchannel_field->str, lastapp_field->str, lastdata_field->str, duration_field->str, billsec_field->str, disposition_field->str, amaflags_field->str, accountcode_field->str, uniqueid_field->str, timestr, clid, cdr->src, cdr->dst, dcontext,channel, dstchannel, lastapp, lastdata, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), cdr->amaflags, cdr->accountcode, uniqueid);
#else
- sprintf(sqlcmd, "INSERT INTO %s (calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,duration,billsec,disposition,amaflags,accountcode) VALUES ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%i,%i,'%s',%i,'%s')", dbtable, timestr, clid, cdr->src, cdr->dst, dcontext, channel, dstchannel, lastapp, lastdata, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), cdr->amaflags, cdr->accountcode);
+ snprintf(sqlcmd, sizeof(sqlcmd), "INSERT INTO %s (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) VALUES ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%i,%i,'%s',%i,'%s')", dbtable->str, calldate_field->str, clid_field->str, src_field->str, dst_field->str, dcontext_field->str, channel_field->str, dstchannel_field->str, lastapp_field->str, lastdata_field->str, duration_field->str, billsec_field->str, disposition_field->str, amaflags_field->str, accountcode_field->str, timestr, clid, cdr->src, cdr->dst, dcontext,channel, dstchannel, lastapp, lastdata, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), cdr->amaflags, cdr->accountcode);
#endif
}
@@ -241,44 +254,64 @@
static int my_unload_module(void)
{
+ struct unload_string *us;
+
ast_cli_unregister(&cdr_mysql_status_cli);
+
if (connected) {
mysql_close(&mysql);
connected = 0;
records = 0;
}
- if (hostname && hostname_alloc) {
- free(hostname);
- hostname = NULL;
- hostname_alloc = 0;
- }
- if (dbname && dbname_alloc) {
- free(dbname);
- dbname = NULL;
- dbname_alloc = 0;
- }
- if (dbuser && dbuser_alloc) {
- free(dbuser);
- dbuser = NULL;
- dbuser_alloc = 0;
- }
- if (dbsock && dbsock_alloc) {
- free(dbsock);
- dbsock = NULL;
- dbsock_alloc = 0;
- }
- if (dbtable && dbtable_alloc) {
- free(dbtable);
- dbtable = NULL;
- dbtable_alloc = 0;
- }
- if (password && password_alloc) {
- free(password);
- password = NULL;
- password_alloc = 0;
- }
+
+ AST_LIST_LOCK(&unload_strings);
+ while ((us = AST_LIST_REMOVE_HEAD(&unload_strings, entry))) {
+ free(us->str);
+ free(us);
+ }
+ AST_LIST_UNLOCK(&unload_strings);
+
dbport = 0;
ast_cdr_unregister(name);
+
+ return 0;
+}
+
+static int my_load_config_string(struct ast_config *cfg, const char *category, const char *variable, struct ast_str **field, const char *def)
+{
+ struct unload_string *us;
+ const char *tmp;
+
+ if (!(us = ast_calloc(1, sizeof(*us))))
+ return -1;
+
+ if (!(*field = ast_str_create(16))) {
+ free(us);
+ return -1;
+ }
+
+ us->str = *field;
+
+ AST_LIST_LOCK(&unload_strings);
+ AST_LIST_INSERT_HEAD(&unload_strings, us, entry);
+ AST_LIST_UNLOCK(&unload_strings);
+
+ tmp = ast_variable_retrieve(cfg, category, variable);
+
+ ast_str_set(field, 0, "%s", tmp ? tmp : def);
+
+ return 0;
+}
+
+static int my_load_config_number(struct ast_config *cfg, const char *category, const char *variable, int *field, int def)
+{
+ const char *tmp;
+
+ tmp = ast_variable_retrieve(cfg, category, variable);
+
+ if (!tmp || sscanf(tmp, "%d", field) < 1)
+ *field = def;
+
return 0;
}
@@ -288,151 +321,94 @@
struct ast_config *cfg;
struct ast_variable *var;
const char *tmp;
+ char *temp;
cfg = ast_config_load(config);
if (!cfg) {
ast_log(LOG_WARNING, "Unable to load config for mysql CDR's: %s\n", config);
- return 0;
+ return AST_MODULE_LOAD_SUCCESS;
}
var = ast_variable_browse(cfg, "global");
if (!var) {
/* nothing configured */
- return 0;
- }
-
- tmp = ast_variable_retrieve(cfg, "global", "hostname");
- if (tmp) {
- hostname = malloc(strlen(tmp) + 1);
- if (hostname != NULL) {
- hostname_alloc = 1;
- strcpy(hostname, tmp);
- } else {
- ast_log(LOG_ERROR, "Out of memory error.\n");
- return -1;
- }
- } else {
- ast_log(LOG_WARNING, "MySQL server hostname not specified. Assuming localhost\n");
- hostname = "localhost";
- }
-
- tmp = ast_variable_retrieve(cfg, "global", "dbname");
- if (tmp) {
- dbname = malloc(strlen(tmp) + 1);
- if (dbname != NULL) {
- dbname_alloc = 1;
- strcpy(dbname, tmp);
- } else {
- ast_log(LOG_ERROR, "Out of memory error.\n");
- return -1;
- }
- } else {
- ast_log(LOG_WARNING, "MySQL database not specified. Assuming asteriskcdrdb\n");
- dbname = "asteriskcdrdb";
- }
-
- tmp = ast_variable_retrieve(cfg, "global", "user");
- if (tmp) {
- dbuser = malloc(strlen(tmp) + 1);
- if (dbuser != NULL) {
- dbuser_alloc = 1;
- strcpy(dbuser, tmp);
- } else {
- ast_log(LOG_ERROR, "Out of memory error.\n");
- return -1;
- }
- } else {
- ast_log(LOG_WARNING, "MySQL database user not specified. Assuming root\n");
- dbuser = "root";
- }
-
- tmp = ast_variable_retrieve(cfg, "global", "sock");
- if (tmp) {
- dbsock = malloc(strlen(tmp) + 1);
- if (dbsock != NULL) {
- dbsock_alloc = 1;
- strcpy(dbsock, tmp);
- } else {
- ast_log(LOG_ERROR, "Out of memory error.\n");
- return -1;
- }
- } else {
- ast_log(LOG_WARNING, "MySQL database sock file not specified. Using default\n");
- dbsock = NULL;
- }
-
- tmp = ast_variable_retrieve(cfg, "global", "table");
- if (tmp) {
- dbtable = malloc(strlen(tmp) + 1);
- if (dbtable != NULL) {
- dbtable_alloc = 1;
- strcpy(dbtable, tmp);
- } else {
- ast_log(LOG_ERROR, "Out of memory error.\n");
- return -1;
- }
- } else {
- ast_log(LOG_NOTICE, "MySQL database table not specified. Assuming \"cdr\"\n");
- dbtable = "cdr";
- }
-
- tmp = ast_variable_retrieve(cfg, "global", "password");
- if (tmp) {
- password = malloc(strlen(tmp) + 1);
- if (password != NULL) {
- password_alloc = 1;
- strcpy(password, tmp);
- } else {
- ast_log(LOG_ERROR, "Out of memory error.\n");
- return -1;
- }
- } else {
- ast_log(LOG_WARNING, "MySQL database password not specified. Assuming blank\n");
- password = "";
- }
-
- tmp = ast_variable_retrieve(cfg, "global", "port");
- if (tmp) {
- if (sscanf(tmp, "%d", &dbport) < 1) {
- ast_log(LOG_WARNING, "Invalid MySQL port number. Using default\n");
- dbport = 0;
- }
- }
-
- tmp = ast_variable_retrieve(cfg, "global", "timeout");
- if (tmp) {
- if (sscanf(tmp,"%d", &timeout) < 1) {
- ast_log(LOG_WARNING, "Invalid MySQL timeout number. Using default\n");
- timeout = 0;
- }
- }
-
- tmp = ast_variable_retrieve(cfg, "global", "userfield");
- if (tmp) {
- if (sscanf(tmp, "%d", &userfield) < 1) {
- ast_log(LOG_WARNING, "Invalid MySQL configuration file\n");
- userfield = 0;
- }
- }
+ return AST_MODULE_LOAD_SUCCESS;
+ }
+
+ res = 0;
+
+ res |= my_load_config_string(cfg, "global", "hostname", &hostname, "localhost");
+ res |= my_load_config_string(cfg, "global", "dbname", &dbname, "astriskcdrdb");
+ res |= my_load_config_string(cfg, "global", "user", &dbuser, "root");
+ res |= my_load_config_string(cfg, "global", "sock", &dbsock, NULL);
+ res |= my_load_config_string(cfg, "global", "table", &dbtable, "cdr");
+ res |= my_load_config_string(cfg, "global", "password", &password, "");
+
+ res |= my_load_config_number(cfg, "global", "port", &dbport, 0);
+ res |= my_load_config_number(cfg, "global", "timeout", &timeout, 0);
+ res |= my_load_config_number(cfg, "global", "userfield", &userfield, 0);
+
+ res |= my_load_config_string(cfg, "global", "calldate_field", &calldate_field, "calldate");
+ res |= my_load_config_string(cfg, "global", "clid_field", &clid_field, "clid");
+ res |= my_load_config_string(cfg, "global", "src_field", &src_field, "src");
+
+ res |= my_load_config_string(cfg, "global", "dst_field", &dst_field, "dst");
+ res |= my_load_config_string(cfg, "global", "dcontext_field", &dcontext_field, "dcontext");
+ res |= my_load_config_string(cfg, "global", "channel_field", &channel_field, "channel");
+ res |= my_load_config_string(cfg, "global", "dstchannel_field", &dstchannel_field, "dstchannel");
+ res |= my_load_config_string(cfg, "global", "lastapp_field", &lastapp_field, "lastapp");
+ res |= my_load_config_string(cfg, "global", "lastdata_field", &lastdata_field, "lastdata");
+ res |= my_load_config_string(cfg, "global", "duration_field", &duration_field, "duration");
+ res |= my_load_config_string(cfg, "global", "billsec_field", &billsec_field, "billsec");
+ res |= my_load_config_string(cfg, "global", "disposition_field", &disposition_field, "disposition");
+ res |= my_load_config_string(cfg, "global", "amaflags_field", &amaflags_field, "amaflags");
+ res |= my_load_config_string(cfg, "global", "accountcode_field", &accountcode_field, "accountcode");
+ res |= my_load_config_string(cfg, "global", "userfield_field", &userfield_field, "userfield");
+
+#ifdef MYSQL_LOGUNIQUEID
+ res += my_load_config_string(cfg, "global", "uniqueid_field", &uniqueid_field, "uniqueid");
+#endif
+
+ if (res < 0)
+ return AST_MODULE_LOAD_FAILURE;
ast_config_destroy(cfg);
- ast_log(LOG_DEBUG, "cdr_mysql: got hostname of %s\n", hostname);
+ ast_log(LOG_DEBUG, "cdr_mysql: got hostname of %s\n", hostname->str);
ast_log(LOG_DEBUG, "cdr_mysql: got port of %d\n", dbport);
ast_log(LOG_DEBUG, "cdr_mysql: got a timeout of %d\n", timeout);
if (dbsock)
- ast_log(LOG_DEBUG, "cdr_mysql: got sock file of %s\n", dbsock);
- ast_log(LOG_DEBUG, "cdr_mysql: got user of %s\n", dbuser);
- ast_log(LOG_DEBUG, "cdr_mysql: got dbname of %s\n", dbname);
- ast_log(LOG_DEBUG, "cdr_mysql: got password of %s\n", password);
+ ast_log(LOG_DEBUG, "cdr_mysql: got sock file of %s\n", dbsock->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got user of %s\n", dbuser->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got dbname of %s\n", dbname->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got password of %s\n", password->str);
+
+ ast_log(LOG_DEBUG, "cdr_mysql: got calldate field of %s\n", calldate_field->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got clid field of %s\n", clid_field->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got src field of %s\n", src_field->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got dst field of %s\n", dst_field->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got dcontext field of %s\n", dcontext_field->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got channel field of %s\n", channel_field->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got dstchannel field of %s\n", dstchannel_field->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got lastapp field of %s\n", lastapp_field->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got lastdata field of %s\n", lastdata_field->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got duration field of %s\n", duration_field->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got billsec field of %s\n", billsec_field->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got amaflags field of %s\n", amaflags_field->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got accountcode field of %s\n", accountcode_field->str);
+ ast_log(LOG_DEBUG, "cdr_mysql: got userfield field of %s\n", userfield_field->str);
+
+#ifdef MYSQL_LOGUNIQUEID
+ ast_log(LOG_DEBUG, "cdr_mysql: got uniqueid field of %s\n", uniqueid_field->str);
+#endif
mysql_init(&mysql);
if (timeout && mysql_options(&mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *)&timeout)!=0) {
ast_log(LOG_ERROR, "cdr_mysql: mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));
}
-
- if (!mysql_real_connect(&mysql, hostname, dbuser, password, dbname, dbport, dbsock, 0)) {
+ temp = dbsock ? dbsock->str : NULL;
+ if (!mysql_real_connect(&mysql, hostname->str, dbuser->str, password->str, dbname->str, dbport, temp, 0)) {
ast_log(LOG_ERROR, "Failed to connect to mysql database %s on %s.\n", dbname, hostname);
connected = 0;
records = 0;
More information about the asterisk-addons-commits
mailing list