aboutsummaryrefslogtreecommitdiffstats
path: root/cdr/cdr_custom.c
diff options
context:
space:
mode:
authorseanbright <seanbright@f38db490-d61c-443f-a65b-d21fe96a405b>2009-05-23 15:16:59 +0000
committerseanbright <seanbright@f38db490-d61c-443f-a65b-d21fe96a405b>2009-05-23 15:16:59 +0000
commit91b93e83f765407ae977ddcf7bda323c53e5351c (patch)
treef93be12015092be0313c89a4ca53a0163454d059 /cdr/cdr_custom.c
parent5e450bcbaf6511eb97d3187a7f8e341631303a4d (diff)
Fix errors in cdr_custom that cause reference errors when non-CDR variable
substitution is done. cdr_custom was creating a ast_channel struct directly and passing it into the core for variable substition. This was fine as long as the format string contained only calls to the CDR() function. Doing something like ${EPOCH} on the other hand tried to lock the channel, which would fail and throw an error because the passed channel hadn't been allocated as an ao2 object. So now we create the dummy channel with ast_channel_alloc, and everything works as expected. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@196520 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'cdr/cdr_custom.c')
-rw-r--r--cdr/cdr_custom.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/cdr/cdr_custom.c b/cdr/cdr_custom.c
index 4ca6386b9..c045241d9 100644
--- a/cdr/cdr_custom.c
+++ b/cdr/cdr_custom.c
@@ -115,7 +115,7 @@ static int load_config(void)
static int custom_log(struct ast_cdr *cdr)
{
- struct ast_channel dummy;
+ struct ast_channel *dummy;
struct ast_str *str;
struct cdr_config *config;
@@ -124,17 +124,24 @@ static int custom_log(struct ast_cdr *cdr)
return -1;
}
- /* Quite possibly the first use of a static struct ast_channel, we need it so the var funcs will work */
- memset(&dummy, 0, sizeof(dummy));
- dummy.cdr = cdr;
+ dummy = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Substitution/%p", cdr);
+
+ if (!dummy) {
+ ast_log(LOG_ERROR, "Unable to allocate channel for variable subsitution.\n");
+ return -1;
+ }
+
+ /* We need to dup here since the cdr actually belongs to the other channel,
+ so when we release this channel we don't want the CDR getting cleaned
+ up prematurely. */
+ dummy->cdr = ast_cdr_dup(cdr);
AST_RWLIST_RDLOCK(&sinks);
AST_LIST_TRAVERSE(&sinks, config, list) {
FILE *out;
- ast_str_reset(str);
- ast_str_substitute_variables(&str, 0, &dummy, config->format);
+ ast_str_substitute_variables(&str, 0, dummy, config->format);
/* Even though we have a lock on the list, we could be being chased by
another thread and this lock ensures that we won't step on anyone's
@@ -158,6 +165,8 @@ static int custom_log(struct ast_cdr *cdr)
AST_RWLIST_UNLOCK(&sinks);
+ ast_channel_release(dummy);
+
return 0;
}