mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-25 22:18:07 +00:00
Argument macro janitor for func_odbc, fixes #7171
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@27522 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -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
|
|||||||
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
|
|||||||
{
|
{
|
||||||
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
|
|||||||
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
|
|||||||
} 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
|
|||||||
/* 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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user