diff options
Diffstat (limited to 'res/res_phoneprov.c')
-rw-r--r-- | res/res_phoneprov.c | 102 |
1 files changed, 75 insertions, 27 deletions
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 */ |