summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
Diffstat (limited to 'res')
-rw-r--r--res/res_agi.c13
-rw-r--r--res/res_config_curl.c236
-rw-r--r--res/res_phoneprov.c102
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 */