Newer
Older
cdr_res = ast_pbx_outgoing_cdr_failed();
if(cdr_res != 0)
return cdr_res;
}
/* create a fake channel and execute the "failed" extension (if it exists) within the requested context */
/* check if "failed" exists */
if (ast_exists_extension(chan, context, "failed", 1, NULL)) {
chan = ast_channel_alloc(0);
if (context && !ast_strlen_zero(context))
strncpy(chan->context, context, sizeof(chan->context) - 1);
strncpy(chan->exten, "failed", sizeof(chan->exten) - 1);
chan->priority = 1;
if (variable) {
tmp = ast_strdupa(variable);
for (var = strtok_r(tmp, "|", &tmp); var; var = strtok_r(NULL, "|", &tmp)) {
pbx_builtin_setvar( chan, var );
}
}
ast_log(LOG_WARNING, "Can't allocate the channel structure, skipping execution of extension 'failed'\n");
}
}
} else {
as = malloc(sizeof(struct async_stat));
if (!as)
return -1;
memset(as, 0, sizeof(struct async_stat));
chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
if (channel) {
*channel = chan;
if (chan)
ast_mutex_lock(&chan->lock);
}
if (!chan) {
free(as);
return -1;
}
if (account)
ast_cdr_setaccount(chan, account);
as->chan = chan;
strncpy(as->context, context, sizeof(as->context) - 1);
strncpy(as->exten, exten, sizeof(as->exten) - 1);
as->priority = priority;
as->timeout = timeout;
if (variable) {
tmp = ast_strdupa(variable);
for (var = strtok_r(tmp, "|", &tmp); var; var = strtok_r(NULL, "|", &tmp))
pbx_builtin_setvar( chan, var );
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
ast_log(LOG_WARNING, "Failed to start async wait\n");
free(as);
ast_hangup(chan);
return -1;
}
res = 0;
}
return res;
}
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
struct app_tmp {
char app[256];
char data[256];
struct ast_channel *chan;
pthread_t t;
};
static void *ast_pbx_run_app(void *data)
{
struct app_tmp *tmp = data;
struct ast_app *app;
app = pbx_findapp(tmp->app);
if (app) {
if (option_verbose > 3)
ast_verbose(VERBOSE_PREFIX_4 "Lauching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name);
pbx_exec(tmp->chan, app, tmp->data, 1);
} else
ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app);
ast_hangup(tmp->chan);
free(tmp);
return NULL;
}
int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, const char *variable, const char *account, struct ast_channel **locked_channel)
{
struct ast_channel *chan;
struct async_stat *as;
struct app_tmp *tmp;
if (locked_channel)
*locked_channel = NULL;
if (!app || ast_strlen_zero(app))
chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
if (account)
ast_cdr_setaccount(chan, account);
if(chan->cdr) { /* check if the channel already has a cdr record, if not give it one */
ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name);
} else {
chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */
if(!chan->cdr) {
/* allocation of the cdr failed */
ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
free(chan->pbx);
return -1; /* return failure */
}
/* allocation of the cdr was successful */
ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */
ast_cdr_start(chan->cdr);
}
if (variable) {
vartmp = ast_strdupa(variable);
for (var = strtok_r(vartmp, "|", &vartmp); var; var = strtok_r(NULL, "|", &vartmp)) {
pbx_builtin_setvar( chan, var );
}
if (chan->_state == AST_STATE_UP) {
res = 0;
if (option_verbose > 3)
ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
tmp = malloc(sizeof(struct app_tmp));
if (tmp) {
memset(tmp, 0, sizeof(struct app_tmp));
strncpy(tmp->app, app, sizeof(tmp->app) - 1);
strncpy(tmp->data, appdata, sizeof(tmp->data) - 1);
tmp->chan = chan;
if (sync > 1) {
if (locked_channel)
ast_mutex_unlock(&chan->lock);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (locked_channel)
ast_mutex_lock(&chan->lock);
if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) {
ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
free(tmp);
if (locked_channel)
ast_mutex_unlock(&chan->lock);
} else {
if (locked_channel)
*locked_channel = chan;
ast_log(LOG_ERROR, "Out of memory :(\n");
res = -1;
}
} else {
if (option_verbose > 3)
ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
if(chan->cdr) { /* update the cdr */
/* here we update the status of the call, which sould be busy.
* if that fails then we set the status to failed */
if(ast_cdr_disposition(chan->cdr, chan->hangupcause))
ast_cdr_failed(chan->cdr);
}
if(res < 0) { /* the call failed for some reason */
if(*reason == 0) { /* if the call failed (not busy or no answer)
* update the cdr with the failed message */
cdr_res = ast_pbx_outgoing_cdr_failed();
if(cdr_res != 0)
return cdr_res;
}
}
} else {
as = malloc(sizeof(struct async_stat));
if (!as)
return -1;
memset(as, 0, sizeof(struct async_stat));
chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
if (!chan) {
free(as);
return -1;
}
if (account)
ast_cdr_setaccount(chan, account);
as->chan = chan;
strncpy(as->app, app, sizeof(as->app) - 1);
if (appdata)
strncpy(as->appdata, appdata, sizeof(as->appdata) - 1);
as->timeout = timeout;
vartmp = ast_strdupa(variable);
for (var = strtok_r(vartmp, "|", &vartmp); var; var = strtok_r(NULL, "|", &vartmp))
pbx_builtin_setvar( chan, var );
/* Start a new thread, and get something handling this channel. */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (locked_channel)
ast_mutex_lock(&chan->lock);
if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
ast_log(LOG_WARNING, "Failed to start async wait\n");
free(as);
if (locked_channel)
ast_mutex_unlock(&chan->lock);
} else {
if (locked_channel)
*locked_channel = chan;
}
res = 0;
}
return res;
}
static void destroy_exten(struct ast_exten *e)
{
if (e->priority == PRIORITY_HINT)
ast_remove_hint(e);
if (e->datad)
e->datad(e->data);
free(e);
}
void __ast_context_destroy(struct ast_context *con, const char *registrar)
struct ast_exten *e, *el, *en;
Mark Spencer
committed
ast_mutex_lock(&conlock);
if (((tmp->name && con && con->name && !strcasecmp(tmp->name, con->name)) || !con) &&
(!registrar || !strcasecmp(registrar, tmp->registrar))) {
/* Okay, let's lock the structure to be sure nobody else
is searching through it. */
if (ast_mutex_lock(&tmp->lock)) {
ast_log(LOG_WARNING, "Unable to lock context lock\n");
return;
}
if (tmpl)
tmpl->next = tmp->next;
else
contexts = tmp->next;
/* Okay, now we're safe to let it go -- in a sense, we were
ready to let it go as soon as we locked it. */
ast_mutex_unlock(&tmp->lock);
for (tmpi = tmp->includes; tmpi; ) {
/* Free includes */
tmpil = tmpi;
tmpi = tmpi->next;
free(tmpil);
ipl = ipi;
ipi = ipi->next;
free(ipl);
swl = sw;
sw = sw->next;
free(swl);
swl = sw;
}
for (e = tmp->root; e;) {
for (en = e->peer; en;) {
el = en;
en = en->peer;
destroy_exten(el);
}
el = e;
e = e->next;
destroy_exten(el);
}
ast_mutex_destroy(&tmp->lock);
if (!con) {
/* Might need to get another one -- restart */
tmp = contexts;
tmpl = NULL;
tmpil = NULL;
continue;
}
Mark Spencer
committed
ast_mutex_unlock(&conlock);
return;
}
tmpl = tmp;
tmp = tmp->next;
}
Mark Spencer
committed
ast_mutex_unlock(&conlock);
void ast_context_destroy(struct ast_context *con, const char *registrar)
Mark Spencer
committed
__ast_context_destroy(con,registrar);
static void wait_for_hangup(struct ast_channel *chan, void *data)
Kevin P. Fleming
committed
if (!data || !strlen(data) || (sscanf(data, "%d", &waittime) != 1) || (waittime < 0))
waittime = -1;
if (waittime > -1) {
ast_safe_sleep(chan, waittime * 1000);
} else do {
res = ast_waitfor(chan, -1);
if (res < 0)
return;
f = ast_read(chan);
if (f)
ast_frfree(f);
} while(f);
}
static int pbx_builtin_progress(struct ast_channel *chan, void *data)
{
ast_indicate(chan, AST_CONTROL_PROGRESS);
return 0;
}
static int pbx_builtin_ringing(struct ast_channel *chan, void *data)
{
ast_indicate(chan, AST_CONTROL_RINGING);
return 0;
}
static int pbx_builtin_busy(struct ast_channel *chan, void *data)
{
ast_indicate(chan, AST_CONTROL_BUSY);
wait_for_hangup(chan, data);
return -1;
}
static int pbx_builtin_congestion(struct ast_channel *chan, void *data)
{
ast_indicate(chan, AST_CONTROL_CONGESTION);
wait_for_hangup(chan, data);
return -1;
}
static int pbx_builtin_answer(struct ast_channel *chan, void *data)
int delay = atoi(data);
int res;
if (chan->_state == AST_STATE_UP)
delay = 0;
res = ast_answer(chan);
if (res)
return res;
if (delay)
res = ast_safe_sleep(chan, delay);
return res;
static int pbx_builtin_setlanguage(struct ast_channel *chan, void *data)
James Golovich
committed
if (data)
strncpy(chan->language, (char *)data, sizeof(chan->language)-1);
static int pbx_builtin_resetcdr(struct ast_channel *chan, void *data)
{
/* Reset the CDR as specified */
if(data) {
if(strchr((char *)data, 'w'))
flags |= AST_CDR_FLAG_POSTED;
if(strchr((char *)data, 'a'))
flags |= AST_CDR_FLAG_LOCKED;
if(strchr((char *)data, 'v'))
flags |= AST_CDR_FLAG_KEEP_VARS;
Mark Spencer
committed
static int pbx_builtin_setaccount(struct ast_channel *chan, void *data)
{
/* Copy the account code as specified */
Mark Spencer
committed
if (data)
ast_cdr_setaccount(chan, (char *)data);
else
ast_cdr_setaccount(chan, "");
return 0;
}
static int pbx_builtin_setamaflags(struct ast_channel *chan, void *data)
{
/* Copy the AMA Flags as specified */
if (data)
ast_cdr_setamaflags(chan, (char *)data);
else
ast_cdr_setamaflags(chan, "");
return 0;
}
static int pbx_builtin_hangup(struct ast_channel *chan, void *data)
{
/* Just return non-zero and it will hang up */
return -1;
}
static int pbx_builtin_stripmsd(struct ast_channel *chan, void *data)
if (!data || !atoi(data)) {
ast_log(LOG_DEBUG, "Ignoring, since number of digits to strip is 0\n");
return 0;
}
if (strlen(chan->exten) > atoi(data)) {
strncpy(newexten, chan->exten + atoi(data), sizeof(newexten)-1);
strncpy(chan->exten, newexten, sizeof(chan->exten)-1);
static int pbx_builtin_prefix(struct ast_channel *chan, void *data)
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_DEBUG, "Ignoring, since there is no prefix to add\n");
return 0;
}
snprintf(newexten, sizeof(newexten), "%s%s", (char *)data, chan->exten);
strncpy(chan->exten, newexten, sizeof(chan->exten)-1);
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Prepended prefix, new extension is %s\n", chan->exten);
static int pbx_builtin_suffix(struct ast_channel *chan, void *data)
{
char newexten[AST_MAX_EXTENSION] = "";
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_DEBUG, "Ignoring, since there is no suffix to add\n");
return 0;
}
snprintf(newexten, sizeof(newexten), "%s%s", chan->exten, (char *)data);
strncpy(chan->exten, newexten, sizeof(chan->exten)-1);
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Appended suffix, new extension is %s\n", chan->exten);
return 0;
}
static int pbx_builtin_gotoiftime(struct ast_channel *chan, void *data)
{
int res=0;
char *s, *ts;
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "GotoIfTime requires an argument:\n <time range>|<days of week>|<days of month>|<months>?[[context|]extension|]priority\n");
return -1;
}
if ((s = ast_strdupa((char *) data))) {
ts = s;
/* Separate the Goto path */
strsep(&ts,"?");
/* struct ast_include include contained garbage here, fixed by zeroing it on get_timerange */
if (ast_build_timing(&timing, s) && ast_check_timing(&timing))
res = pbx_builtin_goto(chan, (void *)ts);
} else {
ast_log(LOG_ERROR, "Memory Error!\n");
}
return res;
}
static int pbx_builtin_execiftime(struct ast_channel *chan, void *data)
{
int res = 0;
char *ptr1, *ptr2;
struct ast_timing timing;
const char *usage = "ExecIfTime requires an argument:\n <time range>|<days of week>|<days of month>|<months>?<appname>[|<appargs>]";
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "%s\n", usage);
if ((ptr1 = ast_strdupa((char *) data))) {
ptr2 = ptr1;
/* Separate the Application data ptr1 is the time spec ptr2 is the app|data*/
strsep(&ptr2,"?");
if (ast_build_timing(&timing, ptr1) && ast_check_timing(&timing)) {
if (ptr2) {
/* ptr2 is now the app name
we're done with ptr1 now so recycle it and use it to point to the app args*/
struct ast_app *app;
if((ptr1 = strchr(ptr2, '|'))) {
*ptr1 = '\0';
ptr1++;
}
if ((app = pbx_findapp(ptr2))) {
res = pbx_exec(chan, app, ptr1 ? ptr1 : "", 1);
} else {
ast_log(LOG_WARNING, "Cannot locate application %s\n", ptr2);
}
} else {
ast_log(LOG_WARNING, "%s\n", usage);
}
} else {
ast_log(LOG_WARNING, "Invalid Time Spec: %s\nCorrect usage: %s\n", ptr1, usage);
res = -1;
}
} else {
ast_log(LOG_ERROR, "Memory Error!\n");
static int pbx_builtin_wait(struct ast_channel *chan, void *data)
if (data && atof((char *)data)) {
ms = atof((char *)data) * 1000;
static int pbx_builtin_waitexten(struct ast_channel *chan, void *data)
{
Mark Spencer
committed
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
int ms, res, argc;
char *args;
char *argv[2];
char *options = NULL;
char *mohclass = NULL;
char *timeout = NULL;
struct ast_flags flags = {0};
args = ast_strdupa(data);
if ((argc = ast_separate_app_args(args, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
if (argc > 0) {
timeout = argv[0];
if (argc > 1)
options = argv[1];
}
}
if (options) {
char *opts[1];
ast_parseoptions(waitexten_opts, &flags, opts, options);
if (ast_test_flag(&flags, WAITEXTEN_MOH)) {
mohclass = opts[0];
}
}
if (ast_test_flag(&flags, WAITEXTEN_MOH))
ast_moh_start(chan, mohclass);
Mark Spencer
committed
if (timeout && atof((char *)timeout))
ms = atof((char *)timeout) * 1000;
else if (chan->pbx)
ms = chan->pbx->rtimeout * 1000;
else
ms = 10000;
res = ast_waitfordigit(chan, ms);
if (!res) {
Mark Spencer
committed
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 1, chan->cid.cid_num)) {
Mark Spencer
committed
ast_verbose(VERBOSE_PREFIX_3 "Timeout on %s, continuing...\n", chan->name);
} else if (ast_exists_extension(chan, chan->context, "t", 1, chan->cid.cid_num)) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Timeout on %s, going to 't'\n", chan->name);
strncpy(chan->exten, "t", sizeof(chan->exten));
chan->priority = 0;
} else {
ast_log(LOG_WARNING, "Timeout but no rule 't' in context '%s'\n", chan->context);
res = -1;
}
Mark Spencer
committed
if (ast_test_flag(&flags, WAITEXTEN_MOH))
ast_moh_stop(chan);
static int pbx_builtin_background(struct ast_channel *chan, void *data)
Mark Spencer
committed
int argc;
char *args;
char *argv[3];
char *options = NULL;
char *filename = NULL;
char *front = NULL, *back = NULL;
Mark Spencer
committed
char *lang = NULL;
struct ast_flags flags = {0};
Mark Spencer
committed
args = ast_strdupa(data);
Mark Spencer
committed
if ((argc = ast_separate_app_args(args, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
if (argc > 0) {
filename = argv[0];
if (argc > 1)
options = argv[1];
if (argc > 2)
lang = argv[2];
} else {
ast_log(LOG_WARNING, "Background requires an argument (filename)\n");
}
}
if (!lang)
lang = chan->language;
Mark Spencer
committed
if (options) {
if (!strcasecmp(options, "skip"))
flags.flags = BACKGROUND_SKIP;
else if (!strcasecmp(options, "noanswer"))
flags.flags = BACKGROUND_NOANSWER;
else
ast_parseoptions(background_opts, &flags, NULL, options);
}
/* Answer if need be */
if (chan->_state != AST_STATE_UP) {
Mark Spencer
committed
if (ast_test_flag(&flags, BACKGROUND_SKIP)) {
Mark Spencer
committed
} else if (!ast_test_flag(&flags, BACKGROUND_NOANSWER)) {
res = ast_answer(chan);
}
}
if (!res) {
/* Stop anything playing */
ast_stopstream(chan);
/* Stream a file */
front = filename;
while(!res && front) {
if((back = strchr(front, '&'))) {
*back = '\0';
back++;
}
res = ast_streamfile(chan, front, lang);
if (!res) {
res = ast_waitstream(chan, AST_DIGIT_ANY);
ast_stopstream(chan);
} else {
ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char*)data);
res = 0;
break;
}
front = back;
static int pbx_builtin_atimeout(struct ast_channel *chan, void *data)
{
int x = atoi((char *) data);
/* Set the absolute maximum time how long a call can be connected */
ast_channel_setwhentohangup(chan,x);
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Set Absolute Timeout to %d\n", x);
return 0;
}
static int pbx_builtin_rtimeout(struct ast_channel *chan, void *data)
Kevin P. Fleming
committed
/* If the channel is not in a PBX, return now */
if (!chan->pbx)
return 0;
/* Set the timeout for how long to wait between digits */
chan->pbx->rtimeout = atoi((char *)data);
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Set Response Timeout to %d\n", chan->pbx->rtimeout);
return 0;
}
static int pbx_builtin_dtimeout(struct ast_channel *chan, void *data)
Kevin P. Fleming
committed
/* If the channel is not in a PBX, return now */
if (!chan->pbx)
return 0;
/* Set the timeout for how long to wait between digits */
chan->pbx->dtimeout = atoi((char *)data);
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Set Digit Timeout to %d\n", chan->pbx->dtimeout);
return 0;
}
static int pbx_builtin_goto(struct ast_channel *chan, void *data)
int res;
res = ast_parseable_goto(chan, (const char *) data);
if (!res && (option_verbose > 2))
ast_verbose( VERBOSE_PREFIX_3 "Goto (%s,%s,%d)\n", chan->context,chan->exten, chan->priority+1);
int pbx_builtin_serialize_variables(struct ast_channel *chan, char *buf, size_t size)
{
struct ast_var_t *variables;
struct varshead *headp;
char *var=NULL ,*val=NULL;
int total = 0;
memset(buf,0,size);
if (chan) {
headp=&chan->varshead;
AST_LIST_TRAVERSE(headp,variables,entries) {
if(chan && variables && (var=ast_var_name(variables)) && (val=ast_var_value(variables)) && !ast_strlen_zero(var) && !ast_strlen_zero(val)) {
snprintf(buf + strlen(buf), size - strlen(buf), "%s=%s\n", var, val);
if(strlen(buf) >= size) {
ast_log(LOG_ERROR,"Data Buffer Size Exceeded!\n");
break;
}
total++;
}
}
return total;
}
char *pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
struct ast_var_t *variables;
struct varshead *headp;
if (chan)
headp=&chan->varshead;
AST_LIST_TRAVERSE(headp,variables,entries) {
if (!strcmp(name, ast_var_name(variables)))
return ast_var_value(variables);
}
if (headp != &globals) {
/* Check global variables if we haven't already */
headp = &globals;
AST_LIST_TRAVERSE(headp,variables,entries) {
if (!strcmp(name, ast_var_name(variables)))
return ast_var_value(variables);
}
}
}
void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
struct varshead *headp;
if (name[strlen(name)-1] == ')')
return ast_func_write(chan, name, value);
headp = &chan->varshead;
if (!strncasecmp(name, "CDR(", 4)) { /* CDR VARS */
char *vtmp, *nt;
int recur = 0;
if ((vtmp = ast_strdupa((char *) name + 4)) && (nt = strchr(vtmp, ')'))) {
*nt = '\0';
if(vtmp[0] == '-') {
vtmp++;
recur = 1;
}
ast_cdr_setvar(chan->cdr, vtmp, value, recur);
} else {
ast_log(LOG_WARNING, "Invalid CDR variable.\n");
}
return;
}
}
headp = &globals;
AST_LIST_TRAVERSE (headp, newvariable, entries) {
if (strcasecmp(ast_var_name(newvariable), name) == 0) {
/* there is already such a variable, delete it */
AST_LIST_REMOVE(headp, newvariable, entries);
ast_var_delete(newvariable);
break;
}
}
if (value) {
if ((option_verbose > 1) && (headp == &globals))
ast_verbose(VERBOSE_PREFIX_3 "Setting global variable '%s' to '%s'\n", name, value);
newvariable = ast_var_assign(name, value);
AST_LIST_INSERT_HEAD(headp, newvariable, entries);
Martin Pycko
committed
int pbx_builtin_setvar(struct ast_channel *chan, void *data)
char *name, *value, *mydata, *next, *fstr = NULL;
struct ast_flags flags = {0};
if (data && !ast_strlen_zero(data) && (mydata = ast_strdupa(data))) {
next = mydata;
while(next) {
name = next;
if ((next = strchr(next, '|'))) {
*next = '\0';
next++;
}
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
if ((value = strchr(name, '='))) {
*value = '\0';
value++;
if( fstr && strchr(fstr, 'g') ) {
pbx_builtin_setvar_helper(NULL, name, value);
}
else {
pbx_builtin_setvar_helper(chan, name, value);
if (ast_test_flag(&flags, AST_CDR_FLAG_SETVAR)) {
ast_cdr_setvar(chan->cdr, name, value, ast_test_flag(&flags, AST_CDR_FLAG_RECUR));
}
}
} else if (!next) {
name++;
if (strchr(name, 'c') ) {
ast_set_flag(&flags, AST_CDR_FLAG_SETVAR);
} else if (strchr(name, 'r') ) {
ast_set_flag(&flags, AST_CDR_FLAG_RECUR | AST_CDR_FLAG_SETVAR);
}
} else
ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name);
}
} else {
ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
}
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
int pbx_builtin_importvar(struct ast_channel *chan, void *data)
{
char *name;
char *value;
char *stringp=NULL;
char *channel;
struct ast_channel *chan2=NULL;
char tmp[4096]="";
char *s;
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
return 0;
}
stringp = ast_strdupa(data);
name = strsep(&stringp,"=");
channel = strsep(&stringp,"|");
value = strsep(&stringp,"\0");
if (channel && value && name) {
while((chan2 = ast_channel_walk_locked(chan2))) {
if (!strcmp(chan2->name, channel))
break;
ast_mutex_unlock(&chan2->lock);
}
if (chan2) {
s = alloca(strlen(value) + 4);
if (s) {
sprintf(s, "${%s}", value);
pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1);
}
ast_mutex_unlock(&chan2->lock);
}
pbx_builtin_setvar_helper(chan, name, tmp);
}
return(0);
}
static int pbx_builtin_setglobalvar(struct ast_channel *chan, void *data)
{
char *name;
char *value;
char *stringp = NULL;
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
return 0;
}
stringp = data;
name = strsep(&stringp, "=");
value = strsep(&stringp, "\0");
pbx_builtin_setvar_helper(NULL, name, value);
return(0);
}
static int pbx_builtin_noop(struct ast_channel *chan, void *data)
{
return 0;
}
void pbx_builtin_clear_globals(void)
{
struct ast_var_t *vardata;
while (!AST_LIST_EMPTY(&globals)) {
vardata = AST_LIST_REMOVE_HEAD(&globals, entries);
ast_var_delete(vardata);
}
}
static int pbx_checkcondition(char *condition)
{
return condition ? atoi(condition) : 0;
}
static int pbx_builtin_gotoif(struct ast_channel *chan, void *data)
{
char *condition,*branch1,*branch2,*branch;
char *s;
int rc;
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n");
stringp=s;
condition=strsep(&stringp,"?");
branch1=strsep(&stringp,":");
branch2=strsep(&stringp,"");
branch = pbx_checkcondition(condition) ? branch1 : branch2;
if ((branch==NULL) || ast_strlen_zero(branch)) {
ast_log(LOG_DEBUG, "Not taking any branch\n");
return(0);
}
rc=pbx_builtin_goto(chan,branch);
static int pbx_builtin_saynumber(struct ast_channel *chan, void *data)
{
int res = 0;
Mark Spencer
committed
char tmp[256];
char *number = (char *) NULL;
char *options = (char *) NULL;
if (!data || ast_strlen_zero((char *)data)) {
ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n");
return -1;
}
strncpy(tmp, (char *)data, sizeof(tmp)-1);
number=tmp;