[svn-commits] murf: trunk r89346 - /trunk/main/pbx.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Nov 16 17:33:32 CST 2007


Author: murf
Date: Fri Nov 16 17:33:32 2007
New Revision: 89346

URL: http://svn.digium.com/view/asterisk?view=rev&rev=89346
Log:
My goodness, haven't handled an extension deletion. Add code to ast_context_remove_extension2() to remove an extension from the trie. Done by marking it deleted. The scoreboard won't update for it any more. Also, a couple of calls to insert hashtab had a spurious ->exten, which was removed.

Modified:
    trunk/main/pbx.c

Modified: trunk/main/pbx.c
URL: http://svn.digium.com/view/asterisk/trunk/main/pbx.c?view=diff&rev=89346&r1=89345&r2=89346
==============================================================================
--- trunk/main/pbx.c (original)
+++ trunk/main/pbx.c Fri Nov 16 17:33:32 2007
@@ -825,13 +825,18 @@
  */
 
 
-static void update_scoreboard(struct scoreboard *board, int length, int spec, struct ast_exten *exten, char last, const char *callerid)
+static void update_scoreboard(struct scoreboard *board, int length, int spec, struct ast_exten *exten, char last, const char *callerid, int deleted)
 {
 	/* doing a matchcid() check here would be easy and cheap, but...
 	   unfortunately, it only works if an extension can have only one 
 	   cid to match. That's not real life. CID patterns need to exist 
 	   in the tree for this sort of thing to work properly. */
 
+	/* if this extension is marked as deleted, then skip this -- if it never shows
+	   on the scoreboard, it will never be found */
+	if (deleted)
+		return;
+	
 	if (length > board->total_length) {
 		board->total_specificity = spec;
 		board->total_length = length;
@@ -891,7 +896,7 @@
 	for (p=tree; p; p=p->alt_char) {
 		if (p->x[0] == 'N' && p->x[1] == 0 && *str >= '2' && *str <= '9' ) {
 			if (p->exten) /* if a shorter pattern matches along the way, might as well report it */
-				update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid);
+				update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted);
 
 			if (p->next_char && ( *(str+1) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
 				if (*(str+1))
@@ -906,7 +911,7 @@
 			}
 		} else if (p->x[0] == 'Z' && p->x[1] == 0 && *str >= '1' && *str <= '9' ) {
 			if (p->exten) /* if a shorter pattern matches along the way, might as well report it */
-				update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid);
+				update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted);
 
 			if (p->next_char && ( *(str+1) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
 				if (*(str+1))
@@ -921,7 +926,7 @@
 			}
 		} else if (p->x[0] == 'X' && p->x[1] == 0 && *str >= '0' && *str <= '9' ) {
 			if (p->exten) /* if a shorter pattern matches along the way, might as well report it */
-				update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid);
+				update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted);
 
 			if (p->next_char && ( *(str+1) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
 				if (*(str+1))
@@ -941,7 +946,7 @@
 				i++;
 			}
 			if (p->exten)
-				update_scoreboard(score, length+i, spec+(i*p->specificity), p->exten, '.', callerid);
+				update_scoreboard(score, length+i, spec+(i*p->specificity), p->exten, '.', callerid, p->deleted);
 			if (p->next_char && p->next_char->x[0] == '/' && p->next_char->x[1] == 0) {
 				new_find_extension("/", score, p->next_char, length+i, spec+(p->specificity*i), callerid);
 			}
@@ -953,7 +958,7 @@
 				i++;
 			}
 			if (p->exten)
-				update_scoreboard(score, length+1, spec+(p->specificity*i), p->exten, '!', callerid);
+				update_scoreboard(score, length+1, spec+(p->specificity*i), p->exten, '!', callerid, p->deleted);
 			if (p->next_char && p->next_char->x[0] == '/' && p->next_char->x[1] == 0) {
 				new_find_extension("/", score, p->next_char, length+i, spec+(p->specificity*i), callerid);
 			}
@@ -965,7 +970,7 @@
 			}
 		} else if (index(p->x, *str)) {
 			if (p->exten) /* if a shorter pattern matches along the way, might as well report it */
-				update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid);
+				update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted);
 
 
 			if (p->next_char && ( *(str+1) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
@@ -1154,7 +1159,10 @@
 #endif
 	t1 = ast_hashtab_start_traversal(con->root_tree);
 	while( (e1 = ast_hashtab_next(t1)) ) {
-		add_exten_to_pattern_tree(con, e1);
+		if (e1->exten)
+			add_exten_to_pattern_tree(con, e1);
+		else
+			ast_log(LOG_ERROR,"Attempt to create extension with no extension name.\n");
 	}
 	ast_hashtab_end_traversal(t1);
 }
@@ -3594,6 +3602,50 @@
 
 	ast_wrlock_context(con);
 
+	/* Handle this is in the new world */
+
+	if (con->pattern_tree) {
+		/* find this particular extension */
+		struct ast_exten ex, *exten2;
+		char dummy_name[1024];
+		ex.exten = dummy_name;
+		ex.matchcid = 0;
+		ast_copy_string(dummy_name,extension, sizeof(dummy_name));
+		exten = ast_hashtab_lookup(con->root_tree, &ex);
+		if (exten) {
+			if (priority == 0)
+			{
+				/* success, this exten is in this pattern tree. */
+				struct match_char *x = add_exten_to_pattern_tree(con, exten);
+				if (x->exten) { /* this test for safety purposes */
+					x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
+					x->exten = 0; /* get rid of what will become a bad pointer */
+					ast_hashtab_remove_this_object(con->root_tree, exten);
+					ast_log(LOG_NOTICE,"Removed extension %s from context %s table\n",
+							exten->exten, con->name);
+				} else {
+					ast_log(LOG_WARNING,"Trying to delete an exten from a context, but the pattern tree node returned isn't a full extension\n");
+				}
+			} else {
+				ex.priority = priority;
+				exten2 = ast_hashtab_lookup(exten->peer_tree, &ex);
+				if (exten2) {
+					ast_hashtab_remove_this_object(exten->peer_tree, exten2);
+					ast_log(LOG_NOTICE,"Removed priority %d from extension %s context %s table\n",
+							priority, exten->exten, con->name);
+				} else {
+					ast_log(LOG_ERROR,"Could not find priority %d of exten %s in context %s!\n",
+							priority, exten->exten, con->name);
+				}
+			}
+		} else {
+			/* hmmm? this exten is not in this pattern tree? */
+			ast_log(LOG_WARNING,"Cannot find extension %s in pattern tree in context %s\n",
+					extension, con->name);
+		}
+	}
+	
+
 	/* scan the extension list to find matching extension-registrar */
 	for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
 		if (!strcmp(exten->exten, extension) &&
@@ -5565,7 +5617,7 @@
 			if (tmp->label)
 				ast_hashtab_insert_safe(tmp->peer_label_tree,tmp);
 			ast_hashtab_remove_object_via_lookup(con->root_tree, e);
-			ast_hashtab_insert_safe(con->root_tree, tmp->exten);
+			ast_hashtab_insert_safe(con->root_tree, tmp);
 			el->next = tmp;
 		} else {			/* We're the very first extension.  */
 			ast_hashtab_remove_object_via_lookup(con->root_tree,e);
@@ -5579,7 +5631,7 @@
 			if (tmp->label)
 			ast_hashtab_insert_safe(tmp->peer_label_tree,tmp);
 			ast_hashtab_remove_object_via_lookup(con->root_tree, e);
-			ast_hashtab_insert_safe(con->root_tree, tmp->exten);
+			ast_hashtab_insert_safe(con->root_tree, tmp);
  			con->root = tmp;
 		}
 		if (tmp->priority == PRIORITY_HINT)




More information about the svn-commits mailing list