From 278a0a089138b2738653d1057ac9f2431aed6841 Mon Sep 17 00:00:00 2001 From: Mark Spencer <markster@digium.com> Date: Thu, 13 Jan 2005 05:14:56 +0000 Subject: [PATCH] Implement eswitch for evalulating variables at runtime (bug #3168) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4780 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- configs/extensions.conf.sample | 6 ++++++ include/asterisk/pbx.h | 5 +++-- pbx.c | 37 +++++++++++++++++++++++++--------- pbx/pbx_config.c | 4 ++-- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/configs/extensions.conf.sample b/configs/extensions.conf.sample index 7ff155af78..ecbaa5a6f4 100755 --- a/configs/extensions.conf.sample +++ b/configs/extensions.conf.sample @@ -254,6 +254,12 @@ include => iaxprovider ; be substituted in the switch routine itself) ; ; lswitch => Loopback/12${EXTEN}@othercontext +; +; An "eswitch" is like a switch but the evaluation of +; variable substitution is performed at runtime before +; being passed to the switch routine. +; +; eswitch => IAX2/context@${CURSERVER} [macro-stdexten]; ; diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h index 33aa1b589a..1c48b456a7 100755 --- a/include/asterisk/pbx.h +++ b/include/asterisk/pbx.h @@ -424,16 +424,17 @@ int ast_context_verify_includes(struct ast_context *con); * \param context context to which to add the switch * \param sw switch to add * \param data data to pass to switch + * \param eval whether to evaluate variables when running switch * \param registrar whoever registered the switch * This function registers a switch with the asterisk switch architecture * It returns 0 on success, -1 on failure */ -int ast_context_add_switch(const char *context, const char *sw, const char *data, const char *registrar); +int ast_context_add_switch(const char *context, const char *sw, const char *data, int eval, const char *registrar); //! Adds a switch (first param is a ast_context) /*! * See ast_context_add_switch() */ -int ast_context_add_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar); +int ast_context_add_switch2(struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar); //! Remove a switch /*! diff --git a/pbx.c b/pbx.c index 2b506dc9db..fcfbb45785 100755 --- a/pbx.c +++ b/pbx.c @@ -56,6 +56,9 @@ #define EXT_DATA_SIZE 8192 #endif +#define SWITCH_DATA_LENGTH 256 + + #define VAR_NORMAL 1 #define VAR_SOFTTRAN 2 #define VAR_HARDTRAN 3 @@ -95,7 +98,9 @@ struct ast_sw { char *name; const char *registrar; /* Registrar */ char *data; /* Data load */ + int eval; struct ast_sw *next; /* Link them together */ + char *tmpdata; char stuff[0]; }; @@ -758,16 +763,19 @@ static struct ast_exten *pbx_find_extension(struct ast_channel *chan, struct ast sw = tmp->alts; while(sw) { if ((asw = pbx_findswitch(sw->name))) { + /* Substitute variables now */ + if (sw->eval) + pbx_substitute_variables_helper(chan, sw->data, sw->tmpdata, SWITCH_DATA_LENGTH - 1); if (action == HELPER_CANMATCH) - res = asw->canmatch ? asw->canmatch(chan, context, exten, priority, callerid, sw->data) : 0; + res = asw->canmatch ? asw->canmatch(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; else if (action == HELPER_MATCHMORE) - res = asw->matchmore ? asw->matchmore(chan, context, exten, priority, callerid, sw->data) : 0; + res = asw->matchmore ? asw->matchmore(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; else - res = asw->exists ? asw->exists(chan, context, exten, priority, callerid, sw->data) : 0; + res = asw->exists ? asw->exists(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; if (res) { /* Got a match */ *swo = asw; - *data = sw->data; + *data = sw->eval ? sw->tmpdata : sw->data; *foundcontext = context; return NULL; } @@ -3612,7 +3620,7 @@ int ast_context_add_include2(struct ast_context *con, const char *value, * EBUSY - can't lock * ENOENT - no existence of context */ -int ast_context_add_switch(const char *context, const char *sw, const char *data, const char *registrar) +int ast_context_add_switch(const char *context, const char *sw, const char *data, int eval, const char *registrar) { struct ast_context *c; @@ -3626,7 +3634,7 @@ int ast_context_add_switch(const char *context, const char *sw, const char *data while (c) { /* ... search for the right one ... */ if (!strcmp(ast_get_context_name(c), context)) { - int ret = ast_context_add_switch2(c, sw, data, registrar); + int ret = ast_context_add_switch2(c, sw, data, eval, registrar); /* ... unlock contexts list and return */ ast_unlock_contexts(); return ret; @@ -3648,7 +3656,7 @@ int ast_context_add_switch(const char *context, const char *sw, const char *data * EINVAL - there is no existence of context for inclusion */ int ast_context_add_switch2(struct ast_context *con, const char *value, - const char *data, const char *registrar) + const char *data, int eval, const char *registrar) { struct ast_sw *new_sw; struct ast_sw *i, *il = NULL; /* sw, sw_last */ @@ -3660,6 +3668,11 @@ int ast_context_add_switch2(struct ast_context *con, const char *value, if (data) length += strlen(data); length++; + if (eval) { + /* Create buffer for evaluation of variables */ + length += SWITCH_DATA_LENGTH; + length++; + } /* allocate new sw structure ... */ if (!(new_sw = malloc(length))) { @@ -3675,11 +3688,17 @@ int ast_context_add_switch2(struct ast_context *con, const char *value, strcpy(new_sw->name, value); p += strlen(value) + 1; new_sw->data = p; - if (data) + if (data) { strcpy(new_sw->data, data); - else + p += strlen(data) + 1; + } else { strcpy(new_sw->data, ""); + p++; + } + if (eval) + new_sw->tmpdata = p; new_sw->next = NULL; + new_sw->eval = eval; new_sw->registrar = registrar; /* ... try to lock this context ... */ diff --git a/pbx/pbx_config.c b/pbx/pbx_config.c index 63c66016cb..84420bad40 100755 --- a/pbx/pbx_config.c +++ b/pbx/pbx_config.c @@ -1754,7 +1754,7 @@ static int pbx_load_module(void) pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); if (ast_context_add_ignorepat2(con, realvalue, registrar)) ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt); - } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch")) { + } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) { char *stringp=NULL; memset(realvalue, 0, sizeof(realvalue)); if (!strcasecmp(v->name, "switch")) @@ -1767,7 +1767,7 @@ static int pbx_load_module(void) data = strsep(&stringp, ""); if (!data) data = ""; - if (ast_context_add_switch2(con, appl, data, registrar)) + if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar)) ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt); } v = v->next; -- GitLab