diff options
Diffstat (limited to 'res')
-rw-r--r-- | res/res_agi.c | 13 | ||||
-rw-r--r-- | res/res_config_curl.c | 236 | ||||
-rw-r--r-- | res/res_phoneprov.c | 102 |
3 files changed, 205 insertions, 146 deletions
diff --git a/res/res_agi.c b/res/res_agi.c index 24dd5d0bb..7eebf7c61 100644 --- a/res/res_agi.c +++ b/res/res_agi.c @@ -1828,8 +1828,7 @@ static int handle_getvariable(struct ast_channel *chan, AGI *agi, int argc, char static int handle_getvariablefull(struct ast_channel *chan, AGI *agi, int argc, char **argv) { - char tmp[4096]; - struct ast_channel *chan2=NULL; + struct ast_channel *chan2 = NULL; if (argc != 4 && argc != 5) { return RESULT_SHOWUSAGE; @@ -1842,8 +1841,14 @@ static int handle_getvariablefull(struct ast_channel *chan, AGI *agi, int argc, } if (chan2) { - pbx_substitute_variables_helper(chan2, argv[3], tmp, sizeof(tmp) - 1); - ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", tmp); + struct ast_str *str = ast_str_create(16); + if (!str) { + ast_agi_send(agi->fd, chan, "200 result=0\n"); + return RESULT_SUCCESS; + } + ast_str_substitute_variables(&str, 0, chan2, argv[3]); + ast_agi_send(agi->fd, chan, "200 result=1 (%s)\n", ast_str_buffer(str)); + ast_free(str); } else { ast_agi_send(agi->fd, chan, "200 result=0\n"); } diff --git a/res/res_config_curl.c b/res/res_config_curl.c index 1d259c845..928a6ae3b 100644 --- a/res/res_config_curl.c +++ b/res/res_config_curl.c @@ -43,6 +43,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/module.h" #include "asterisk/lock.h" #include "asterisk/utils.h" +#include "asterisk/threadstorage.h" + +AST_THREADSTORAGE(query_buf); +AST_THREADSTORAGE(result_buf); /*! * \brief Execute a curl query and return ast_variable list @@ -55,25 +59,24 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") */ static struct ast_variable *realtime_curl(const char *url, const char *unused, va_list ap) { - struct ast_str *query; - char buf1[200], buf2[200]; + struct ast_str *query, *buffer; + char buf1[256], buf2[256]; const char *newparam, *newval; char *stringp, *pair, *key; int i; - struct ast_variable *var=NULL, *prev=NULL; - const int EncodeSpecialChars = 1, bufsize = 64000; - char *buffer; + struct ast_variable *var = NULL, *prev = NULL; + const int EncodeSpecialChars = 1; if (!ast_custom_function_find("CURL")) { ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n"); return NULL; } - if (!(query = ast_str_create(1000))) + if (!(query = ast_str_thread_get(&query_buf, 16))) { return NULL; + } - if (!(buffer = ast_malloc(bufsize))) { - ast_free(query); + if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return NULL; } @@ -88,31 +91,33 @@ static struct ast_variable *realtime_curl(const char *url, const char *unused, v va_end(ap); ast_str_append(&query, 0, ")}"); - pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, bufsize); + ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); /* Remove any trailing newline characters */ - if ((stringp = strchr(buffer, '\r')) || (stringp = strchr(buffer, '\n'))) + if ((stringp = strchr(ast_str_buffer(buffer), '\r')) || (stringp = strchr(ast_str_buffer(buffer), '\n'))) { *stringp = '\0'; + } - stringp = buffer; + stringp = ast_str_buffer(buffer); while ((pair = strsep(&stringp, "&"))) { key = strsep(&pair, "="); ast_uri_decode(key); - if (pair) + if (pair) { ast_uri_decode(pair); + } if (!ast_strlen_zero(key)) { if (prev) { prev->next = ast_variable_new(key, S_OR(pair, ""), ""); - if (prev->next) + if (prev->next) { prev = prev->next; - } else + } + } else { prev = var = ast_variable_new(key, S_OR(pair, ""), ""); + } } } - ast_free(buffer); - ast_free(query); return var; } @@ -127,27 +132,26 @@ static struct ast_variable *realtime_curl(const char *url, const char *unused, v */ static struct ast_config *realtime_multi_curl(const char *url, const char *unused, va_list ap) { - struct ast_str *query; - char buf1[200], buf2[200]; + struct ast_str *query, *buffer; + char buf1[256], buf2[256]; const char *newparam, *newval; char *stringp, *line, *pair, *key, *initfield = NULL; int i; - const int EncodeSpecialChars = 1, bufsize = 256000; - struct ast_variable *var=NULL; - struct ast_config *cfg=NULL; - struct ast_category *cat=NULL; - char *buffer; + const int EncodeSpecialChars = 1; + struct ast_variable *var = NULL; + struct ast_config *cfg = NULL; + struct ast_category *cat = NULL; if (!ast_custom_function_find("CURL")) { ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n"); return NULL; } - if (!(query = ast_str_create(1000))) + if (!(query = ast_str_thread_get(&query_buf, 16))) { return NULL; + } - if (!(buffer = ast_malloc(bufsize))) { - ast_free(query); + if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return NULL; } @@ -170,28 +174,33 @@ static struct ast_config *realtime_multi_curl(const char *url, const char *unuse ast_str_append(&query, 0, ")}"); /* Do the CURL query */ - pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, bufsize); + ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); - if (!(cfg = ast_config_new())) - goto exit_multi; + if (!(cfg = ast_config_new())) { + return NULL; + } /* Line oriented output */ - stringp = buffer; + stringp = ast_str_buffer(buffer); while ((line = strsep(&stringp, "\r\n"))) { - if (ast_strlen_zero(line)) + if (ast_strlen_zero(line)) { continue; + } - if (!(cat = ast_category_new("", "", 99999))) + if (!(cat = ast_category_new("", "", 99999))) { continue; + } while ((pair = strsep(&line, "&"))) { key = strsep(&pair, "="); ast_uri_decode(key); - if (pair) + if (pair) { ast_uri_decode(pair); + } - if (!strcasecmp(key, initfield) && pair) + if (!strcasecmp(key, initfield) && pair) { ast_category_rename(cat, pair); + } if (!ast_strlen_zero(key)) { var = ast_variable_new(key, S_OR(pair, ""), ""); @@ -201,9 +210,6 @@ static struct ast_config *realtime_multi_curl(const char *url, const char *unuse ast_category_append(cfg, cat); } -exit_multi: - ast_free(buffer); - ast_free(query); return cfg; } @@ -224,24 +230,23 @@ exit_multi: */ static int update_curl(const char *url, const char *unused, const char *keyfield, const char *lookup, va_list ap) { - struct ast_str *query; - char buf1[200], buf2[200]; + struct ast_str *query, *buffer; + char buf1[256], buf2[256]; const char *newparam, *newval; char *stringp; int i, rowcount = -1; - const int EncodeSpecialChars = 1, bufsize = 100; - char *buffer; + const int EncodeSpecialChars = 1; if (!ast_custom_function_find("CURL")) { ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n"); return -1; } - if (!(query = ast_str_create(1000))) + if (!(query = ast_str_thread_get(&query_buf, 16))) { return -1; + } - if (!(buffer = ast_malloc(bufsize))) { - ast_free(query); + if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return -1; } @@ -258,43 +263,40 @@ static int update_curl(const char *url, const char *unused, const char *keyfield va_end(ap); ast_str_append(&query, 0, ")}"); - pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, bufsize); + ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); /* Line oriented output */ - stringp = buffer; - while (*stringp <= ' ') + stringp = ast_str_buffer(buffer); + while (*stringp <= ' ') { stringp++; + } sscanf(stringp, "%d", &rowcount); - ast_free(buffer); - ast_free(query); - - if (rowcount >= 0) + if (rowcount >= 0) { return (int)rowcount; + } return -1; } static int update2_curl(const char *url, const char *unused, va_list ap) { - struct ast_str *query; + struct ast_str *query, *buffer; char buf1[200], buf2[200]; const char *newparam, *newval; char *stringp; int rowcount = -1, lookup = 1, first = 1; - const int EncodeSpecialChars = 1, bufsize = 100; - char *buffer; + const int EncodeSpecialChars = 1; if (!ast_custom_function_find("CURL")) { ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n"); return -1; } - if (!(query = ast_str_create(1000))) + if (!(query = ast_str_thread_get(&query_buf, 1000))) return -1; - if (!(buffer = ast_malloc(bufsize))) { - ast_free(query); + if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return -1; } @@ -316,24 +318,27 @@ static int update2_curl(const char *url, const char *unused, va_list ap) ast_uri_encode(newparam, buf1, sizeof(buf1), EncodeSpecialChars); ast_uri_encode(newval, buf2, sizeof(buf2), EncodeSpecialChars); ast_str_append(&query, 0, "%s%s=%s", first ? "" : "&", buf1, buf2); + first = 0; } va_end(ap); ast_str_append(&query, 0, ")}"); - /* TODO: Make proxies work */ - pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, bufsize); + /* Proxies work, by setting CURLOPT options in the [globals] section of + * extensions.conf. Unfortunately, this means preloading pbx_config.so + * so that they have an opportunity to be set prior to startup realtime + * queries. */ + ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); /* Line oriented output */ - stringp = buffer; - while (*stringp <= ' ') + stringp = ast_str_buffer(buffer); + while (*stringp <= ' ') { stringp++; + } sscanf(stringp, "%d", &rowcount); - ast_free(buffer); - ast_free(query); - - if (rowcount >= 0) + if (rowcount >= 0) { return (int)rowcount; + } return -1; } @@ -353,24 +358,23 @@ static int update2_curl(const char *url, const char *unused, va_list ap) */ static int store_curl(const char *url, const char *unused, va_list ap) { - struct ast_str *query; - char buf1[200], buf2[200]; + struct ast_str *query, *buffer; + char buf1[256], buf2[256]; const char *newparam, *newval; char *stringp; int i, rowcount = -1; - const int EncodeSpecialChars = 1, bufsize = 100; - char *buffer; + const int EncodeSpecialChars = 1; if (!ast_custom_function_find("CURL")) { ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n"); return -1; } - if (!(query = ast_str_create(1000))) + if (!(query = ast_str_thread_get(&query_buf, 1000))) { return -1; + } - if (!(buffer = ast_malloc(bufsize))) { - ast_free(query); + if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return -1; } @@ -385,18 +389,17 @@ static int store_curl(const char *url, const char *unused, va_list ap) va_end(ap); ast_str_append(&query, 0, ")}"); - pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, bufsize); + ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); - stringp = buffer; - while (*stringp <= ' ') + stringp = ast_str_buffer(buffer); + while (*stringp <= ' ') { stringp++; + } sscanf(stringp, "%d", &rowcount); - ast_free(buffer); - ast_free(query); - - if (rowcount >= 0) - return (int)rowcount; + if (rowcount >= 0) { + return rowcount; + } return -1; } @@ -418,24 +421,23 @@ static int store_curl(const char *url, const char *unused, va_list ap) */ static int destroy_curl(const char *url, const char *unused, const char *keyfield, const char *lookup, va_list ap) { - struct ast_str *query; + struct ast_str *query, *buffer; char buf1[200], buf2[200]; const char *newparam, *newval; char *stringp; int i, rowcount = -1; - const int EncodeSpecialChars = 1, bufsize = 100; - char *buffer; + const int EncodeSpecialChars = 1; if (!ast_custom_function_find("CURL")) { ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n"); return -1; } - if (!(query = ast_str_create(1000))) + if (!(query = ast_str_thread_get(&query_buf, 1000))) { return -1; + } - if (!(buffer = ast_malloc(bufsize))) { - ast_free(query); + if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return -1; } @@ -452,27 +454,26 @@ static int destroy_curl(const char *url, const char *unused, const char *keyfiel va_end(ap); ast_str_append(&query, 0, ")}"); - pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, bufsize); + ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); /* Line oriented output */ - stringp = buffer; - while (*stringp <= ' ') + stringp = ast_str_buffer(buffer); + while (*stringp <= ' ') { stringp++; + } sscanf(stringp, "%d", &rowcount); - ast_free(buffer); - ast_free(query); - - if (rowcount >= 0) + if (rowcount >= 0) { return (int)rowcount; + } return -1; } static int require_curl(const char *url, const char *unused, va_list ap) { - struct ast_str *query; - char *elm, field[256], buffer[128]; + struct ast_str *query, *buffer; + char *elm, field[256]; int type, size; const int EncodeSpecialChars = 1; @@ -481,7 +482,11 @@ static int require_curl(const char *url, const char *unused, va_list ap) return -1; } - if (!(query = ast_str_create(100))) { + if (!(query = ast_str_thread_get(&query_buf, 100))) { + return -1; + } + + if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return -1; } @@ -511,19 +516,19 @@ static int require_curl(const char *url, const char *unused, va_list ap) va_end(ap); ast_str_append(&query, 0, ")}"); - pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, sizeof(buffer)); - return atoi(buffer); + ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); + return atoi(ast_str_buffer(buffer)); } static struct ast_config *config_curl(const char *url, const char *unused, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *sugg_incl, const char *who_asked) { - struct ast_str *query; + struct ast_str *query, *buffer; char buf1[200]; char *stringp, *line, *pair, *key; - const int EncodeSpecialChars = 1, bufsize = 256000; + const int EncodeSpecialChars = 1; int last_cat_metric = -1, cat_metric = -1; - struct ast_category *cat=NULL; - char *buffer, *cur_cat = ""; + struct ast_category *cat = NULL; + char *cur_cat = ""; char *category = "", *var_name = "", *var_val = ""; struct ast_flags loader_flags = { 0 }; @@ -532,11 +537,11 @@ static struct ast_config *config_curl(const char *url, const char *unused, const return NULL; } - if (!(query = ast_str_create(1000))) + if (!(query = ast_str_thread_get(&query_buf, 100))) { return NULL; + } - if (!(buffer = ast_malloc(bufsize))) { - ast_free(query); + if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return NULL; } @@ -544,30 +549,33 @@ static struct ast_config *config_curl(const char *url, const char *unused, const ast_str_set(&query, 0, "${CURL(%s/static?file=%s)}", url, buf1); /* Do the CURL query */ - pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, bufsize); + ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); /* Line oriented output */ - stringp = buffer; + stringp = ast_str_buffer(buffer); cat = ast_config_get_current_category(cfg); while ((line = strsep(&stringp, "\r\n"))) { - if (ast_strlen_zero(line)) + if (ast_strlen_zero(line)) { continue; + } while ((pair = strsep(&line, "&"))) { key = strsep(&pair, "="); ast_uri_decode(key); - if (pair) + if (pair) { ast_uri_decode(pair); + } - if (!strcasecmp(key, "category")) + if (!strcasecmp(key, "category")) { category = S_OR(pair, ""); - else if (!strcasecmp(key, "var_name")) + } else if (!strcasecmp(key, "var_name")) { var_name = S_OR(pair, ""); - else if (!strcasecmp(key, "var_val")) + } else if (!strcasecmp(key, "var_val")) { var_val = S_OR(pair, ""); - else if (!strcasecmp(key, "cat_metric")) + } else if (!strcasecmp(key, "cat_metric")) { cat_metric = pair ? atoi(pair) : 0; + } } if (!strcmp(var_name, "#include")) { @@ -585,8 +593,6 @@ static struct ast_config *config_curl(const char *url, const char *unused, const ast_variable_append(cat, ast_variable_new(var_name, var_val, "")); } - ast_free(buffer); - ast_free(query); return cfg; } diff --git a/res/res_phoneprov.c b/res/res_phoneprov.c index 2a5d24af7..a444c491d 100644 --- a/res/res_phoneprov.c +++ b/res/res_phoneprov.c @@ -429,8 +429,7 @@ static int phoneprov_callback(struct ast_tcptls_session_instance *ser, const str route = unref_route(route); return 0; } else { /* Dynamic file */ - int bufsize; - char *tmp; + struct ast_str *tmp; len = load_file(path, &file); if (len < 0) { @@ -446,12 +445,7 @@ static int phoneprov_callback(struct ast_tcptls_session_instance *ser, const str goto out500; } - /* XXX This is a hack -- maybe sum length of all variables in route->user->headp and add that? */ - bufsize = len + VAR_BUF_SIZE; - - /* malloc() instead of alloca() here, just in case the file is bigger than - * we have enough stack space for. */ - if (!(tmp = ast_calloc(1, bufsize))) { + if (!(tmp = ast_str_create(len))) { if (file) { ast_free(file); } @@ -480,7 +474,7 @@ static int phoneprov_callback(struct ast_tcptls_session_instance *ser, const str } } - pbx_substitute_variables_varshead(AST_LIST_FIRST(&route->user->extensions)->headp, file, tmp, bufsize); + ast_str_substitute_variables_varshead(&tmp, 0, AST_LIST_FIRST(&route->user->extensions)->headp, file); if (file) { ast_free(file); @@ -496,7 +490,7 @@ static int phoneprov_callback(struct ast_tcptls_session_instance *ser, const str } goto out500; } - ast_str_append(&result, 0, "%s", tmp); + ast_str_append(&result, 0, "%s", ast_str_buffer(tmp)); ast_http_send(ser, method, 200, NULL, http_header, result, 0, 0); if (tmp) { @@ -830,18 +824,25 @@ static struct user *build_user(const char *mac, struct phone_profile *profile) static int add_user_extension(struct user *user, struct extension *exten) { struct ast_var_t *var; + struct ast_str *str = ast_str_create(16); + + if (!str) { + return -1; + } /* Append profile variables here, and substitute variables on profile * setvars, so that we can use user specific variables in them */ AST_LIST_TRAVERSE(user->profile->headp, var, entries) { - char expand_buf[VAR_BUF_SIZE] = {0,}; struct ast_var_t *var2; - pbx_substitute_variables_varshead(exten->headp, var->value, expand_buf, sizeof(expand_buf)); - if ((var2 = ast_var_assign(var->name, expand_buf))) + ast_str_substitute_variables_varshead(&str, 0, exten->headp, var->value); + if ((var2 = ast_var_assign(var->name, ast_str_buffer(str)))) { AST_LIST_INSERT_TAIL(exten->headp, var2, entries); + } } + ast_free(str); + if (AST_LIST_EMPTY(&user->extensions)) { AST_LIST_INSERT_HEAD(&user->extensions, exten, entry); } else { @@ -867,14 +868,18 @@ static int add_user_extension(struct user *user, struct extension *exten) static int build_user_routes(struct user *user) { struct phoneprov_file *pp_file; + struct ast_str *str; - AST_LIST_TRAVERSE(&user->profile->dynamic_files, pp_file, entry) { - char expand_buf[VAR_BUF_SIZE] = { 0, }; + if (!(str = ast_str_create(16))) { + return -1; + } - pbx_substitute_variables_varshead(AST_LIST_FIRST(&user->extensions)->headp, pp_file->format, expand_buf, sizeof(expand_buf)); - build_route(pp_file, user, expand_buf); + AST_LIST_TRAVERSE(&user->profile->dynamic_files, pp_file, entry) { + ast_str_substitute_variables_varshead(&str, 0, AST_LIST_FIRST(&user->extensions)->headp, pp_file->format); + build_route(pp_file, user, ast_str_buffer(str)); } + ast_free(str); return 0; } @@ -1053,17 +1058,22 @@ static void delete_profiles(void) } /*! \brief A dialplan function that can be used to print a string for each phoneprov user */ -static int pp_each_user_exec(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) +static int pp_each_user_helper(struct ast_channel *chan, char *data, char *buf, struct ast_str **bufstr, int len) { - char *tmp, expand_buf[VAR_BUF_SIZE] = {0,}; + char *tmp; struct ao2_iterator i; struct user *user; + struct ast_str *str; AST_DECLARE_APP_ARGS(args, AST_APP_ARG(string); AST_APP_ARG(exclude_mac); ); AST_STANDARD_APP_ARGS(args, data); + if (!(str = ast_str_create(16))) { + return -1; + } + /* Fix data by turning %{ into ${ */ while ((tmp = strstr(args.string, "%{"))) *tmp = '$'; @@ -1073,14 +1083,30 @@ static int pp_each_user_exec(struct ast_channel *chan, const char *cmd, char *da if (!ast_strlen_zero(args.exclude_mac) && !strcasecmp(user->macaddress, args.exclude_mac)) { continue; } - pbx_substitute_variables_varshead(AST_LIST_FIRST(&user->extensions)->headp, args.string, expand_buf, sizeof(expand_buf)); - ast_build_string(&buf, &len, "%s", expand_buf); + ast_str_substitute_variables_varshead(&str, len, AST_LIST_FIRST(&user->extensions)->headp, args.string); + if (buf) { + size_t slen = len; + ast_build_string(&buf, &slen, "%s", ast_str_buffer(str)); + } else { + ast_str_append(bufstr, len, "%s", ast_str_buffer(str)); + } user = unref_user(user); } + ast_free(str); return 0; } +static int pp_each_user_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) +{ + return pp_each_user_helper(chan, data, buf, NULL, len); +} + +static int pp_each_user_read2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, int len) +{ + return pp_each_user_helper(chan, data, NULL, buf, len); +} + static struct ast_custom_function pp_each_user_function = { .name = "PP_EACH_USER", .synopsis = "Generate a string for each phoneprov user", @@ -1091,17 +1117,19 @@ static struct ast_custom_function pp_each_user_function = { "excluding ones with MAC address <exclude_mac>. Probably not useful outside of\n" "res_phoneprov.\n" "\nExample: ${PP_EACH_USER(<item><fn>%{DISPLAY_NAME}</fn></item>|${MAC})", - .read = pp_each_user_exec, + .read = pp_each_user_read, + .read2 = pp_each_user_read2, }; /*! \brief A dialplan function that can be used to output a template for each extension attached to a user */ -static int pp_each_extension_exec(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) +static int pp_each_extension_helper(struct ast_channel *chan, const char *cmd, char *data, char *buf, struct ast_str **bufstr, int len) { struct user *user; struct extension *exten; char path[PATH_MAX]; char *file; int filelen; + struct ast_str *str; AST_DECLARE_APP_ARGS(args, AST_APP_ARG(mac); AST_APP_ARG(template); @@ -1133,19 +1161,38 @@ static int pp_each_extension_exec(struct ast_channel *chan, const char *cmd, cha return 0; } + if (!(str = ast_str_create(filelen))) { + return 0; + } + AST_LIST_TRAVERSE(&user->extensions, exten, entry) { - char expand_buf[VAR_BUF_SIZE] = {0,}; - pbx_substitute_variables_varshead(exten->headp, file, expand_buf, sizeof(expand_buf)); - ast_build_string(&buf, &len, "%s", expand_buf); + ast_str_substitute_variables_varshead(&str, 0, exten->headp, file); + if (buf) { + size_t slen = len; + ast_build_string(&buf, &slen, "%s", ast_str_buffer(str)); + } else { + ast_str_append(bufstr, len, "%s", ast_str_buffer(str)); + } } ast_free(file); + ast_free(str); user = unref_user(user); return 0; } +static int pp_each_extension_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) +{ + return pp_each_extension_helper(chan, cmd, data, buf, NULL, len); +} + +static int pp_each_extension_read2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, int len) +{ + return pp_each_extension_helper(chan, cmd, data, NULL, buf, len); +} + static struct ast_custom_function pp_each_extension_function = { .name = "PP_EACH_EXTENSION", .synopsis = "Execute specified template for each extension", @@ -1153,7 +1200,8 @@ static struct ast_custom_function pp_each_extension_function = { .desc = "Output the specified template for each extension associated with the specified\n" "MAC address.", - .read = pp_each_extension_exec, + .read = pp_each_extension_read, + .read2 = pp_each_extension_read2, }; /*! \brief CLI command to list static and dynamic routes */ |