aboutsummaryrefslogtreecommitdiffstats
path: root/cdr/cdr_tds.c
diff options
context:
space:
mode:
Diffstat (limited to 'cdr/cdr_tds.c')
-rw-r--r--cdr/cdr_tds.c249
1 files changed, 175 insertions, 74 deletions
diff --git a/cdr/cdr_tds.c b/cdr/cdr_tds.c
index 2536fae07..4e44e4ee1 100644
--- a/cdr/cdr_tds.c
+++ b/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);
-
- 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
- );
+ if (has_userfield) {
+ userfield = anti_injection(cdr->userfield, AST_MAX_USER_FIELD);
+ }
+
+ 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;