aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-07-04 03:30:30 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-07-04 03:30:30 +0000
commitdcdab9324c53636c7b5c6b4b16f4708f237bfd27 (patch)
tree283ff324f759348a8b8aba09c88d03f2cc5df46b /main
parent9bb2e9bc7abd199a52f6a6d115df504af751d35c (diff)
Fix the 'dialplan remove extension' logic, so that it a) works with cidmatch,
and b) completes contexts correctly when the extension is ambiguous. (closes issue #12980) Reported by: licedey Patches: 20080703__bug12980.diff.txt uploaded by Corydon76 (license 14) Tested by: Corydon76 git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@127973 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r--main/pbx.c92
1 files changed, 46 insertions, 46 deletions
diff --git a/main/pbx.c b/main/pbx.c
index 107840c9a..f4e5a150c 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -2805,11 +2805,16 @@ int ast_context_remove_switch2(struct ast_context *con, const char *sw, const ch
*/
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
{
+ return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar);
+}
+
+int ast_context_remove_extension_callerid(const char *context, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar)
+{
int ret = -1; /* default error return */
struct ast_context *c = find_context_locked(context);
if (c) { /* ... remove extension ... */
- ret = ast_context_remove_extension2(c, extension, priority, registrar);
+ ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar);
ast_unlock_contexts();
}
return ret;
@@ -2827,12 +2832,20 @@ int ast_context_remove_extension(const char *context, const char *extension, int
*/
int ast_context_remove_extension2(struct ast_context *con, const char *extension, int priority, const char *registrar)
{
+ return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar);
+}
+
+int ast_context_remove_extension_callerid2(struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar)
+{
struct ast_exten *exten, *prev_exten = NULL;
struct ast_exten *peer;
+ struct ast_exten *previous_peer = NULL;
+ struct ast_exten *next_peer = NULL;
+ int found = 0;
ast_mutex_lock(&con->lock);
- /* scan the extension list to find matching extension-registrar */
+ /* scan the extension list to find first matching extension-registrar */
for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
if (!strcmp(exten->exten, extension) &&
(!registrar || !strcmp(exten->registrar, registrar)))
@@ -2844,56 +2857,43 @@ int ast_context_remove_extension2(struct ast_context *con, const char *extension
return -1;
}
- /* should we free all peers in this extension? (priority == 0)? */
- if (priority == 0) {
- /* remove this extension from context list */
- if (prev_exten)
- prev_exten->next = exten->next;
- else
- con->root = exten->next;
+ /* scan the priority list to remove extension with exten->priority == priority */
+ for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next;
+ peer && !strcmp(peer->exten, extension);
+ peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) {
+ if ((priority == 0 || peer->priority == priority) &&
+ (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) &&
+ (!registrar || !strcmp(peer->registrar, registrar) )) {
+ found = 1;
- /* fire out all peers */
- while ( (peer = exten) ) {
- exten = peer->peer; /* prepare for next entry */
- destroy_exten(peer);
- }
- } else {
- /* scan the priority list to remove extension with exten->priority == priority */
- struct ast_exten *previous_peer = NULL;
+ /* we are first priority extension? */
+ if (!previous_peer) {
+ /*
+ * We are first in the priority chain, so must update the extension chain.
+ * The next node is either the next priority or the next extension
+ */
+ struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
- for (peer = exten; peer; previous_peer = peer, peer = peer->peer) {
- if (peer->priority == priority &&
- (!registrar || !strcmp(peer->registrar, registrar) ))
- break; /* found our priority */
- }
- if (!peer) { /* not found */
- ast_mutex_unlock(&con->lock);
- return -1;
- }
- /* we are first priority extension? */
- if (!previous_peer) {
- /*
- * We are first in the priority chain, so must update the extension chain.
- * The next node is either the next priority or the next extension
- */
- struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
+ if (!prev_exten) { /* change the root... */
+ con->root = next_node;
+ } else {
+ prev_exten->next = next_node; /* unlink */
+ }
+ if (peer->peer) { /* update the new head of the pri list */
+ peer->peer->next = peer->next;
+ }
+ } else { /* easy, we are not first priority in extension */
+ previous_peer->peer = peer->peer;
+ }
- if (!prev_exten) /* change the root... */
- con->root = next_node;
- else
- prev_exten->next = next_node; /* unlink */
- if (peer->peer) /* XXX update the new head of the pri list */
- peer->peer->next = peer->next;
- } else { /* easy, we are not first priority in extension */
- previous_peer->peer = peer->peer;
+ /* now, free whole priority extension */
+ destroy_exten(peer);
+ } else {
+ previous_peer = peer;
}
-
- /* now, free whole priority extension */
- destroy_exten(peer);
- /* XXX should we return -1 ? */
}
ast_mutex_unlock(&con->lock);
- return 0;
+ return found ? 0 : -1;
}