summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzuul <zuul@gerrit.asterisk.org>2016-09-19 15:21:39 -0500
committerGerrit Code Review <gerrit2@gerrit.digium.api>2016-09-19 15:21:39 -0500
commit9383beb0735c5e4ede371e3c34a45421035cd4be (patch)
tree2b658929e2718cdb99b9378fcf2073ea71bfa07a
parent4d64b176ebbd6ee6c51f028068a0d0d6ddaa4ac7 (diff)
parentcdbad152c79a042341288069f0713f6cc4a92410 (diff)
Merge "res_config_odbc.c: Fix buffer size limitation creating invalid SQL." into 13
-rw-r--r--res/res_config_odbc.c174
1 files changed, 94 insertions, 80 deletions
diff --git a/res/res_config_odbc.c b/res/res_config_odbc.c
index 2d991a586..893b9d897 100644
--- a/res/res_config_odbc.c
+++ b/res/res_config_odbc.c
@@ -47,6 +47,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/utils.h"
#include "asterisk/stringfields.h"
+/*! Initial SQL query buffer size to allocate. */
+#define SQL_BUF_SIZE 1024
+
AST_THREADSTORAGE(sql_buf);
AST_THREADSTORAGE(rowdata_buf);
@@ -114,7 +117,7 @@ static SQLHSTMT custom_prepare(struct odbc_obj *obj, void *data)
res = SQLPrepare(stmt, (unsigned char *)cps->sql, SQL_NTS);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", cps->sql);
+ ast_log(LOG_WARNING, "SQL Prepare failed! [%s]\n", cps->sql);
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
return NULL;
}
@@ -161,13 +164,13 @@ static SQLHSTMT custom_prepare(struct odbc_obj *obj, void *data)
*
* \retval var on success
* \retval NULL on failure
-*/
+ */
static struct ast_variable *realtime_odbc(const char *database, const char *table, const struct ast_variable *fields)
{
struct odbc_obj *obj;
SQLHSTMT stmt;
- char sql[1024];
char coltitle[256];
+ struct ast_str *sql = ast_str_thread_get(&sql_buf, SQL_BUF_SIZE);
struct ast_str *rowdata = ast_str_thread_get(&rowdata_buf, 128);
char *op;
const struct ast_variable *field = fields;
@@ -183,29 +186,30 @@ static struct ast_variable *realtime_odbc(const char *database, const char *tabl
SQLSMALLINT decimaldigits;
SQLSMALLINT nullable;
SQLLEN indicator;
- struct custom_prepare_struct cps = { .sql = sql, .fields = fields, };
+ struct custom_prepare_struct cps = { .fields = fields, };
struct ast_flags connected_flag = { RES_ODBC_CONNECTED };
- if (!table || !field) {
+ if (!table || !field || !sql || !rowdata) {
return NULL;
}
obj = ast_odbc_request_obj2(database, connected_flag);
-
if (!obj) {
ast_log(LOG_ERROR, "No database handle available with the name of '%s' (check res_odbc.conf)\n", database);
return NULL;
}
op = !strchr(field->name, ' ') ? " =" : "";
- snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s ?%s", table, field->name, op,
+ ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s ?%s", table, field->name, op,
strcasestr(field->name, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\\\'" : "");
while ((field = field->next)) {
op = !strchr(field->name, ' ') ? " =" : "";
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s ?%s", field->name, op,
+ ast_str_append(&sql, 0, " AND %s%s ?%s", field->name, op,
strcasestr(field->name, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\\\'" : "");
}
+ cps.sql = ast_str_buffer(sql);
+
if (ast_string_field_init(&cps, 256)) {
ast_odbc_release_obj(obj);
return NULL;
@@ -220,7 +224,7 @@ static struct ast_variable *realtime_odbc(const char *database, const char *tabl
res = SQLNumResultCols(stmt, &colcount);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL Column Count error! [%s]\n", ast_str_buffer(sql));
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
ast_odbc_release_obj(obj);
return NULL;
@@ -233,7 +237,7 @@ static struct ast_variable *realtime_odbc(const char *database, const char *tabl
return NULL;
}
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL Fetch error! [%s]\n", ast_str_buffer(sql));
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
ast_odbc_release_obj(obj);
return NULL;
@@ -244,7 +248,7 @@ static struct ast_variable *realtime_odbc(const char *database, const char *tabl
res = SQLDescribeCol(stmt, x + 1, (unsigned char *)coltitle, sizeof(coltitle), &collen,
&datatype, &colsize, &decimaldigits, &nullable);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL Describe Column error! [%s]\n", ast_str_buffer(sql));
if (var)
ast_variables_destroy(var);
ast_odbc_release_obj(obj);
@@ -273,7 +277,7 @@ static struct ast_variable *realtime_odbc(const char *database, const char *tabl
}
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL Get Data error! [%s]\n", ast_str_buffer(sql));
if (var)
ast_variables_destroy(var);
ast_odbc_release_obj(obj);
@@ -317,13 +321,13 @@ static struct ast_variable *realtime_odbc(const char *database, const char *tabl
*
* \retval var on success
* \retval NULL on failure
-*/
+ */
static struct ast_config *realtime_multi_odbc(const char *database, const char *table, const struct ast_variable *fields)
{
struct odbc_obj *obj;
SQLHSTMT stmt;
- char sql[1024];
char coltitle[256];
+ struct ast_str *sql = ast_str_thread_get(&sql_buf, SQL_BUF_SIZE);
struct ast_str *rowdata = ast_str_thread_get(&rowdata_buf, 128);
const char *initfield;
char *op;
@@ -343,9 +347,9 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char *
SQLSMALLINT decimaldigits;
SQLSMALLINT nullable;
SQLLEN indicator;
- struct custom_prepare_struct cps = { .sql = sql, .fields = fields, };
+ struct custom_prepare_struct cps = { .fields = fields, };
- if (!table || !field) {
+ if (!table || !field || !sql || !rowdata) {
return NULL;
}
@@ -360,15 +364,16 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char *
}
op = !strchr(field->name, ' ') ? " =" : "";
- snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s ?%s", table, field->name, op,
+ ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s ?%s", table, field->name, op,
strcasestr(field->name, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\\\'" : "");
while ((field = field->next)) {
op = !strchr(field->name, ' ') ? " =" : "";
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s ?%s", field->name, op,
+ ast_str_append(&sql, 0, " AND %s%s ?%s", field->name, op,
strcasestr(field->name, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\\\'" : "");
}
+ ast_str_append(&sql, 0, " ORDER BY %s", initfield);
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " ORDER BY %s", initfield);
+ cps.sql = ast_str_buffer(sql);
if (ast_string_field_init(&cps, 256)) {
ast_odbc_release_obj(obj);
@@ -384,7 +389,7 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char *
res = SQLNumResultCols(stmt, &colcount);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL Column Count error! [%s]\n", ast_str_buffer(sql));
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
ast_odbc_release_obj(obj);
return NULL;
@@ -401,7 +406,7 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char *
while ((res=SQLFetch(stmt)) != SQL_NO_DATA) {
var = NULL;
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL Fetch error! [%s]\n", ast_str_buffer(sql));
continue;
}
cat = ast_category_new("","",99999);
@@ -415,7 +420,7 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char *
res = SQLDescribeCol(stmt, x + 1, (unsigned char *)coltitle, sizeof(coltitle), &collen,
&datatype, &colsize, &decimaldigits, &nullable);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL Describe Column error! [%s]\n", ast_str_buffer(sql));
ast_category_destroy(cat);
goto next_sql_fetch;
}
@@ -440,7 +445,7 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char *
}
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL Get Data error! [%s]\n", ast_str_buffer(sql));
ast_category_destroy(cat);
goto next_sql_fetch;
}
@@ -482,21 +487,21 @@ next_sql_fetch:;
*
* \retval number of rows affected
* \retval -1 on failure
-*/
+ */
static int update_odbc(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *fields)
{
struct odbc_obj *obj;
SQLHSTMT stmt;
- char sql[256];
SQLLEN rowcount=0;
+ struct ast_str *sql = ast_str_thread_get(&sql_buf, SQL_BUF_SIZE);
const struct ast_variable *field = fields;
int res, count = 0, paramcount = 0;
- struct custom_prepare_struct cps = { .sql = sql, .extra = lookup, .fields = fields, };
+ struct custom_prepare_struct cps = { .extra = lookup, .fields = fields, };
struct odbc_cache_tables *tableptr;
struct odbc_cache_columns *column = NULL;
struct ast_flags connected_flag = { RES_ODBC_CONNECTED };
- if (!table || !field || !keyfield) {
+ if (!table || !field || !keyfield || !sql) {
return -1;
}
@@ -510,19 +515,19 @@ static int update_odbc(const char *database, const char *table, const char *keyf
ast_log(LOG_WARNING, "Key field '%s' does not exist in table '%s@%s'. Update will fail\n", keyfield, table, database);
}
- snprintf(sql, sizeof(sql), "UPDATE %s SET ", table);
+ ast_str_set(&sql, 0, "UPDATE %s SET ", table);
while (field) {
if ((tableptr && (column = ast_odbc_find_column(tableptr, field->name))) || count >= 64) {
if (paramcount++) {
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", ");
+ ast_str_append(&sql, 0, ", ");
}
/* NULL test for non-text columns */
if (count < 64 && ast_strlen_zero(field->value) && column->nullable && !is_text(column)) {
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s=NULL", field->name);
+ ast_str_append(&sql, 0, "%s=NULL", field->name);
cps.skip |= (1LL << count);
} else {
/* Value is not an empty string, or column is of text type, or we couldn't fit any more into cps.skip (count >= 64 ?!). */
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s=?", field->name);
+ ast_str_append(&sql, 0, "%s=?", field->name);
}
} else { /* the column does not exist in the table */
cps.skip |= (1LL << count);
@@ -530,9 +535,11 @@ static int update_odbc(const char *database, const char *table, const char *keyf
++count;
field = field->next;
}
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s=?", keyfield);
+ ast_str_append(&sql, 0, " WHERE %s=?", keyfield);
ast_odbc_release_table(tableptr);
+ cps.sql = ast_str_buffer(sql);
+
if (ast_string_field_init(&cps, 256)) {
ast_odbc_release_obj(obj);
return -1;
@@ -550,7 +557,7 @@ static int update_odbc(const char *database, const char *table, const char *keyf
ast_odbc_release_obj(obj);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Row Count error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL Row Count error! [%s]\n", ast_str_buffer(sql));
return -1;
}
@@ -573,17 +580,15 @@ static SQLHSTMT update2_prepare(struct odbc_obj *obj, void *data)
int res, x = 1, first = 1;
struct update2_prepare_struct *ups = data;
const struct ast_variable *field;
- struct ast_str *sql = ast_str_thread_get(&sql_buf, 16);
+ struct ast_str *sql = ast_str_thread_get(&sql_buf, SQL_BUF_SIZE);
SQLHSTMT stmt;
- struct odbc_cache_tables *tableptr = ast_odbc_find_table(ups->database, ups->table);
+ struct odbc_cache_tables *tableptr;
if (!sql) {
- if (tableptr) {
- ast_odbc_release_table(tableptr);
- }
return NULL;
}
+ tableptr = ast_odbc_find_table(ups->database, ups->table);
if (!tableptr) {
ast_log(LOG_ERROR, "Could not retrieve metadata for table '%s@%s'. Update will fail!\n", ups->table, ups->database);
return NULL;
@@ -628,7 +633,7 @@ static SQLHSTMT update2_prepare(struct odbc_obj *obj, void *data)
res = SQLPrepare(stmt, (unsigned char *)ast_str_buffer(sql), SQL_NTS);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", ast_str_buffer(sql));
+ ast_log(LOG_WARNING, "SQL Prepare failed! [%s]\n", ast_str_buffer(sql));
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
return NULL;
}
@@ -674,8 +679,9 @@ static int update2_odbc(const char *database, const char *table, const struct as
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
/* Since only a single thread can access this memory, we can retrieve what would otherwise be lost. */
- sql = ast_str_thread_get(&sql_buf, 16);
- ast_log(LOG_WARNING, "SQL Row Count error!\n[%s]\n", ast_str_buffer(sql));
+ sql = ast_str_thread_get(&sql_buf, SQL_BUF_SIZE);
+ ast_assert(sql != NULL);
+ ast_log(LOG_WARNING, "SQL Row Count error! [%s]\n", ast_str_buffer(sql));
return -1;
}
@@ -698,36 +704,47 @@ static int update2_odbc(const char *database, const char *table, const struct as
*
* \retval number of rows affected
* \retval -1 on failure
-*/
+ */
static int store_odbc(const char *database, const char *table, const struct ast_variable *fields)
{
struct odbc_obj *obj;
SQLHSTMT stmt;
- char sql[256];
- char keys[256];
- char vals[256];
SQLLEN rowcount=0;
const struct ast_variable *field = fields;
+ struct ast_str *keys;
+ struct ast_str *vals;
+ struct ast_str *sql = ast_str_thread_get(&sql_buf, SQL_BUF_SIZE);
int res;
- struct custom_prepare_struct cps = { .sql = sql, .extra = NULL, .fields = fields, };
+ struct custom_prepare_struct cps = { .fields = fields, };
struct ast_flags connected_flag = { RES_ODBC_CONNECTED };
- if (!table || !field) {
+ keys = ast_str_create(SQL_BUF_SIZE / 2);
+ vals = ast_str_create(SQL_BUF_SIZE / 4);
+ if (!table || !field || !keys || !vals || !sql) {
+ ast_free(vals);
+ ast_free(keys);
return -1;
}
obj = ast_odbc_request_obj2(database, connected_flag);
if (!obj) {
+ ast_free(vals);
+ ast_free(keys);
return -1;
}
- snprintf(keys, sizeof(keys), "%s", field->name);
- ast_copy_string(vals, "?", sizeof(vals));
+ ast_str_set(&keys, 0, "%s", field->name);
+ ast_str_set(&vals, 0, "?");
while ((field = field->next)) {
- snprintf(keys + strlen(keys), sizeof(keys) - strlen(keys), ", %s", field->name);
- snprintf(vals + strlen(vals), sizeof(vals) - strlen(vals), ", ?");
+ ast_str_append(&keys, 0, ", %s", field->name);
+ ast_str_append(&vals, 0, ", ?");
}
- snprintf(sql, sizeof(sql), "INSERT INTO %s (%s) VALUES (%s)", table, keys, vals);
+ ast_str_set(&sql, 0, "INSERT INTO %s (%s) VALUES (%s)",
+ table, ast_str_buffer(keys), ast_str_buffer(vals));
+
+ ast_free(vals);
+ ast_free(keys);
+ cps.sql = ast_str_buffer(sql);
if (ast_string_field_init(&cps, 256)) {
ast_odbc_release_obj(obj);
@@ -746,7 +763,7 @@ static int store_odbc(const char *database, const char *table, const struct ast_
ast_odbc_release_obj(obj);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Row Count error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL Row Count error! [%s]\n", ast_str_buffer(sql));
return -1;
}
@@ -770,19 +787,19 @@ static int store_odbc(const char *database, const char *table, const struct ast_
*
* \retval number of rows affected
* \retval -1 on failure
-*/
+ */
static int destroy_odbc(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *fields)
{
struct odbc_obj *obj;
SQLHSTMT stmt;
- char sql[256];
SQLLEN rowcount=0;
+ struct ast_str *sql = ast_str_thread_get(&sql_buf, SQL_BUF_SIZE);
const struct ast_variable *field;
int res;
- struct custom_prepare_struct cps = { .sql = sql, .extra = lookup, .fields = fields, };
+ struct custom_prepare_struct cps = { .extra = lookup, .fields = fields, };
struct ast_flags connected_flag = { RES_ODBC_CONNECTED };
- if (!table) {
+ if (!table || !sql) {
return -1;
}
@@ -791,12 +808,13 @@ static int destroy_odbc(const char *database, const char *table, const char *key
return -1;
}
- snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE ", table);
-
+ ast_str_set(&sql, 0, "DELETE FROM %s WHERE ", table);
for (field = fields; field; field = field->next) {
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s=? AND ", field->name);
+ ast_str_append(&sql, 0, "%s=? AND ", field->name);
}
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s=?", keyfield);
+ ast_str_append(&sql, 0, "%s=?", keyfield);
+
+ cps.sql = ast_str_buffer(sql);
if (ast_string_field_init(&cps, 256)) {
ast_odbc_release_obj(obj);
@@ -815,7 +833,7 @@ static int destroy_odbc(const char *database, const char *table, const char *key
ast_odbc_release_obj(obj);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Row Count error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL Row Count error! [%s]\n", ast_str_buffer(sql));
return -1;
}
@@ -893,9 +911,7 @@ static struct ast_config *config_odbc(const char *database, const char *table, c
struct ast_category *cur_cat;
int res = 0;
struct odbc_obj *obj;
- char sqlbuf[1024] = "";
- char *sql = sqlbuf;
- size_t sqlleft = sizeof(sqlbuf);
+ struct ast_str *sql = ast_str_thread_get(&sql_buf, SQL_BUF_SIZE);
unsigned int last_cat_metric = 0;
SQLSMALLINT rowcount = 0;
SQLHSTMT stmt;
@@ -906,21 +922,21 @@ static struct ast_config *config_odbc(const char *database, const char *table, c
memset(&q, 0, sizeof(q));
- if (!file || !strcmp (file, "res_config_odbc.conf"))
+ if (!file || !strcmp (file, "res_config_odbc.conf") || !sql) {
return NULL; /* cant configure myself with myself ! */
+ }
obj = ast_odbc_request_obj2(database, connected_flag);
if (!obj)
return NULL;
- q.sql = sqlbuf;
-
- ast_build_string(&sql, &sqlleft, "SELECT MAX(LENGTH(var_val)) FROM %s WHERE filename='%s'", table, file);
+ ast_str_set(&sql, 0, "SELECT MAX(LENGTH(var_val)) FROM %s WHERE filename='%s'",
+ table, file);
+ q.sql = ast_str_buffer(sql);
stmt = ast_odbc_prepare_and_execute(obj, length_determination_odbc_prepare, &q);
-
if (!stmt) {
- ast_log(LOG_WARNING, "SQL select error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL select error! [%s]\n", ast_str_buffer(sql));
ast_odbc_release_obj(obj);
return NULL;
}
@@ -928,7 +944,7 @@ static struct ast_config *config_odbc(const char *database, const char *table, c
res = SQLNumResultCols(stmt, &rowcount);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL NumResultCols error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL NumResultCols error! [%s]\n", ast_str_buffer(sql));
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
ast_odbc_release_obj(obj);
return NULL;
@@ -950,12 +966,11 @@ static struct ast_config *config_odbc(const char *database, const char *table, c
/* Reset stuff to a fresh state for the actual query which will retrieve all configuration */
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- sql = sqlbuf;
- sqlleft = sizeof(sqlbuf);
- ast_build_string(&sql, &sqlleft, "SELECT cat_metric, category, var_name, var_val FROM %s ", table);
- ast_build_string(&sql, &sqlleft, "WHERE filename='%s' AND commented=0 ", file);
- ast_build_string(&sql, &sqlleft, "ORDER BY cat_metric DESC, var_metric ASC, category, var_name ");
+ ast_str_set(&sql, 0, "SELECT cat_metric, category, var_name, var_val FROM %s ", table);
+ ast_str_append(&sql, 0, "WHERE filename='%s' AND commented=0 ", file);
+ ast_str_append(&sql, 0, "ORDER BY cat_metric DESC, var_metric ASC, category, var_name ");
+ q.sql = ast_str_buffer(sql);
q.var_val_size += 1;
q.var_val = ast_malloc(q.var_val_size);
@@ -966,9 +981,8 @@ static struct ast_config *config_odbc(const char *database, const char *table, c
}
stmt = ast_odbc_prepare_and_execute(obj, config_odbc_prepare, &q);
-
if (!stmt) {
- ast_log(LOG_WARNING, "SQL select error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL select error! [%s]\n", ast_str_buffer(sql));
ast_odbc_release_obj(obj);
ast_free(q.var_val);
return NULL;
@@ -977,7 +991,7 @@ static struct ast_config *config_odbc(const char *database, const char *table, c
res = SQLNumResultCols(stmt, &rowcount);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL NumResultCols error!\n[%s]\n\n", sql);
+ ast_log(LOG_WARNING, "SQL NumResultCols error! [%s]\n", ast_str_buffer(sql));
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
ast_odbc_release_obj(obj);
ast_free(q.var_val);