summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2016-09-12 18:00:22 -0500
committerRichard Mudgett <rmudgett@digium.com>2016-09-15 18:06:45 -0500
commitcdbad152c79a042341288069f0713f6cc4a92410 (patch)
treed26b229982ba6faa0d946394499d1b3346caf33f
parent11d05fc3699aa3547be722b83529bfecbe15ee4f (diff)
res_config_odbc.c: Fix buffer size limitation creating invalid SQL.
Creating ODBC SQL queries resulted in queries too large to fit into the supplied buffer. The resulting truncated buffer contained an invalid SQL query. * Made SQL query generation code use a thread storage buffer that can increase in size as needed. * Fixed bad multi-line warning messages. ASTERISK-26263 #close Reported by: Jeppe Ryskov Larsen Change-Id: I23f3cdd43c2dac80bed3ded4dd77d18cb17f21ae
-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);