mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 20:20:07 +00:00
Bring cdr_tds in line with the other CDR backends and have it try to store
CDR(userfield) if it is set. The new behavior is to check for the userfield column on module load, and if it exists, we will store CDR(userfield) when CDRs are written. A similar patch already went into trunk and 1.6.0. (closes issue #13290) Reported by: falves11 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@137348 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
247
cdr/cdr_tds.c
247
cdr/cdr_tds.c
@@ -48,7 +48,8 @@ CREATE TABLE [dbo].[cdr] (
|
||||
[billsec] [int] NULL ,
|
||||
[disposition] [varchar] (20) NULL ,
|
||||
[amaflags] [varchar] (16) NULL ,
|
||||
[uniqueid] [varchar] (32) NULL
|
||||
[uniqueid] [varchar] (32) NULL ,
|
||||
[userfield] [varchar] (256) NULL
|
||||
) ON [PRIMARY]
|
||||
|
||||
\endverbatim
|
||||
@@ -95,6 +96,7 @@ static char *hostname = NULL, *dbname = NULL, *dbuser = NULL, *password = NULL,
|
||||
static char *table = NULL;
|
||||
|
||||
static int connected = 0;
|
||||
static int has_userfield = 0;
|
||||
|
||||
AST_MUTEX_DEFINE_STATIC(tds_lock);
|
||||
|
||||
@@ -103,7 +105,7 @@ static TDSLOGIN *login;
|
||||
static TDSCONTEXT *context;
|
||||
|
||||
static char *anti_injection(const char *, int);
|
||||
static void get_date(char *, struct timeval);
|
||||
static void get_date(char *, size_t, struct timeval);
|
||||
|
||||
static int mssql_connect(void);
|
||||
static int mssql_disconnect(void);
|
||||
@@ -111,7 +113,7 @@ static int mssql_disconnect(void);
|
||||
static int tds_log(struct ast_cdr *cdr)
|
||||
{
|
||||
char sqlcmd[2048], start[80], answer[80], end[80];
|
||||
char *accountcode, *src, *dst, *dcontext, *clid, *channel, *dstchannel, *lastapp, *lastdata, *uniqueid;
|
||||
char *accountcode, *src, *dst, *dcontext, *clid, *channel, *dstchannel, *lastapp, *lastdata, *uniqueid, *userfield = NULL;
|
||||
int res = 0;
|
||||
int retried = 0;
|
||||
#ifdef FREETDS_PRE_0_62
|
||||
@@ -133,71 +135,144 @@ static int tds_log(struct ast_cdr *cdr)
|
||||
lastdata = anti_injection(cdr->lastdata, 80);
|
||||
uniqueid = anti_injection(cdr->uniqueid, 32);
|
||||
|
||||
get_date(start, cdr->start);
|
||||
get_date(answer, cdr->answer);
|
||||
get_date(end, cdr->end);
|
||||
if (has_userfield) {
|
||||
userfield = anti_injection(cdr->userfield, AST_MAX_USER_FIELD);
|
||||
}
|
||||
|
||||
sprintf(
|
||||
sqlcmd,
|
||||
"INSERT INTO %s "
|
||||
"("
|
||||
"accountcode, "
|
||||
"src, "
|
||||
"dst, "
|
||||
"dcontext, "
|
||||
"clid, "
|
||||
"channel, "
|
||||
"dstchannel, "
|
||||
"lastapp, "
|
||||
"lastdata, "
|
||||
"start, "
|
||||
"answer, "
|
||||
"[end], "
|
||||
"duration, "
|
||||
"billsec, "
|
||||
"disposition, "
|
||||
"amaflags, "
|
||||
"uniqueid"
|
||||
") "
|
||||
"VALUES "
|
||||
"("
|
||||
"'%s', " /* accountcode */
|
||||
"'%s', " /* src */
|
||||
"'%s', " /* dst */
|
||||
"'%s', " /* dcontext */
|
||||
"'%s', " /* clid */
|
||||
"'%s', " /* channel */
|
||||
"'%s', " /* dstchannel */
|
||||
"'%s', " /* lastapp */
|
||||
"'%s', " /* lastdata */
|
||||
"%s, " /* start */
|
||||
"%s, " /* answer */
|
||||
"%s, " /* end */
|
||||
"%ld, " /* duration */
|
||||
"%ld, " /* billsec */
|
||||
"'%s', " /* disposition */
|
||||
"'%s', " /* amaflags */
|
||||
"'%s'" /* uniqueid */
|
||||
")",
|
||||
table,
|
||||
accountcode,
|
||||
src,
|
||||
dst,
|
||||
dcontext,
|
||||
clid,
|
||||
channel,
|
||||
dstchannel,
|
||||
lastapp,
|
||||
lastdata,
|
||||
start,
|
||||
answer,
|
||||
end,
|
||||
cdr->duration,
|
||||
cdr->billsec,
|
||||
ast_cdr_disp2str(cdr->disposition),
|
||||
ast_cdr_flags2str(cdr->amaflags),
|
||||
uniqueid
|
||||
);
|
||||
get_date(start, sizeof(start), cdr->start);
|
||||
get_date(answer, sizeof(answer), cdr->answer);
|
||||
get_date(end, sizeof(end), cdr->end);
|
||||
|
||||
if (has_userfield) {
|
||||
snprintf(
|
||||
sqlcmd,
|
||||
sizeof(sqlcmd),
|
||||
"INSERT INTO %s "
|
||||
"("
|
||||
"accountcode, "
|
||||
"src, "
|
||||
"dst, "
|
||||
"dcontext, "
|
||||
"clid, "
|
||||
"channel, "
|
||||
"dstchannel, "
|
||||
"lastapp, "
|
||||
"lastdata, "
|
||||
"start, "
|
||||
"answer, "
|
||||
"[end], "
|
||||
"duration, "
|
||||
"billsec, "
|
||||
"disposition, "
|
||||
"amaflags, "
|
||||
"uniqueid, "
|
||||
"userfield"
|
||||
") "
|
||||
"VALUES "
|
||||
"("
|
||||
"'%s', " /* accountcode */
|
||||
"'%s', " /* src */
|
||||
"'%s', " /* dst */
|
||||
"'%s', " /* dcontext */
|
||||
"'%s', " /* clid */
|
||||
"'%s', " /* channel */
|
||||
"'%s', " /* dstchannel */
|
||||
"'%s', " /* lastapp */
|
||||
"'%s', " /* lastdata */
|
||||
"%s, " /* start */
|
||||
"%s, " /* answer */
|
||||
"%s, " /* end */
|
||||
"%ld, " /* duration */
|
||||
"%ld, " /* billsec */
|
||||
"'%s', " /* disposition */
|
||||
"'%s', " /* amaflags */
|
||||
"'%s', " /* uniqueid */
|
||||
"'%s'" /* userfield */
|
||||
")",
|
||||
table,
|
||||
accountcode,
|
||||
src,
|
||||
dst,
|
||||
dcontext,
|
||||
clid,
|
||||
channel,
|
||||
dstchannel,
|
||||
lastapp,
|
||||
lastdata,
|
||||
start,
|
||||
answer,
|
||||
end,
|
||||
cdr->duration,
|
||||
cdr->billsec,
|
||||
ast_cdr_disp2str(cdr->disposition),
|
||||
ast_cdr_flags2str(cdr->amaflags),
|
||||
uniqueid,
|
||||
userfield
|
||||
);
|
||||
} else {
|
||||
snprintf(
|
||||
sqlcmd,
|
||||
sizeof(sqlcmd),
|
||||
"INSERT INTO %s "
|
||||
"("
|
||||
"accountcode, "
|
||||
"src, "
|
||||
"dst, "
|
||||
"dcontext, "
|
||||
"clid, "
|
||||
"channel, "
|
||||
"dstchannel, "
|
||||
"lastapp, "
|
||||
"lastdata, "
|
||||
"start, "
|
||||
"answer, "
|
||||
"[end], "
|
||||
"duration, "
|
||||
"billsec, "
|
||||
"disposition, "
|
||||
"amaflags, "
|
||||
"uniqueid"
|
||||
") "
|
||||
"VALUES "
|
||||
"("
|
||||
"'%s', " /* accountcode */
|
||||
"'%s', " /* src */
|
||||
"'%s', " /* dst */
|
||||
"'%s', " /* dcontext */
|
||||
"'%s', " /* clid */
|
||||
"'%s', " /* channel */
|
||||
"'%s', " /* dstchannel */
|
||||
"'%s', " /* lastapp */
|
||||
"'%s', " /* lastdata */
|
||||
"%s, " /* start */
|
||||
"%s, " /* answer */
|
||||
"%s, " /* end */
|
||||
"%ld, " /* duration */
|
||||
"%ld, " /* billsec */
|
||||
"'%s', " /* disposition */
|
||||
"'%s', " /* amaflags */
|
||||
"'%s'" /* uniqueid */
|
||||
")",
|
||||
table,
|
||||
accountcode,
|
||||
src,
|
||||
dst,
|
||||
dcontext,
|
||||
clid,
|
||||
channel,
|
||||
dstchannel,
|
||||
lastapp,
|
||||
lastdata,
|
||||
start,
|
||||
answer,
|
||||
end,
|
||||
cdr->duration,
|
||||
cdr->billsec,
|
||||
ast_cdr_disp2str(cdr->disposition),
|
||||
ast_cdr_flags2str(cdr->amaflags),
|
||||
uniqueid
|
||||
);
|
||||
}
|
||||
|
||||
do {
|
||||
if (!connected) {
|
||||
@@ -231,6 +306,9 @@ static int tds_log(struct ast_cdr *cdr)
|
||||
free(lastapp);
|
||||
free(lastdata);
|
||||
free(uniqueid);
|
||||
if (userfield) {
|
||||
free(userfield);
|
||||
}
|
||||
|
||||
ast_mutex_unlock(&tds_lock);
|
||||
|
||||
@@ -276,7 +354,7 @@ static char *anti_injection(const char *str, int len)
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void get_date(char *dateField, struct timeval tv)
|
||||
static void get_date(char *dateField, size_t length, struct timeval tv)
|
||||
{
|
||||
struct tm tm;
|
||||
time_t t;
|
||||
@@ -287,12 +365,12 @@ static void get_date(char *dateField, struct timeval tv)
|
||||
{
|
||||
t = tv.tv_sec;
|
||||
ast_localtime(&t, &tm, NULL);
|
||||
strftime(buf, 80, DATE_FORMAT, &tm);
|
||||
sprintf(dateField, "'%s'", buf);
|
||||
strftime(buf, sizeof(buf), DATE_FORMAT, &tm);
|
||||
snprintf(dateField, length, "'%s'", buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(dateField, "null");
|
||||
ast_copy_string(dateField, "null", length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,7 +403,7 @@ static int mssql_connect(void)
|
||||
#else
|
||||
TDSCONNECTINFO *connection = NULL;
|
||||
#endif
|
||||
char query[128];
|
||||
char query[512];
|
||||
|
||||
/* Connect to M$SQL Server */
|
||||
if (!(login = tds_alloc_login()))
|
||||
@@ -388,7 +466,7 @@ static int mssql_connect(void)
|
||||
#endif
|
||||
connection = NULL;
|
||||
|
||||
sprintf(query, "USE %s", dbname);
|
||||
snprintf(query, sizeof(query), "USE %s", dbname);
|
||||
#ifdef FREETDS_PRE_0_62
|
||||
if ((tds_submit_query(tds, query) != TDS_SUCCEED) || (tds_process_simple_query(tds, &result_type) != TDS_SUCCEED || result_type != TDS_CMD_SUCCEED))
|
||||
#else
|
||||
@@ -399,6 +477,29 @@ static int mssql_connect(void)
|
||||
goto connect_fail;
|
||||
}
|
||||
|
||||
snprintf(query, sizeof(query), "SELECT 1 FROM %s", table);
|
||||
#ifdef FREETDS_PRE_0_62
|
||||
if ((tds_submit_query(tds, query) != TDS_SUCCEED) || (tds_process_simple_query(tds, &result_type) != TDS_SUCCEED || result_type != TDS_CMD_SUCCEED))
|
||||
#else
|
||||
if ((tds_submit_query(tds, query) != TDS_SUCCEED) || (tds_process_simple_query(tds) != TDS_SUCCEED))
|
||||
#endif
|
||||
{
|
||||
ast_log(LOG_ERROR, "Could not find table '%s' in database '%s'\n", table, dbname);
|
||||
goto connect_fail;
|
||||
}
|
||||
|
||||
has_userfield = 1;
|
||||
snprintf(query, sizeof(query), "SELECT userfield FROM %s WHERE 1 = 0", table);
|
||||
#ifdef FREETDS_PRE_0_62
|
||||
if ((tds_submit_query(tds, query) != TDS_SUCCEED) || (tds_process_simple_query(tds, &result_type) != TDS_SUCCEED || result_type != TDS_CMD_SUCCEED))
|
||||
#else
|
||||
if ((tds_submit_query(tds, query) != TDS_SUCCEED) || (tds_process_simple_query(tds) != TDS_SUCCEED))
|
||||
#endif
|
||||
{
|
||||
ast_log(LOG_NOTICE, "Unable to find 'userfield' column in table '%s'\n", table);
|
||||
has_userfield = 0;
|
||||
}
|
||||
|
||||
connected = 1;
|
||||
return 0;
|
||||
|
||||
|
Reference in New Issue
Block a user