#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
Go to the source code of this file.
Defines | |
#define | MACRO_EXIT_RESULT 1024 |
#define | MAX_ARGS 80 |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | _macro_exec (struct ast_channel *chan, void *data, int exclusive) |
static struct ast_exten * | find_matching_priority (struct ast_context *c, const char *exten, int priority, const char *callerid) |
static int | load_module (void) |
static int | macro_exec (struct ast_channel *chan, void *data) |
static int | macro_exit_exec (struct ast_channel *chan, void *data) |
static void | macro_fixup (void *data, struct ast_channel *old_chan, struct ast_channel *new_chan) |
static int | macroexclusive_exec (struct ast_channel *chan, void *data) |
static int | macroif_exec (struct ast_channel *chan, void *data) |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Extension Macros" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } |
static char * | app = "Macro" |
static struct ast_module_info * | ast_module_info = &__mod_info |
static char * | descrip |
static char * | exclusive_app = "MacroExclusive" |
static char * | exclusive_descrip |
static char * | exclusive_synopsis = "Exclusive Macro Implementation" |
static char * | exit_app = "MacroExit" |
static char * | exit_descrip |
static char * | exit_synopsis = "Exit From Macro" |
static char * | if_app = "MacroIf" |
static char * | if_descrip |
static char * | if_synopsis = "Conditional Macro Implementation" |
ast_datastore_info | macro_ds_info |
static char * | synopsis = "Macro Implementation" |
Definition in file app_macro.c.
#define MACRO_EXIT_RESULT 1024 |
#define MAX_ARGS 80 |
Definition at line 40 of file app_macro.c.
Referenced by _macro_exec(), agi_exec_full(), agi_handle_command(), and parse_args().
static void __reg_module | ( | void | ) | [static] |
Definition at line 560 of file app_macro.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 560 of file app_macro.c.
static int _macro_exec | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | exclusive | |||
) | [static] |
Definition at line 156 of file app_macro.c.
References app2, ast_autoservice_start(), ast_autoservice_stop(), ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_copy_string(), ast_datastore_alloc(), ast_debug, ast_exists_extension(), AST_FLAG_IN_AUTOLOOP, ast_free, ast_get_context_name(), ast_get_extension_app(), ast_get_extension_app_data(), ast_log(), AST_MAX_CONTEXT, ast_rdlock_context(), ast_rdlock_contexts(), ast_set2_flag, ast_set_flag, AST_SOFTHANGUP_ASYNCGOTO, ast_spawn_extension(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_unlock_context(), ast_unlock_contexts(), ast_verb, ast_walk_contexts(), chan, ast_channel::cid, ast_callerid::cid_num, cond, ast_channel::context, DATASTORE_INHERIT_FOREVER, ast_channel::exten, find_matching_priority(), ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, macro_ds_info, MACRO_EXIT_RESULT, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::macropriority, MAX_ARGS, ast_channel::name, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_checkcondition(), pbx_substitute_variables_helper(), ast_channel::priority, s, and strsep().
Referenced by macro_exec(), and macroexclusive_exec().
00157 { 00158 const char *s; 00159 char *tmp; 00160 char *cur, *rest; 00161 char *macro; 00162 char fullmacro[80]; 00163 char varname[80]; 00164 char runningapp[80], runningdata[1024]; 00165 char *oldargs[MAX_ARGS + 1] = { NULL, }; 00166 int argc, x; 00167 int res=0; 00168 char oldexten[256]=""; 00169 int oldpriority, gosub_level = 0; 00170 char pc[80], depthc[12]; 00171 char oldcontext[AST_MAX_CONTEXT] = ""; 00172 const char *inhangupc; 00173 int offset, depth = 0, maxdepth = 7; 00174 int setmacrocontext=0; 00175 int autoloopflag, inhangup = 0; 00176 00177 char *save_macro_exten; 00178 char *save_macro_context; 00179 char *save_macro_priority; 00180 char *save_macro_offset; 00181 struct ast_datastore *macro_store = ast_channel_datastore_find(chan, ¯o_ds_info, NULL); 00182 00183 if (ast_strlen_zero(data)) { 00184 ast_log(LOG_WARNING, "Macro() requires arguments. See \"core show application macro\" for help.\n"); 00185 return -1; 00186 } 00187 00188 do { 00189 if (macro_store) { 00190 break; 00191 } 00192 if (!(macro_store = ast_datastore_alloc(¯o_ds_info, NULL))) { 00193 ast_log(LOG_WARNING, "Unable to allocate new datastore.\n"); 00194 break; 00195 } 00196 /* Just the existence of this datastore is enough. */ 00197 macro_store->inheritance = DATASTORE_INHERIT_FOREVER; 00198 ast_channel_datastore_add(chan, macro_store); 00199 } while (0); 00200 00201 /* does the user want a deeper rabbit hole? */ 00202 ast_channel_lock(chan); 00203 if ((s = pbx_builtin_getvar_helper(chan, "MACRO_RECURSION"))) { 00204 sscanf(s, "%d", &maxdepth); 00205 } 00206 00207 /* Count how many levels deep the rabbit hole goes */ 00208 if ((s = pbx_builtin_getvar_helper(chan, "MACRO_DEPTH"))) { 00209 sscanf(s, "%d", &depth); 00210 } 00211 00212 /* Used for detecting whether to return when a Macro is called from another Macro after hangup */ 00213 if (strcmp(chan->exten, "h") == 0) 00214 pbx_builtin_setvar_helper(chan, "MACRO_IN_HANGUP", "1"); 00215 00216 if ((inhangupc = pbx_builtin_getvar_helper(chan, "MACRO_IN_HANGUP"))) { 00217 sscanf(inhangupc, "%d", &inhangup); 00218 } 00219 ast_channel_unlock(chan); 00220 00221 if (depth >= maxdepth) { 00222 ast_log(LOG_ERROR, "Macro(): possible infinite loop detected. Returning early.\n"); 00223 return 0; 00224 } 00225 snprintf(depthc, sizeof(depthc), "%d", depth + 1); 00226 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); 00227 00228 tmp = ast_strdupa(data); 00229 rest = tmp; 00230 macro = strsep(&rest, ","); 00231 if (ast_strlen_zero(macro)) { 00232 ast_log(LOG_WARNING, "Invalid macro name specified\n"); 00233 return 0; 00234 } 00235 00236 snprintf(fullmacro, sizeof(fullmacro), "macro-%s", macro); 00237 if (!ast_exists_extension(chan, fullmacro, "s", 1, chan->cid.cid_num)) { 00238 if (!ast_context_find(fullmacro)) 00239 ast_log(LOG_WARNING, "No such context '%s' for macro '%s'\n", fullmacro, macro); 00240 else 00241 ast_log(LOG_WARNING, "Context '%s' for macro '%s' lacks 's' extension, priority 1\n", fullmacro, macro); 00242 return 0; 00243 } 00244 00245 /* If we are to run the macro exclusively, take the mutex */ 00246 if (exclusive) { 00247 ast_debug(1, "Locking macrolock for '%s'\n", fullmacro); 00248 ast_autoservice_start(chan); 00249 if (ast_context_lockmacro(fullmacro)) { 00250 ast_log(LOG_WARNING, "Failed to lock macro '%s' as in-use\n", fullmacro); 00251 ast_autoservice_stop(chan); 00252 return 0; 00253 } 00254 ast_autoservice_stop(chan); 00255 } 00256 00257 /* Save old info */ 00258 oldpriority = chan->priority; 00259 ast_copy_string(oldexten, chan->exten, sizeof(oldexten)); 00260 ast_copy_string(oldcontext, chan->context, sizeof(oldcontext)); 00261 if (ast_strlen_zero(chan->macrocontext)) { 00262 ast_copy_string(chan->macrocontext, chan->context, sizeof(chan->macrocontext)); 00263 ast_copy_string(chan->macroexten, chan->exten, sizeof(chan->macroexten)); 00264 chan->macropriority = chan->priority; 00265 setmacrocontext=1; 00266 } 00267 argc = 1; 00268 /* Save old macro variables */ 00269 save_macro_exten = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_EXTEN")); 00270 pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", oldexten); 00271 00272 save_macro_context = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_CONTEXT")); 00273 pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", oldcontext); 00274 00275 save_macro_priority = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_PRIORITY")); 00276 snprintf(pc, sizeof(pc), "%d", oldpriority); 00277 pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", pc); 00278 00279 save_macro_offset = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_OFFSET")); 00280 pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", NULL); 00281 00282 /* Setup environment for new run */ 00283 chan->exten[0] = 's'; 00284 chan->exten[1] = '\0'; 00285 ast_copy_string(chan->context, fullmacro, sizeof(chan->context)); 00286 chan->priority = 1; 00287 00288 ast_channel_lock(chan); 00289 while((cur = strsep(&rest, ",")) && (argc < MAX_ARGS)) { 00290 const char *argp; 00291 /* Save copy of old arguments if we're overwriting some, otherwise 00292 let them pass through to the other macro */ 00293 snprintf(varname, sizeof(varname), "ARG%d", argc); 00294 if ((argp = pbx_builtin_getvar_helper(chan, varname))) { 00295 oldargs[argc] = ast_strdup(argp); 00296 } 00297 pbx_builtin_setvar_helper(chan, varname, cur); 00298 argc++; 00299 } 00300 ast_channel_unlock(chan); 00301 autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP); 00302 ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP); 00303 while(ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) { 00304 struct ast_context *c; 00305 struct ast_exten *e; 00306 int foundx; 00307 runningapp[0] = '\0'; 00308 runningdata[0] = '\0'; 00309 00310 /* What application will execute? */ 00311 if (ast_rdlock_contexts()) { 00312 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 00313 } else { 00314 for (c = ast_walk_contexts(NULL), e = NULL; c; c = ast_walk_contexts(c)) { 00315 if (!strcmp(ast_get_context_name(c), chan->context)) { 00316 if (ast_rdlock_context(c)) { 00317 ast_log(LOG_WARNING, "Unable to lock context?\n"); 00318 } else { 00319 e = find_matching_priority(c, chan->exten, chan->priority, chan->cid.cid_num); 00320 if (e) { /* This will only be undefined for pbx_realtime, which is majorly broken. */ 00321 ast_copy_string(runningapp, ast_get_extension_app(e), sizeof(runningapp)); 00322 ast_copy_string(runningdata, ast_get_extension_app_data(e), sizeof(runningdata)); 00323 } 00324 ast_unlock_context(c); 00325 } 00326 break; 00327 } 00328 } 00329 } 00330 ast_unlock_contexts(); 00331 00332 /* Reset the macro depth, if it was changed in the last iteration */ 00333 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); 00334 00335 if ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &foundx,1))) { 00336 /* Something bad happened, or a hangup has been requested. */ 00337 if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) || 00338 (res == '*') || (res == '#')) { 00339 /* Just return result as to the previous application as if it had been dialed */ 00340 ast_debug(1, "Oooh, got something to jump out with ('%c')!\n", res); 00341 break; 00342 } 00343 switch(res) { 00344 case MACRO_EXIT_RESULT: 00345 res = 0; 00346 goto out; 00347 default: 00348 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); 00349 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); 00350 goto out; 00351 } 00352 } 00353 00354 ast_debug(1, "Executed application: %s\n", runningapp); 00355 00356 if (!strcasecmp(runningapp, "GOSUB")) { 00357 gosub_level++; 00358 ast_debug(1, "Incrementing gosub_level\n"); 00359 } else if (!strcasecmp(runningapp, "GOSUBIF")) { 00360 char tmp2[1024], *cond, *app_arg, *app2 = tmp2; 00361 pbx_substitute_variables_helper(chan, runningdata, tmp2, sizeof(tmp2) - 1); 00362 cond = strsep(&app2, "?"); 00363 app_arg = strsep(&app2, ":"); 00364 if (pbx_checkcondition(cond)) { 00365 if (!ast_strlen_zero(app_arg)) { 00366 gosub_level++; 00367 ast_debug(1, "Incrementing gosub_level\n"); 00368 } 00369 } else { 00370 if (!ast_strlen_zero(app2)) { 00371 gosub_level++; 00372 ast_debug(1, "Incrementing gosub_level\n"); 00373 } 00374 } 00375 } else if (!strcasecmp(runningapp, "RETURN")) { 00376 gosub_level--; 00377 ast_debug(1, "Decrementing gosub_level\n"); 00378 } else if (!strcasecmp(runningapp, "STACKPOP")) { 00379 gosub_level--; 00380 ast_debug(1, "Decrementing gosub_level\n"); 00381 } else if (!strncasecmp(runningapp, "EXEC", 4)) { 00382 /* Must evaluate args to find actual app */ 00383 char tmp2[1024], *tmp3 = NULL; 00384 pbx_substitute_variables_helper(chan, runningdata, tmp2, sizeof(tmp2) - 1); 00385 if (!strcasecmp(runningapp, "EXECIF")) { 00386 tmp3 = strchr(tmp2, '|'); 00387 if (tmp3) 00388 *tmp3++ = '\0'; 00389 if (!pbx_checkcondition(tmp2)) 00390 tmp3 = NULL; 00391 } else 00392 tmp3 = tmp2; 00393 00394 if (tmp3) 00395 ast_debug(1, "Last app: %s\n", tmp3); 00396 00397 if (tmp3 && !strncasecmp(tmp3, "GOSUB", 5)) { 00398 gosub_level++; 00399 ast_debug(1, "Incrementing gosub_level\n"); 00400 } else if (tmp3 && !strncasecmp(tmp3, "RETURN", 6)) { 00401 gosub_level--; 00402 ast_debug(1, "Decrementing gosub_level\n"); 00403 } else if (tmp3 && !strncasecmp(tmp3, "STACKPOP", 8)) { 00404 gosub_level--; 00405 ast_debug(1, "Decrementing gosub_level\n"); 00406 } 00407 } 00408 00409 if (gosub_level == 0 && strcasecmp(chan->context, fullmacro)) { 00410 ast_verb(2, "Channel '%s' jumping out of macro '%s'\n", chan->name, macro); 00411 break; 00412 } 00413 00414 /* don't stop executing extensions when we're in "h" */ 00415 if (ast_check_hangup(chan) && !inhangup) { 00416 ast_debug(1, "Extension %s, macroexten %s, priority %d returned normally even though call was hung up\n", chan->exten, chan->macroexten, chan->priority); 00417 goto out; 00418 } 00419 chan->priority++; 00420 } 00421 out: 00422 00423 /* Don't let the channel change now. */ 00424 ast_channel_lock(chan); 00425 00426 /* Reset the depth back to what it was when the routine was entered (like if we called Macro recursively) */ 00427 snprintf(depthc, sizeof(depthc), "%d", depth); 00428 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); 00429 ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP); 00430 00431 for (x = 1; x < argc; x++) { 00432 /* Restore old arguments and delete ours */ 00433 snprintf(varname, sizeof(varname), "ARG%d", x); 00434 if (oldargs[x]) { 00435 pbx_builtin_setvar_helper(chan, varname, oldargs[x]); 00436 ast_free(oldargs[x]); 00437 } else { 00438 pbx_builtin_setvar_helper(chan, varname, NULL); 00439 } 00440 } 00441 00442 /* Restore macro variables */ 00443 pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten); 00444 pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context); 00445 pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority); 00446 if (save_macro_exten) 00447 ast_free(save_macro_exten); 00448 if (save_macro_context) 00449 ast_free(save_macro_context); 00450 if (save_macro_priority) 00451 ast_free(save_macro_priority); 00452 00453 if (setmacrocontext) { 00454 chan->macrocontext[0] = '\0'; 00455 chan->macroexten[0] = '\0'; 00456 chan->macropriority = 0; 00457 } 00458 00459 if (!strcasecmp(chan->context, fullmacro)) { 00460 /* If we're leaving the macro normally, restore original information */ 00461 chan->priority = oldpriority; 00462 ast_copy_string(chan->context, oldcontext, sizeof(chan->context)); 00463 if (!(ast_check_hangup(chan) & AST_SOFTHANGUP_ASYNCGOTO)) { 00464 /* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */ 00465 const char *offsets; 00466 ast_copy_string(chan->exten, oldexten, sizeof(chan->exten)); 00467 if ((offsets = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"))) { 00468 /* Handle macro offset if it's set by checking the availability of step n + offset + 1, otherwise continue 00469 normally if there is any problem */ 00470 if (sscanf(offsets, "%d", &offset) == 1) { 00471 if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + offset + 1, chan->cid.cid_num)) { 00472 chan->priority += offset; 00473 } 00474 } 00475 } 00476 } 00477 } 00478 00479 pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset); 00480 if (save_macro_offset) 00481 ast_free(save_macro_offset); 00482 00483 /* Unlock the macro */ 00484 if (exclusive) { 00485 ast_debug(1, "Unlocking macrolock for '%s'\n", fullmacro); 00486 if (ast_context_unlockmacro(fullmacro)) { 00487 ast_log(LOG_ERROR, "Failed to unlock macro '%s' - that isn't good\n", fullmacro); 00488 res = 0; 00489 } 00490 } 00491 ast_channel_unlock(chan); 00492 00493 return res; 00494 }
static struct ast_exten* find_matching_priority | ( | struct ast_context * | c, | |
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) | [static] |
Definition at line 121 of file app_macro.c.
References ast_extension_match(), ast_get_context_name(), ast_get_extension_cidmatch(), ast_get_extension_matchcid(), ast_get_extension_name(), ast_get_extension_priority(), ast_get_include_name(), ast_walk_context_extensions(), ast_walk_context_includes(), ast_walk_contexts(), and ast_walk_extension_priorities().
Referenced by _macro_exec(), find_matching_endwhile(), and find_matching_priority().
00122 { 00123 struct ast_exten *e; 00124 struct ast_include *i; 00125 struct ast_context *c2; 00126 00127 for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) { 00128 if (ast_extension_match(ast_get_extension_name(e), exten)) { 00129 int needmatch = ast_get_extension_matchcid(e); 00130 if ((needmatch && ast_extension_match(ast_get_extension_cidmatch(e), callerid)) || 00131 (!needmatch)) { 00132 /* This is the matching extension we want */ 00133 struct ast_exten *p; 00134 for (p=ast_walk_extension_priorities(e, NULL); p; p=ast_walk_extension_priorities(e, p)) { 00135 if (priority != ast_get_extension_priority(p)) 00136 continue; 00137 return p; 00138 } 00139 } 00140 } 00141 } 00142 00143 /* No match; run through includes */ 00144 for (i=ast_walk_context_includes(c, NULL); i; i=ast_walk_context_includes(c, i)) { 00145 for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) { 00146 if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) { 00147 e = find_matching_priority(c2, exten, priority, callerid); 00148 if (e) 00149 return e; 00150 } 00151 } 00152 } 00153 return NULL; 00154 }
static int load_module | ( | void | ) | [static] |
Definition at line 548 of file app_macro.c.
References ast_register_application, macro_exec(), macro_exit_exec(), macroexclusive_exec(), and macroif_exec().
00549 { 00550 int res; 00551 00552 res = ast_register_application(exit_app, macro_exit_exec, exit_synopsis, exit_descrip); 00553 res |= ast_register_application(if_app, macroif_exec, if_synopsis, if_descrip); 00554 res |= ast_register_application(exclusive_app, macroexclusive_exec, exclusive_synopsis, exclusive_descrip); 00555 res |= ast_register_application(app, macro_exec, synopsis, descrip); 00556 00557 return res; 00558 }
static int macro_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 496 of file app_macro.c.
References _macro_exec(), and chan.
Referenced by load_module(), and macroif_exec().
00497 { 00498 return _macro_exec(chan, data, 0); 00499 }
static int macro_exit_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 531 of file app_macro.c.
References MACRO_EXIT_RESULT.
Referenced by load_module().
00532 { 00533 return MACRO_EXIT_RESULT; 00534 }
static void macro_fixup | ( | void * | data, | |
struct ast_channel * | old_chan, | |||
struct ast_channel * | new_chan | |||
) | [static] |
Definition at line 103 of file app_macro.c.
References pbx_builtin_getvar_helper(), and pbx_builtin_setvar_helper().
00104 { 00105 int i; 00106 char varname[10]; 00107 pbx_builtin_setvar_helper(new_chan, "MACRO_DEPTH", "0"); 00108 pbx_builtin_setvar_helper(new_chan, "MACRO_CONTEXT", NULL); 00109 pbx_builtin_setvar_helper(new_chan, "MACRO_EXTEN", NULL); 00110 pbx_builtin_setvar_helper(new_chan, "MACRO_PRIORITY", NULL); 00111 pbx_builtin_setvar_helper(new_chan, "MACRO_OFFSET", NULL); 00112 for (i = 1; i < 100; i++) { 00113 snprintf(varname, sizeof(varname), "ARG%d", i); 00114 while (pbx_builtin_getvar_helper(new_chan, varname)) { 00115 /* Kill all levels of arguments */ 00116 pbx_builtin_setvar_helper(new_chan, varname, NULL); 00117 } 00118 } 00119 }
static int macroexclusive_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 501 of file app_macro.c.
References _macro_exec(), and chan.
Referenced by load_module().
00502 { 00503 return _macro_exec(chan, data, 1); 00504 }
static int macroif_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 506 of file app_macro.c.
References ast_log(), ast_strdupa, chan, LOG_WARNING, macro_exec(), and pbx_checkcondition().
Referenced by load_module().
00507 { 00508 char *expr = NULL, *label_a = NULL, *label_b = NULL; 00509 int res = 0; 00510 00511 if (!(expr = ast_strdupa(data))) 00512 return -1; 00513 00514 if ((label_a = strchr(expr, '?'))) { 00515 *label_a = '\0'; 00516 label_a++; 00517 if ((label_b = strchr(label_a, ':'))) { 00518 *label_b = '\0'; 00519 label_b++; 00520 } 00521 if (pbx_checkcondition(expr)) 00522 res = macro_exec(chan, label_a); 00523 else if (label_b) 00524 res = macro_exec(chan, label_b); 00525 } else 00526 ast_log(LOG_WARNING, "Invalid Syntax.\n"); 00527 00528 return res; 00529 }
static int unload_module | ( | void | ) | [static] |
Definition at line 536 of file app_macro.c.
References ast_unregister_application().
00537 { 00538 int res; 00539 00540 res = ast_unregister_application(if_app); 00541 res |= ast_unregister_application(exit_app); 00542 res |= ast_unregister_application(app); 00543 res |= ast_unregister_application(exclusive_app); 00544 00545 return res; 00546 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Extension Macros" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 560 of file app_macro.c.
char* app = "Macro" [static] |
Definition at line 86 of file app_macro.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 560 of file app_macro.c.
char* descrip [static] |
Definition at line 45 of file app_macro.c.
char* exclusive_app = "MacroExclusive" [static] |
Definition at line 88 of file app_macro.c.
char* exclusive_descrip [static] |
Definition at line 72 of file app_macro.c.
char* exclusive_synopsis = "Exclusive Macro Implementation" [static] |
Definition at line 93 of file app_macro.c.
char* exit_app = "MacroExit" [static] |
Definition at line 89 of file app_macro.c.
char* exit_descrip [static] |
Definition at line 79 of file app_macro.c.
char* exit_synopsis = "Exit From Macro" [static] |
Definition at line 94 of file app_macro.c.
char* if_app = "MacroIf" [static] |
Definition at line 87 of file app_macro.c.
char* if_descrip [static] |
Initial value:
" MacroIf(<expr>?macroname_a[,arg1][:macroname_b[,arg1]])\n" "Executes macro defined in <macroname_a> if <expr> is true\n" "(otherwise <macroname_b> if provided)\n" "Arguments and return values as in application Macro()\n"
Definition at line 66 of file app_macro.c.
char* if_synopsis = "Conditional Macro Implementation" [static] |
Definition at line 92 of file app_macro.c.
struct ast_datastore_info macro_ds_info |
Initial value:
{ .type = "MACRO", .chan_fixup = macro_fixup, }
Definition at line 98 of file app_macro.c.
Referenced by _macro_exec().
char* synopsis = "Macro Implementation" [static] |
Definition at line 91 of file app_macro.c.