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
This commit is contained in:
Sean Bright 2008-08-11 14:25:15 +00:00
parent 37133a6993
commit 9c7099faae
2 changed files with 96 additions and 73 deletions

View File

@ -168,7 +168,8 @@ CDR:
systemname was too long, the uniqueid would have been truncated. systemname was too long, the uniqueid would have been truncated.
* The cdr_tds module now supports all versions of FreeTDS that contain * 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: Formats:

View File

@ -48,7 +48,8 @@ CREATE TABLE [dbo].[cdr] (
[billsec] [int] NULL , [billsec] [int] NULL ,
[disposition] [varchar] (20) NULL , [disposition] [varchar] (20) NULL ,
[amaflags] [varchar] (16) NULL , [amaflags] [varchar] (16) NULL ,
[uniqueid] [varchar] (32) NULL [uniqueid] [varchar] (32) NULL ,
[userfield] [varchar] (256) NULL
) ON [PRIMARY] ) ON [PRIMARY]
\endverbatim \endverbatim
@ -91,6 +92,7 @@ struct cdr_tds_config {
); );
DBPROCESS *dbproc; DBPROCESS *dbproc;
unsigned int connected:1; unsigned int connected:1;
unsigned int has_userfield:1;
}; };
AST_MUTEX_DEFINE_STATIC(tds_lock); AST_MUTEX_DEFINE_STATIC(tds_lock);
@ -100,13 +102,16 @@ static struct cdr_tds_config *settings;
static char *anti_injection(const char *, int); static char *anti_injection(const char *, int);
static void get_date(char *, size_t len, struct timeval); 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_connect(void);
static int mssql_disconnect(void); static int mssql_disconnect(void);
static int tds_log(struct ast_cdr *cdr) static int tds_log(struct ast_cdr *cdr)
{ {
char start[80], answer[80], end[80]; 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; RETCODE erc;
int res = -1; int res = -1;
@ -127,6 +132,10 @@ static int tds_log(struct ast_cdr *cdr)
ast_mutex_lock(&tds_lock); ast_mutex_lock(&tds_lock);
if (settings->has_userfield) {
userfield = anti_injection(cdr->userfield, AST_MAX_USER_FIELD);
}
/* Ensure that we are connected */ /* Ensure that we are connected */
if (!settings->connected) { if (!settings->connected) {
if (mssql_connect()) { if (mssql_connect()) {
@ -135,66 +144,46 @@ static int tds_log(struct ast_cdr *cdr)
} }
} }
erc = dbfcmd(settings->dbproc, if (settings->has_userfield) {
"INSERT INTO %s " erc = dbfcmd(settings->dbproc,
"(" "INSERT INTO %s "
"accountcode, " "("
"src, " "accountcode, src, dst, dcontext, clid, channel, "
"dst, " "dstchannel, lastapp, lastdata, start, answer, [end], duration, "
"dcontext, " "billsec, disposition, amaflags, uniqueid, userfield"
"clid, " ") "
"channel, " "VALUES "
"dstchannel, " "("
"lastapp, " "'%s', '%s', '%s', '%s', '%s', '%s', "
"lastdata, " "'%s', '%s', '%s', %s, %s, %s, %ld, "
"start, " "%ld, '%s', '%s', '%s', '%s'"
"answer, " ")",
"[end], " settings->table,
"duration, " accountcode, src, dst, dcontext, clid, channel,
"billsec, " dstchannel, lastapp, lastdata, start, answer, end, cdr->duration,
"disposition, " cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_cdr_flags2str(cdr->amaflags), uniqueid,
"amaflags, " userfield
"uniqueid" );
") " } else {
"VALUES " erc = dbfcmd(settings->dbproc,
"(" "INSERT INTO %s "
"'%s', " /* accountcode */ "("
"'%s', " /* src */ "accountcode, src, dst, dcontext, clid, channel, "
"'%s', " /* dst */ "dstchannel, lastapp, lastdata, start, answer, [end], duration, "
"'%s', " /* dcontext */ "billsec, disposition, amaflags, uniqueid"
"'%s', " /* clid */ ") "
"'%s', " /* channel */ "VALUES "
"'%s', " /* dstchannel */ "("
"'%s', " /* lastapp */ "'%s', '%s', '%s', '%s', '%s', '%s', "
"'%s', " /* lastdata */ "'%s', '%s', '%s', %s, %s, %s, %ld, "
"%s, " /* start */ "%ld, '%s', '%s', '%s'"
"%s, " /* answer */ ")",
"%s, " /* end */ settings->table,
"%ld, " /* duration */ accountcode, src, dst, dcontext, clid, channel,
"%ld, " /* billsec */ dstchannel, lastapp, lastdata, start, answer, end, cdr->duration,
"'%s', " /* disposition */ cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_cdr_flags2str(cdr->amaflags), uniqueid
"'%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 (erc == FAIL) { if (erc == FAIL) {
ast_log(LOG_ERROR, "Failed to build INSERT statement, no CDR was logged.\n"); ast_log(LOG_ERROR, "Failed to build INSERT statement, no CDR was logged.\n");
@ -228,6 +217,10 @@ done:
ast_free(lastdata); ast_free(lastdata);
ast_free(uniqueid); ast_free(uniqueid);
if (userfield) {
ast_free(userfield);
}
return res; 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) static int mssql_disconnect(void)
{ {
if (settings->dbproc) { if (settings->dbproc) {
@ -317,19 +341,17 @@ static int mssql_connect(void)
goto failed; goto failed;
} }
if (dbfcmd(settings->dbproc, "SELECT 1 FROM [%s]", settings->table) == FAIL) { if (execute_and_consume(settings->dbproc, "SELECT 1 FROM [%s]", settings->table)) {
ast_log(LOG_ERROR, "Unable to build query while verifying the existence of table '%s'\n", settings->table); ast_log(LOG_ERROR, "Unable to find table '%s'\n", settings->table);
goto failed; goto failed;
} }
if (dbsqlexec(settings->dbproc) == FAIL) { /* Check to see if we have a userfield column in the table */
ast_log(LOG_ERROR, "Unable to verify existence of table '%s'\n", settings->table); if (execute_and_consume(settings->dbproc, "SELECT userfield FROM [%s] WHERE 1 = 0", settings->table)) {
goto failed; ast_log(LOG_NOTICE, "Unable to find 'userfield' column in table '%s'\n", settings->table);
} settings->has_userfield = 0;
} else {
/* Consume the result set (we don't really care about the result, though) */ settings->has_userfield = 1;
while (dbresults(settings->dbproc) != NO_MORE_RESULTS) {
while (dbnextrow(settings->dbproc) != NO_MORE_ROWS);
} }
settings->connected = 1; settings->connected = 1;