Skip to content
Snippets Groups Projects
Commit 912f9f9d authored by Tilghman Lesher's avatar Tilghman Lesher
Browse files

Argument macro janitor for func_odbc, fixes #7171

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@27522 65c4cc65-6c06-0410-ace0-fbb531ad65f3
parent eeb21849
No related branches found
No related tags found
No related merge requests found
...@@ -81,9 +81,14 @@ static int acf_odbc_write(struct ast_channel *chan, char *cmd, char *s, const ch ...@@ -81,9 +81,14 @@ static int acf_odbc_write(struct ast_channel *chan, char *cmd, char *s, const ch
{ {
struct odbc_obj *obj; struct odbc_obj *obj;
struct acf_odbc_query *query; struct acf_odbc_query *query;
char *t, *arg, buf[2048]="", varname[15]; char *t, buf[2048]="", varname[15];
int res, argcount=0, valcount=0, i, retry=0; int res, i, retry=0;
struct ast_channel *ast; AST_DECLARE_APP_ARGS(values,
AST_APP_ARG(field)[100];
);
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(field)[100];
);
SQLHSTMT stmt; SQLHSTMT stmt;
SQLINTEGER nativeerror=0, numfields=0, rows=0; SQLINTEGER nativeerror=0, numfields=0, rows=0;
SQLSMALLINT diagbytes=0; SQLSMALLINT diagbytes=0;
...@@ -123,52 +128,37 @@ static int acf_odbc_write(struct ast_channel *chan, char *cmd, char *s, const ch ...@@ -123,52 +128,37 @@ static int acf_odbc_write(struct ast_channel *chan, char *cmd, char *s, const ch
return -1; return -1;
} }
/* XXX You might be tempted to change this section into using AST_STANDARD_APP_ARGS(args, s);
* pbx_builtin_pushvar_helper(). However, note that if you try for (i = 0; i < args.argc; i++) {
* to set a NULL (like for VALUE), then nothing gets set, and the snprintf(varname, sizeof(varname), "ARG%d", i + 1);
* value doesn't get masked out. Even worse, when you subsequently pbx_builtin_pushvar_helper(chan, varname, args.field[i]);
* try to remove the value you just set, you'll wind up unsetting
* the previous value (which is wholly undesireable). Hence, this
* has to remain the way it is done here. XXX
*/
/* Save old arguments as variables in a fake channel */
ast = ast_channel_alloc(0);
while ((arg = strsep(&s, "|"))) {
argcount++;
snprintf(varname, sizeof(varname), "ARG%d", argcount);
pbx_builtin_setvar_helper(ast, varname, pbx_builtin_getvar_helper(chan, varname));
pbx_builtin_setvar_helper(chan, varname, arg);
} }
/* Parse values, just like arguments */ /* Parse values, just like arguments */
while ((arg = strsep(&t, "|"))) { /* Can't use the pipe, because app Set removes them */
valcount++; AST_NONSTANDARD_APP_ARGS(values, t, ',');
snprintf(varname, sizeof(varname), "VAL%d", valcount); for (i = 0; i < values.argc; i++) {
pbx_builtin_setvar_helper(ast, varname, pbx_builtin_getvar_helper(chan, varname)); snprintf(varname, sizeof(varname), "VAL%d", i + 1);
pbx_builtin_setvar_helper(chan, varname, arg); pbx_builtin_pushvar_helper(chan, varname, values.field[i]);
} }
/* Additionally set the value as a whole */ /* Additionally set the value as a whole (but push an empty string if value is NULL) */
/* Note that pbx_builtin_setvar_helper will quite happily take a NULL for the 3rd argument */ pbx_builtin_pushvar_helper(chan, "VALUE", value ? value : "");
pbx_builtin_setvar_helper(ast, "VALUE", pbx_builtin_getvar_helper(chan, "VALUE"));
pbx_builtin_setvar_helper(chan, "VALUE", value);
pbx_substitute_variables_helper(chan, query->sql_write, buf, sizeof(buf) - 1); pbx_substitute_variables_helper(chan, query->sql_write, buf, sizeof(buf) - 1);
/* Restore prior values */ /* Restore prior values */
for (i=1; i<=argcount; i++) { for (i = 0; i < args.argc; i++) {
snprintf(varname, sizeof(varname), "ARG%d", argcount); snprintf(varname, sizeof(varname), "ARG%d", i + 1);
pbx_builtin_setvar_helper(chan, varname, pbx_builtin_getvar_helper(ast, varname)); pbx_builtin_setvar_helper(chan, varname, NULL);
} }
for (i=1; i<=valcount; i++) { for (i = 0; i < values.argc; i++) {
snprintf(varname, sizeof(varname), "VAL%d", argcount); snprintf(varname, sizeof(varname), "VAL%d", i + 1);
pbx_builtin_setvar_helper(chan, varname, pbx_builtin_getvar_helper(ast, varname)); pbx_builtin_setvar_helper(chan, varname, NULL);
} }
pbx_builtin_setvar_helper(chan, "VALUE", pbx_builtin_getvar_helper(ast, "VALUE")); pbx_builtin_setvar_helper(chan, "VALUE", NULL);
ast_channel_free(ast);
AST_LIST_UNLOCK(&queries); AST_LIST_UNLOCK(&queries);
retry_write: retry_write:
...@@ -239,8 +229,11 @@ static int acf_odbc_read(struct ast_channel *chan, char *cmd, char *s, char *buf ...@@ -239,8 +229,11 @@ static int acf_odbc_read(struct ast_channel *chan, char *cmd, char *s, char *buf
{ {
struct odbc_obj *obj; struct odbc_obj *obj;
struct acf_odbc_query *query; struct acf_odbc_query *query;
char *arg, sql[2048] = "", varname[15]; char sql[2048] = "", varname[15];
int count=0, res, x, buflen = 0; int res, x, buflen = 0;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(field)[100];
);
SQLHSTMT stmt; SQLHSTMT stmt;
SQLSMALLINT colcount=0; SQLSMALLINT colcount=0;
SQLINTEGER indicator; SQLINTEGER indicator;
...@@ -275,18 +268,17 @@ static int acf_odbc_read(struct ast_channel *chan, char *cmd, char *s, char *buf ...@@ -275,18 +268,17 @@ static int acf_odbc_read(struct ast_channel *chan, char *cmd, char *s, char *buf
SQLSetConnectAttr(obj->con, SQL_ATTR_TRACEFILE, tracefile, strlen(tracefile)); SQLSetConnectAttr(obj->con, SQL_ATTR_TRACEFILE, tracefile, strlen(tracefile));
#endif #endif
while ((arg = strsep(&s, "|"))) { AST_STANDARD_APP_ARGS(args, s);
count++; for (x = 0; x < args.argc; x++) {
snprintf(varname, sizeof(varname), "ARG%d", count); snprintf(varname, sizeof(varname), "ARG%d", x + 1);
/* arg is by definition non-NULL, so this works, here */ pbx_builtin_pushvar_helper(chan, varname, args.field[x]);
pbx_builtin_pushvar_helper(chan, varname, arg);
} }
pbx_substitute_variables_helper(chan, query->sql_read, sql, sizeof(sql) - 1); pbx_substitute_variables_helper(chan, query->sql_read, sql, sizeof(sql) - 1);
/* Restore prior values */ /* Restore prior values */
for (x = 1; x <= count; x++) { for (x = 0; x < args.argc; x++) {
snprintf(varname, sizeof(varname), "ARG%d", x); snprintf(varname, sizeof(varname), "ARG%d", x + 1);
pbx_builtin_setvar_helper(chan, varname, NULL); pbx_builtin_setvar_helper(chan, varname, NULL);
} }
...@@ -330,7 +322,8 @@ static int acf_odbc_read(struct ast_channel *chan, char *cmd, char *s, char *buf ...@@ -330,7 +322,8 @@ static int acf_odbc_read(struct ast_channel *chan, char *cmd, char *s, char *buf
} else if (option_verbose > 3) { } else if (option_verbose > 3) {
ast_log(LOG_WARNING, "Error %d in FETCH [%s]\n", res, sql); ast_log(LOG_WARNING, "Error %d in FETCH [%s]\n", res, sql);
} }
goto acf_out; SQLFreeHandle(SQL_HANDLE_STMT, stmt);
return 0;
} }
for (x = 0; x < colcount; x++) { for (x = 0; x < colcount; x++) {
...@@ -369,7 +362,6 @@ static int acf_odbc_read(struct ast_channel *chan, char *cmd, char *s, char *buf ...@@ -369,7 +362,6 @@ static int acf_odbc_read(struct ast_channel *chan, char *cmd, char *s, char *buf
/* Trim trailing comma */ /* Trim trailing comma */
buf[buflen - 1] = '\0'; buf[buflen - 1] = '\0';
acf_out:
SQLFreeHandle(SQL_HANDLE_STMT, stmt); SQLFreeHandle(SQL_HANDLE_STMT, stmt);
return 0; return 0;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment