From 6f8508e0dc91d74f9c126759b28d711eeffca2ac Mon Sep 17 00:00:00 2001 From: matteo Date: Wed, 12 Feb 2003 13:59:15 +0000 Subject: mer feb 12 14:56:57 CET 2003 git-svn-id: http://svn.digium.com/svn/asterisk/trunk@612 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/Makefile | 2 +- apps/app_agi.c | 2 - apps/app_macro.c | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++ apps/app_substring.c | 2 - 4 files changed, 235 insertions(+), 5 deletions(-) create mode 100755 apps/app_macro.c (limited to 'apps') diff --git a/apps/Makefile b/apps/Makefile index 1f08653bd..95f727531 100755 --- a/apps/Makefile +++ b/apps/Makefile @@ -17,7 +17,7 @@ APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_intercom. app_agi.so app_qcall.so app_adsiprog.so app_getcpeid.so app_milliwatt.so \ app_zapateller.so app_datetime.so app_setcallerid.so app_festival.so \ app_queue.so app_senddtmf.so app_parkandannounce.so app_striplsd.so \ - app_setcidname.so app_lookupcidname.so app_substring.so + app_setcidname.so app_lookupcidname.so app_substring.so app_macro.so #APPS+=app_sql_postgres.so #APPS+=app_sql_odbc.so diff --git a/apps/app_agi.c b/apps/app_agi.c index add410a80..91ca9749f 100755 --- a/apps/app_agi.c +++ b/apps/app_agi.c @@ -72,8 +72,6 @@ STANDARD_LOCAL_USER; LOCAL_USER_DECL; -extern char *pbx_builtin_getvar_helper(struct ast_channel *chan, char *name); -extern void pbx_builtin_setvar_helper(struct ast_channel *chan, char *name, char *value); #define TONE_BLOCK_SIZE 200 diff --git a/apps/app_macro.c b/apps/app_macro.c new file mode 100755 index 000000000..bb8b43de8 --- /dev/null +++ b/apps/app_macro.c @@ -0,0 +1,234 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * + * Macro Implementation + * + * Copyright (C) 2003, Digium + * + * Mark Spencer + * + * This program is free software, distributed under the terms of + * the GNU General Public License + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MAX_ARGS 80 + +static char *tdesc = "Extension Macros"; + +static char *descrip = +" Macro(macroname|arg1|arg2...): Executes a macro using the context\n" +"'macro-', jumping to the 's' extension of that context and\n" +"executing each step, then returning when the steps end. The calling\n" +"extension, context, and priority are stored in ${MACRO_EXTEN}, \n" +"${MACRO_CONTEXT} and ${MACRO_PRIORITY} respectively. Arguments become\n" +"${ARG1}, ${ARG2}, etc in the macro context. Macro returns -1 if\n" +"any step in the macro returns -1, and 0 otherwise. If you Goto out\n" +"of the Macro context, the Macro will terminate and control will be return\n" +"at the location of the Goto. Otherwise if ${MACRO_OFFSET} is set at\n" +"termination, Macro will attempt to continue at priority\n" +"MACRO_OFFSET + N + 1 if such a step exists, and N + 1 otherwise.\n"; + +static char *app = "Macro"; + +static char *synopsis = "Macro Implementation"; + +STANDARD_LOCAL_USER; + +LOCAL_USER_DECL; + +static int macro_exec(struct ast_channel *chan, void *data) +{ + char tmp[256] = ""; + char *cur, *rest; + char *macro; + char fullmacro[80]; + char varname[80]; + char *oldargs[MAX_ARGS + 1] = { NULL, }; + int argc, x; + int res; + char oldexten[256]=""; + int oldpriority; + char pc[80]; + char oldcontext[256] = ""; + char *offsets; + int offset; + + char *save_macro_exten; + char *save_macro_context; + char *save_macro_priority; + char *save_macro_offset; + + if (!data || !strlen(data)) { + ast_log(LOG_WARNING, "Invalid Macro incantation\n"); + return 0; + } + strncpy(tmp, data, sizeof(tmp) - 1); + rest = tmp; + macro = strsep(&rest, "|"); + if (!macro || !strlen(macro)) { + ast_log(LOG_WARNING, "Invalid macro name specified\n"); + return 0; + } + snprintf(fullmacro, sizeof(fullmacro), "macro-%s", macro); + if (!ast_exists_extension(chan, fullmacro, "s", 1, chan->callerid)) { + if (!ast_context_find(fullmacro)) + ast_log(LOG_WARNING, "No such context '%s' for macro '%s'\n", fullmacro, macro); + else + ast_log(LOG_WARNING, "Context '%s' for macro '%s' lacks 's' extension, priority 1\n", fullmacro, macro); + return 0; + } + /* Save old info */ + oldpriority = chan->priority; + strncpy(oldexten, chan->exten, sizeof(oldexten) - 1); + strncpy(oldcontext, chan->context, sizeof(oldcontext) - 1); + argc = 1; + /* Save old macro variables */ + save_macro_exten = pbx_builtin_getvar_helper(chan, "MACRO_EXTEN"); + if (save_macro_exten) save_macro_exten = strdup(save_macro_exten); + pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", oldexten); + + save_macro_context = pbx_builtin_getvar_helper(chan, "MACRO_CONTEXT"); + if (save_macro_context) save_macro_context = strdup(save_macro_context); + pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", oldcontext); + + save_macro_priority = pbx_builtin_getvar_helper(chan, "MACRO_PRIORITY"); + if (save_macro_priority) save_macro_priority = strdup(save_macro_priority); + snprintf(pc, sizeof(pc), "%d", oldpriority); + pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", pc); + + save_macro_offset = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"); + if (save_macro_offset) save_macro_offset = strdup(save_macro_offset); + pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", NULL); + + /* Setup environment for new run */ + strcpy(chan->exten, "s"); + strncpy(chan->context, fullmacro, sizeof(chan->context)); + chan->priority = 1; + + while((cur = strsep(&rest, "|")) && (argc < MAX_ARGS)) { + /* Save copy of old arguments if we're overwriting some, otherwise + let them pass through to the other macro */ + oldargs[argc] = pbx_builtin_getvar_helper(chan, varname); + if (oldargs[argc]) + oldargs[argc] = strdup(oldargs[argc]); + snprintf(varname, sizeof(varname), "ARG%d", argc); + pbx_builtin_setvar_helper(chan, varname, cur); + argc++; + } + while(ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->callerid)) { + if ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->callerid))) { + /* Something bad happened, or a hangup has been requested. */ + if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F'))) { + /* Just return result as to the previous application as if it had been dialed */ + ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res); + break; + } + switch(res) { + case AST_PBX_KEEPALIVE: + if (option_debug) + ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE in macro %s on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name); + else if (option_verbose > 1) + ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE in macro '%s' on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name); + goto out; + break; + default: + if (option_debug) + ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro); + else if (option_verbose > 1) + ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro); + goto out; + } + } + if (strcasecmp(chan->context, fullmacro)) { + if (option_verbose > 1) + ast_verbose(VERBOSE_PREFIX_2 "Channel '%s' jumping out of macro '%s'\n", chan->name, macro); + break; + } + if (chan->_softhangup) { + ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n", + chan->exten, chan->priority); + goto out; + } + chan->priority++; + } +out: + for (x=1;xcontext, fullmacro)) { + /* If we're leaving the macro normally, restore original information */ + chan->priority = oldpriority; + strncpy(chan->exten, oldexten, sizeof(chan->exten) - 1); + strncpy(chan->context, oldcontext, sizeof(chan->context) - 1); + 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 */ + if (sscanf(offsets, "%d", &offset) == 1) { + if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + offset + 1, chan->callerid)) { + chan->priority += offset; + } + } + } + } + + pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset); + if (save_macro_offset) free(save_macro_offset); + return res; +} + +int unload_module(void) +{ + STANDARD_HANGUP_LOCALUSERS; + return ast_unregister_application(app); +} + +int load_module(void) +{ + return ast_register_application(app, macro_exec, synopsis, descrip); +} + +char *description(void) +{ + return tdesc; +} + +int usecount(void) +{ + int res; + STANDARD_USECOUNT(res); + return res; +} + +char *key() +{ + return ASTERISK_GPL_KEY; +} diff --git a/apps/app_substring.c b/apps/app_substring.c index a1edf64ae..97f0fea0a 100755 --- a/apps/app_substring.c +++ b/apps/app_substring.c @@ -27,8 +27,6 @@ static char *tdesc = "Save substring digits in a given variable"; -extern void pbx_builtin_setvar_helper(struct ast_channel *chan, char *name, char *value); - static char *descrip = " StripLSD(variable=string_of_digits|count1|count2): Assigns the substring\n" "of string_of_digits to a given variable. Parameter count1 may be positive\n" -- cgit v1.2.3