Skip to content
Snippets Groups Projects
Commit 9c7099fa authored by Sean Bright's avatar Sean Bright
Browse files

Log the userfield CDR variable like the other CDR backends, assuming the

column is actually there.  If it's not, we still log everything else as
before.

(closes issue #13281)
Reported by: falves11


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@137203 65c4cc65-6c06-0410-ace0-fbb531ad65f3
parent 37133a69
No related branches found
No related tags found
No related merge requests found
......@@ -168,7 +168,8 @@ CDR:
systemname was too long, the uniqueid would have been truncated.
* The cdr_tds module now supports all versions of FreeTDS that contain
the db-lib frontend.
the db-lib frontend. It will also now log the userfield variable if
the target database table contains a column for it.
Formats:
......
......@@ -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
......@@ -91,6 +92,7 @@ struct cdr_tds_config {
);
DBPROCESS *dbproc;
unsigned int connected:1;
unsigned int has_userfield:1;
};
AST_MUTEX_DEFINE_STATIC(tds_lock);
......@@ -100,13 +102,16 @@ static struct cdr_tds_config *settings;
static char *anti_injection(const char *, int);
static void get_date(char *, size_t len, struct timeval);
static int execute_and_consume(DBPROCESS *dbproc, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
static int mssql_connect(void);
static int mssql_disconnect(void);
static int tds_log(struct ast_cdr *cdr)
{
char 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;
RETCODE erc;
int res = -1;
......@@ -127,6 +132,10 @@ static int tds_log(struct ast_cdr *cdr)
ast_mutex_lock(&tds_lock);
if (settings->has_userfield) {
userfield = anti_injection(cdr->userfield, AST_MAX_USER_FIELD);
}
/* Ensure that we are connected */
if (!settings->connected) {
if (mssql_connect()) {
......@@ -135,66 +144,46 @@ static int tds_log(struct ast_cdr *cdr)
}
}
erc = dbfcmd(settings->dbproc,
"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 */
")",
settings->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
);
if (settings->has_userfield) {
erc = dbfcmd(settings->dbproc,
"INSERT INTO %s "
"("
"accountcode, src, dst, dcontext, clid, channel, "
"dstchannel, lastapp, lastdata, start, answer, [end], duration, "
"billsec, disposition, amaflags, uniqueid, userfield"
") "
"VALUES "
"("
"'%s', '%s', '%s', '%s', '%s', '%s', "
"'%s', '%s', '%s', %s, %s, %s, %ld, "
"%ld, '%s', '%s', '%s', '%s'"
")",
settings->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 {
erc = dbfcmd(settings->dbproc,
"INSERT INTO %s "
"("
"accountcode, src, dst, dcontext, clid, channel, "
"dstchannel, lastapp, lastdata, start, answer, [end], duration, "
"billsec, disposition, amaflags, uniqueid"
") "
"VALUES "
"("
"'%s', '%s', '%s', '%s', '%s', '%s', "
"'%s', '%s', '%s', %s, %s, %s, %ld, "
"%ld, '%s', '%s', '%s'"
")",
settings->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
);
}
if (erc == FAIL) {
ast_log(LOG_ERROR, "Failed to build INSERT statement, no CDR was logged.\n");
......@@ -228,6 +217,10 @@ done:
ast_free(lastdata);
ast_free(uniqueid);
if (userfield) {
ast_free(userfield);
}
return res;
}
......@@ -277,6 +270,37 @@ static void get_date(char *dateField, size_t len, struct timeval when)
}
}
static int execute_and_consume(DBPROCESS *dbproc, const char *fmt, ...)
{
va_list ap;
char *buffer;
va_start(ap, fmt);
if (vasprintf(&buffer, fmt, ap) < 0) {
va_end(ap);
return 1;
}
va_end(ap);
if (dbfcmd(dbproc, buffer) == FAIL) {
free(buffer);
return 1;
}
free(buffer);
if (dbsqlexec(dbproc) == FAIL) {
return 1;
}
/* Consume the result set (we don't really care about the result, though) */
while (dbresults(dbproc) != NO_MORE_RESULTS) {
while (dbnextrow(dbproc) != NO_MORE_ROWS);
}
return 0;
}
static int mssql_disconnect(void)
{
if (settings->dbproc) {
......@@ -317,19 +341,17 @@ static int mssql_connect(void)
goto failed;
}
if (dbfcmd(settings->dbproc, "SELECT 1 FROM [%s]", settings->table) == FAIL) {
ast_log(LOG_ERROR, "Unable to build query while verifying the existence of table '%s'\n", settings->table);
if (execute_and_consume(settings->dbproc, "SELECT 1 FROM [%s]", settings->table)) {
ast_log(LOG_ERROR, "Unable to find table '%s'\n", settings->table);
goto failed;
}
if (dbsqlexec(settings->dbproc) == FAIL) {
ast_log(LOG_ERROR, "Unable to verify existence of table '%s'\n", settings->table);
goto failed;
}
/* Consume the result set (we don't really care about the result, though) */
while (dbresults(settings->dbproc) != NO_MORE_RESULTS) {
while (dbnextrow(settings->dbproc) != NO_MORE_ROWS);
/* Check to see if we have a userfield column in the table */
if (execute_and_consume(settings->dbproc, "SELECT userfield FROM [%s] WHERE 1 = 0", settings->table)) {
ast_log(LOG_NOTICE, "Unable to find 'userfield' column in table '%s'\n", settings->table);
settings->has_userfield = 0;
} else {
settings->has_userfield = 1;
}
settings->connected = 1;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment