mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-11-03 20:38:59 +00:00 
			
		
		
		
	Merged revisions 165317 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r165317 | tilghman | 2008-12-17 15:14:37 -0600 (Wed, 17 Dec 2008) | 4 lines Reverse the fix from issue #6176 and add proper handling for that issue. (Closes issue #13962, closes issue #13363) Fixed by myself (license 14) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@165319 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		@@ -155,6 +155,31 @@ static char *if_app = "MacroIf";
 | 
			
		||||
static char *exclusive_app = "MacroExclusive";
 | 
			
		||||
static char *exit_app = "MacroExit";
 | 
			
		||||
 | 
			
		||||
static void macro_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
 | 
			
		||||
 | 
			
		||||
struct ast_datastore_info macro_ds_info = {
 | 
			
		||||
	.type = "MACRO",
 | 
			
		||||
	.chan_fixup = macro_fixup,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void macro_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	char varname[10];
 | 
			
		||||
	pbx_builtin_setvar_helper(new_chan, "MACRO_DEPTH", "0");
 | 
			
		||||
	pbx_builtin_setvar_helper(new_chan, "MACRO_CONTEXT", NULL);
 | 
			
		||||
	pbx_builtin_setvar_helper(new_chan, "MACRO_EXTEN", NULL);
 | 
			
		||||
	pbx_builtin_setvar_helper(new_chan, "MACRO_PRIORITY", NULL);
 | 
			
		||||
	pbx_builtin_setvar_helper(new_chan, "MACRO_OFFSET", NULL);
 | 
			
		||||
	for (i = 1; i < 100; i++) {
 | 
			
		||||
		snprintf(varname, sizeof(varname), "ARG%d", i);
 | 
			
		||||
		while (pbx_builtin_getvar_helper(new_chan, varname)) {
 | 
			
		||||
			/* Kill all levels of arguments */
 | 
			
		||||
			pbx_builtin_setvar_helper(new_chan, varname, NULL);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct ast_exten *find_matching_priority(struct ast_context *c, const char *exten, int priority, const char *callerid)
 | 
			
		||||
{
 | 
			
		||||
	struct ast_exten *e;
 | 
			
		||||
@@ -209,18 +234,32 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
 | 
			
		||||
	const char *inhangupc;
 | 
			
		||||
	int offset, depth = 0, maxdepth = 7;
 | 
			
		||||
	int setmacrocontext=0;
 | 
			
		||||
	int autoloopflag, dead = 0, inhangup = 0;
 | 
			
		||||
	int autoloopflag, inhangup = 0;
 | 
			
		||||
  
 | 
			
		||||
	char *save_macro_exten;
 | 
			
		||||
	char *save_macro_context;
 | 
			
		||||
	char *save_macro_priority;
 | 
			
		||||
	char *save_macro_offset;
 | 
			
		||||
	struct ast_datastore *macro_store = ast_channel_datastore_find(chan, ¯o_ds_info, NULL);
 | 
			
		||||
 
 | 
			
		||||
	if (ast_strlen_zero(data)) {
 | 
			
		||||
		ast_log(LOG_WARNING, "Macro() requires arguments. See \"core show application macro\" for help.\n");
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		if (macro_store) {
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		if (!(macro_store = ast_channel_datastore_alloc(¯o_ds_info, NULL))) {
 | 
			
		||||
			ast_log(LOG_WARNING, "Unable to allocate new datastore.\n");
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		/* Just the existence of this datastore is enough. */
 | 
			
		||||
		macro_store->inheritance = DATASTORE_INHERIT_FOREVER;
 | 
			
		||||
		ast_channel_datastore_add(chan, macro_store);
 | 
			
		||||
	} while (0);
 | 
			
		||||
 | 
			
		||||
	/* does the user want a deeper rabbit hole? */
 | 
			
		||||
	ast_channel_lock(chan);
 | 
			
		||||
	if ((s = pbx_builtin_getvar_helper(chan, "MACRO_RECURSION"))) {
 | 
			
		||||
@@ -370,12 +409,10 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
 | 
			
		||||
			case AST_PBX_KEEPALIVE:
 | 
			
		||||
				ast_debug(2, "Spawn extension (%s,%s,%d) exited KEEPALIVE in macro %s on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
 | 
			
		||||
				ast_verb(2, "Spawn extension (%s, %s, %d) exited KEEPALIVE in macro '%s' on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
 | 
			
		||||
				dead = 1;
 | 
			
		||||
				goto out;
 | 
			
		||||
			default:
 | 
			
		||||
				ast_debug(2, "Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
 | 
			
		||||
				ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
 | 
			
		||||
				dead = 1;
 | 
			
		||||
				goto out;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -448,31 +485,30 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
 | 
			
		||||
		chan->priority++;
 | 
			
		||||
  	}
 | 
			
		||||
	out:
 | 
			
		||||
 | 
			
		||||
	/* Don't let the channel change now. */
 | 
			
		||||
	ast_channel_lock(chan);
 | 
			
		||||
 | 
			
		||||
	/* Reset the depth back to what it was when the routine was entered (like if we called Macro recursively) */
 | 
			
		||||
	snprintf(depthc, sizeof(depthc), "%d", depth);
 | 
			
		||||
	if (!dead) {
 | 
			
		||||
		pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
 | 
			
		||||
		ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP);
 | 
			
		||||
	}
 | 
			
		||||
	pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
 | 
			
		||||
	ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP);
 | 
			
		||||
 | 
			
		||||
  	for (x = 1; x < argc; x++) {
 | 
			
		||||
  		/* Restore old arguments and delete ours */
 | 
			
		||||
		snprintf(varname, sizeof(varname), "ARG%d", x);
 | 
			
		||||
  		if (oldargs[x]) {
 | 
			
		||||
			if (!dead)
 | 
			
		||||
				pbx_builtin_setvar_helper(chan, varname, oldargs[x]);
 | 
			
		||||
			pbx_builtin_setvar_helper(chan, varname, oldargs[x]);
 | 
			
		||||
			ast_free(oldargs[x]);
 | 
			
		||||
		} else if (!dead) {
 | 
			
		||||
		} else {
 | 
			
		||||
			pbx_builtin_setvar_helper(chan, varname, NULL);
 | 
			
		||||
		}
 | 
			
		||||
  	}
 | 
			
		||||
 | 
			
		||||
	/* Restore macro variables */
 | 
			
		||||
	if (!dead) {
 | 
			
		||||
		pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten);
 | 
			
		||||
		pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context);
 | 
			
		||||
		pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority);
 | 
			
		||||
	}
 | 
			
		||||
	pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten);
 | 
			
		||||
	pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context);
 | 
			
		||||
	pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority);
 | 
			
		||||
	if (save_macro_exten)
 | 
			
		||||
		ast_free(save_macro_exten);
 | 
			
		||||
	if (save_macro_context)
 | 
			
		||||
@@ -480,13 +516,13 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
 | 
			
		||||
	if (save_macro_priority)
 | 
			
		||||
		ast_free(save_macro_priority);
 | 
			
		||||
 | 
			
		||||
	if (!dead && setmacrocontext) {
 | 
			
		||||
	if (setmacrocontext) {
 | 
			
		||||
		chan->macrocontext[0] = '\0';
 | 
			
		||||
		chan->macroexten[0] = '\0';
 | 
			
		||||
		chan->macropriority = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!dead && !strcasecmp(chan->context, fullmacro)) {
 | 
			
		||||
	if (!strcasecmp(chan->context, fullmacro)) {
 | 
			
		||||
  		/* If we're leaving the macro normally, restore original information */
 | 
			
		||||
		chan->priority = oldpriority;
 | 
			
		||||
		ast_copy_string(chan->context, oldcontext, sizeof(chan->context));
 | 
			
		||||
@@ -494,7 +530,6 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
 | 
			
		||||
			/* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */
 | 
			
		||||
			const char *offsets;
 | 
			
		||||
			ast_copy_string(chan->exten, oldexten, sizeof(chan->exten));
 | 
			
		||||
			ast_channel_lock(chan);
 | 
			
		||||
			if ((offsets = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"))) {
 | 
			
		||||
				/* Handle macro offset if it's set by checking the availability of step n + offset + 1, otherwise continue
 | 
			
		||||
			   	normally if there is any problem */
 | 
			
		||||
@@ -504,12 +539,10 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			ast_channel_unlock(chan);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!dead)
 | 
			
		||||
		pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset);
 | 
			
		||||
	pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset);
 | 
			
		||||
	if (save_macro_offset)
 | 
			
		||||
		ast_free(save_macro_offset);
 | 
			
		||||
 | 
			
		||||
@@ -521,6 +554,7 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
 | 
			
		||||
			res = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	ast_channel_unlock(chan);
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user