summaryrefslogtreecommitdiff
path: root/apps/app_followme.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/app_followme.c')
-rw-r--r--apps/app_followme.c187
1 files changed, 93 insertions, 94 deletions
diff --git a/apps/app_followme.c b/apps/app_followme.c
index 86f991437..bab4d1ba3 100644
--- a/apps/app_followme.c
+++ b/apps/app_followme.c
@@ -323,7 +323,6 @@ static int reload_followme(int reload)
struct number *cur, *nm;
char numberstr[90];
int timeout;
- char *timeoutstr;
int numorder;
const char *takecallstr;
const char *declinecallstr;
@@ -441,17 +440,17 @@ static int reload_followme(int reload)
ast_copy_string(numberstr, var->value, sizeof(numberstr));
if ((tmp = strchr(numberstr, ','))) {
*tmp++ = '\0';
- timeoutstr = ast_strdupa(tmp);
- if ((tmp = strchr(timeoutstr, ','))) {
+ timeout = atoi(tmp);
+ if (timeout < 0) {
+ timeout = 25;
+ }
+ if ((tmp = strchr(tmp, ','))) {
*tmp++ = '\0';
numorder = atoi(tmp);
if (numorder < 0)
numorder = 0;
} else
numorder = 0;
- timeout = atoi(timeoutstr);
- if (timeout < 0)
- timeout = 25;
} else {
timeout = 25;
numorder = 0;
@@ -464,7 +463,9 @@ static int reload_followme(int reload)
numorder = idx;
}
cur = create_followme_number(numberstr, timeout, numorder);
- AST_LIST_INSERT_TAIL(&f->numbers, cur, entry);
+ if (cur) {
+ AST_LIST_INSERT_TAIL(&f->numbers, cur, entry);
+ }
} else {
profile_set_param(f, var->name, var->value, var->lineno, 1);
ast_debug(2, "Logging parameter %s with value %s from lineno %d\n", var->name, var->value, var->lineno);
@@ -511,7 +512,6 @@ static void clear_caller(struct findme_user *tmpuser)
ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
ast_hangup(tmpuser->ochan);
}
-
}
static void clear_calling_tree(struct findme_user_listptr *findme_user_list)
@@ -524,7 +524,18 @@ static void clear_calling_tree(struct findme_user_listptr *findme_user_list)
}
}
+static void destroy_calling_tree(struct findme_user_listptr *findme_user_list)
+{
+ struct findme_user *fmuser;
+ while ((fmuser = AST_LIST_REMOVE_HEAD(findme_user_list, entry))) {
+ if (!fmuser->cleared) {
+ clear_caller(fmuser);
+ }
+ ast_free(fmuser);
+ }
+ ast_free(findme_user_list);
+}
static struct ast_channel *wait_for_winner(struct findme_user_listptr *findme_user_list, struct number *nm, struct ast_channel *caller, char *namerecloc, int *status, struct fm_args *tpargs)
{
@@ -801,6 +812,7 @@ static void findmeexec(struct fm_args *tpargs)
struct ast_channel *caller;
struct ast_channel *winner = NULL;
char dialarg[512];
+ char num[512];
int dg, idx;
char *rest, *number;
struct findme_user *tmpuser;
@@ -813,132 +825,121 @@ static void findmeexec(struct fm_args *tpargs)
/* We're going to figure out what the longest possible string of digits to collect is */
ynlongest = 0;
- if (strlen(tpargs->takecall) > ynlongest)
+ if (strlen(tpargs->takecall) > ynlongest) {
ynlongest = strlen(tpargs->takecall);
- if (strlen(tpargs->nextindp) > ynlongest)
+ }
+ if (strlen(tpargs->nextindp) > ynlongest) {
ynlongest = strlen(tpargs->nextindp);
+ }
- idx = 1;
caller = tpargs->chan;
- AST_LIST_TRAVERSE(&tpargs->cnumbers, nm, entry)
- if (nm->order == idx)
+ for (idx = 1; !winner && !ast_check_hangup(caller); ++idx) {
+ /* Find next followme numbers to dial. */
+ AST_LIST_TRAVERSE(&tpargs->cnumbers, nm, entry) {
+ if (nm->order == idx) {
+ break;
+ }
+ }
+ if (!nm) {
break;
+ }
- while (nm) {
ast_debug(2, "Number %s timeout %ld\n", nm->number,nm->timeout);
- number = ast_strdupa(nm->number);
- ast_debug(3, "examining %s\n", number);
- do {
+ ast_copy_string(num, nm->number, sizeof(num));
+ for (number = num; number; number = rest) {
rest = strchr(number, '&');
if (rest) {
- *rest = 0;
- rest++;
+ *rest++ = 0;
}
- /* We check if that context exists, before creating the ast_channel struct needed */
+ /* We check if the extension exists, before creating the ast_channel struct */
if (!ast_exists_extension(caller, tpargs->context, number, 1, S_COR(caller->caller.id.number.valid, caller->caller.id.number.str, NULL))) {
- /* XXX Should probably restructure to simply skip this item, instead of returning. XXX */
ast_log(LOG_ERROR, "Extension '%s@%s' doesn't exist\n", number, tpargs->context);
- free(findme_user_list);
- return;
+ continue;
}
- if (!strcmp(tpargs->context, ""))
+ if (!strcmp(tpargs->context, "")) {
snprintf(dialarg, sizeof(dialarg), "%s%s", number, ast_test_flag(&tpargs->followmeflags, FOLLOWMEFLAG_DISABLEOPTIMIZATION) ? "/n" : "");
- else
+ } else {
snprintf(dialarg, sizeof(dialarg), "%s@%s%s", number, tpargs->context, ast_test_flag(&tpargs->followmeflags, FOLLOWMEFLAG_DISABLEOPTIMIZATION) ? "/n" : "");
+ }
tmpuser = ast_calloc(1, sizeof(*tmpuser));
if (!tmpuser) {
- ast_free(findme_user_list);
- return;
+ continue;
}
outbound = ast_request("Local", caller->nativeformats, caller, dialarg, &dg);
if (outbound) {
- ast_set_callerid(outbound,
- S_COR(caller->caller.id.number.valid, caller->caller.id.number.str, NULL),
- S_COR(caller->caller.id.name.valid, caller->caller.id.name.str, NULL),
- S_COR(caller->caller.id.number.valid, caller->caller.id.number.str, NULL));
- ast_channel_inherit_variables(tpargs->chan, outbound);
- ast_channel_datastore_inherit(tpargs->chan, outbound);
- ast_string_field_set(outbound, language, tpargs->chan->language);
- ast_string_field_set(outbound, accountcode, tpargs->chan->accountcode);
- ast_string_field_set(outbound, musicclass, tpargs->chan->musicclass);
- ast_verb(3, "calling %s\n", dialarg);
- if (!ast_call(outbound,dialarg,0)) {
+ ast_channel_lock_both(caller, outbound);
+ ast_connected_line_copy_from_caller(&outbound->connected, &caller->caller);
+ ast_channel_inherit_variables(caller, outbound);
+ ast_channel_datastore_inherit(caller, outbound);
+ ast_string_field_set(outbound, language, caller->language);
+ ast_string_field_set(outbound, accountcode, caller->accountcode);
+ ast_string_field_set(outbound, musicclass, caller->musicclass);
+ ast_channel_unlock(outbound);
+ ast_channel_unlock(caller);
+ ast_verb(3, "calling Local/%s\n", dialarg);
+ if (!ast_call(outbound, dialarg, 0)) {
tmpuser->ochan = outbound;
tmpuser->state = 0;
tmpuser->cleared = 0;
ast_copy_string(tmpuser->dialarg, dialarg, sizeof(dialarg));
AST_LIST_INSERT_TAIL(findme_user_list, tmpuser, entry);
} else {
- ast_verb(3, "couldn't reach at this number.\n");
- if (outbound) {
- if (!outbound->cdr)
- outbound->cdr = ast_cdr_alloc();
- if (outbound->cdr) {
- char tmp[256];
-
- ast_cdr_init(outbound->cdr, outbound);
- snprintf(tmp, sizeof(tmp), "%s/%s", "Local", dialarg);
- ast_cdr_setapp(outbound->cdr, "FollowMe", tmp);
- ast_cdr_update(outbound);
- ast_cdr_start(outbound->cdr);
- ast_cdr_end(outbound->cdr);
- /* If the cause wasn't handled properly */
- if (ast_cdr_disposition(outbound->cdr,outbound->hangupcause))
- ast_cdr_failed(outbound->cdr);
- } else {
- ast_log(LOG_ERROR, "Unable to create Call Detail Record\n");
- ast_hangup(outbound);
- outbound = NULL;
+ ast_verb(3, "couldn't reach at this number.\n");
+ if (!outbound->cdr) {
+ outbound->cdr = ast_cdr_alloc();
+ }
+ if (outbound->cdr) {
+ char tmp[256];
+
+ ast_cdr_init(outbound->cdr, outbound);
+ snprintf(tmp, sizeof(tmp), "%s/%s", "Local", dialarg);
+ ast_cdr_setapp(outbound->cdr, "FollowMe", tmp);
+ ast_cdr_update(outbound);
+ ast_cdr_start(outbound->cdr);
+ ast_cdr_end(outbound->cdr);
+ /* If the cause wasn't handled properly */
+ if (ast_cdr_disposition(outbound->cdr, outbound->hangupcause)) {
+ ast_cdr_failed(outbound->cdr);
}
+ } else {
+ ast_log(LOG_ERROR, "Unable to create Call Detail Record\n");
}
+ ast_hangup(outbound);
+ ast_free(tmpuser);
}
- } else
+ } else {
ast_log(LOG_WARNING, "Unable to allocate a channel for Local/%s cause: %s\n", dialarg, ast_cause2str(dg));
+ ast_free(tmpuser);
+ }
+ }
- number = rest;
- } while (number);
+ if (AST_LIST_EMPTY(findme_user_list)) {
+ continue;
+ }
status = 0;
- if (!AST_LIST_EMPTY(findme_user_list))
- winner = wait_for_winner(findme_user_list, nm, caller, tpargs->namerecloc, &status, tpargs);
+ winner = wait_for_winner(findme_user_list, nm, caller, tpargs->namerecloc, &status, tpargs);
+ /* Clean up all calls but winner. */
while ((fmuser = AST_LIST_REMOVE_HEAD(findme_user_list, entry))) {
- if (!fmuser->cleared && fmuser->ochan != winner)
+ if (!fmuser->cleared && fmuser->ochan != winner) {
clear_caller(fmuser);
+ }
ast_free(fmuser);
}
-
- fmuser = NULL;
- tmpuser = NULL;
- if (winner)
- break;
-
- if (!caller || ast_check_hangup(caller)) {
- tpargs->status = 1;
- ast_free(findme_user_list);
- return;
- }
-
- idx++;
- AST_LIST_TRAVERSE(&tpargs->cnumbers, nm, entry) {
- if (nm->order == idx)
- break;
- }
}
- ast_free(findme_user_list);
- if (!winner)
+ destroy_calling_tree(findme_user_list);
+ if (!winner) {
tpargs->status = 1;
- else {
+ } else {
tpargs->status = 100;
tpargs->outbound = winner;
}
-
- return;
}
static struct call_followme *find_realtime(const char *name)
@@ -1049,10 +1050,7 @@ static int app_exec(struct ast_channel *chan, const char *data)
return -1;
}
- if (!(argstr = ast_strdupa((char *)data))) {
- ast_log(LOG_ERROR, "Out of memory!\n");
- return -1;
- }
+ argstr = ast_strdupa((char *) data);
AST_STANDARD_APP_ARGS(args, argstr);
@@ -1100,7 +1098,9 @@ static int app_exec(struct ast_channel *chan, const char *data)
AST_LIST_HEAD_INIT_NOLOCK(&targs.cnumbers);
AST_LIST_TRAVERSE(&f->numbers, nm, entry) {
newnm = create_followme_number(nm->number, nm->timeout, nm->order);
- AST_LIST_INSERT_TAIL(&targs.cnumbers, newnm, entry);
+ if (newnm) {
+ AST_LIST_INSERT_TAIL(&targs.cnumbers, newnm, entry);
+ }
}
ast_mutex_unlock(&f->lock);
@@ -1182,11 +1182,10 @@ static int app_exec(struct ast_channel *chan, const char *data)
goto outrun;
}
res = ast_bridge_call(caller, outbound, &config);
- if (outbound)
- ast_hangup(outbound);
+ ast_hangup(outbound);
}
- outrun:
+outrun:
if (f->realtime) {
/* Not in list */