#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"
#include "asterisk/app.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, const char *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, const char *data) |
static int | macro_exit_exec (struct ast_channel *chan, const char *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, const char *data) |
static int | macroif_exec (struct ast_channel *chan, const char *data) |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } |
static char * | app = "Macro" |
static struct ast_module_info * | ast_module_info = &__mod_info |
static char * | exclusive_app = "MacroExclusive" |
static char * | exit_app = "MacroExit" |
static char * | if_app = "MacroIf" |
static struct ast_datastore_info | macro_ds_info |
Definition in file app_macro.c.
#define MACRO_EXIT_RESULT 1024 |
#define MAX_ARGS 80 |
Definition at line 150 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 643 of file app_macro.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 643 of file app_macro.c.
static int _macro_exec | ( | struct ast_channel * | chan, | |
const char * | data, | |||
int | exclusive | |||
) | [static] |
Definition at line 220 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_spawn_extension(), ast_str_buffer(), ast_str_create(), ast_str_substitute_variables(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_unlock_context(), ast_unlock_contexts(), ast_verb, ast_walk_contexts(), ast_channel::caller, cond, ast_channel::context, DATASTORE_INHERIT_FOREVER, ast_channel::exten, find_matching_priority(), ast_party_caller::id, 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, ast_party_id::number, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_checkcondition(), ast_channel::priority, S_COR, ast_party_number::str, strsep(), and ast_party_number::valid.
Referenced by macro_exec(), and macroexclusive_exec().
00221 { 00222 const char *s; 00223 char *tmp; 00224 char *cur, *rest; 00225 char *macro; 00226 char fullmacro[80]; 00227 char varname[80]; 00228 char runningapp[80], runningdata[1024]; 00229 char *oldargs[MAX_ARGS + 1] = { NULL, }; 00230 int argc, x; 00231 int res=0; 00232 char oldexten[256]=""; 00233 int oldpriority, gosub_level = 0; 00234 char pc[80], depthc[12]; 00235 char oldcontext[AST_MAX_CONTEXT] = ""; 00236 const char *inhangupc; 00237 int offset, depth = 0, maxdepth = 7; 00238 int setmacrocontext=0; 00239 int autoloopflag, inhangup = 0; 00240 struct ast_str *tmp_subst = NULL; 00241 00242 char *save_macro_exten; 00243 char *save_macro_context; 00244 char *save_macro_priority; 00245 char *save_macro_offset; 00246 struct ast_datastore *macro_store = ast_channel_datastore_find(chan, ¯o_ds_info, NULL); 00247 00248 if (ast_strlen_zero(data)) { 00249 ast_log(LOG_WARNING, "Macro() requires arguments. See \"core show application macro\" for help.\n"); 00250 return -1; 00251 } 00252 00253 do { 00254 if (macro_store) { 00255 break; 00256 } 00257 if (!(macro_store = ast_datastore_alloc(¯o_ds_info, NULL))) { 00258 ast_log(LOG_WARNING, "Unable to allocate new datastore.\n"); 00259 break; 00260 } 00261 /* Just the existence of this datastore is enough. */ 00262 macro_store->inheritance = DATASTORE_INHERIT_FOREVER; 00263 ast_channel_datastore_add(chan, macro_store); 00264 } while (0); 00265 00266 /* does the user want a deeper rabbit hole? */ 00267 ast_channel_lock(chan); 00268 if ((s = pbx_builtin_getvar_helper(chan, "MACRO_RECURSION"))) { 00269 sscanf(s, "%30d", &maxdepth); 00270 } 00271 00272 /* Count how many levels deep the rabbit hole goes */ 00273 if ((s = pbx_builtin_getvar_helper(chan, "MACRO_DEPTH"))) { 00274 sscanf(s, "%30d", &depth); 00275 } 00276 00277 /* Used for detecting whether to return when a Macro is called from another Macro after hangup */ 00278 if (strcmp(chan->exten, "h") == 0) 00279 pbx_builtin_setvar_helper(chan, "MACRO_IN_HANGUP", "1"); 00280 00281 if ((inhangupc = pbx_builtin_getvar_helper(chan, "MACRO_IN_HANGUP"))) { 00282 sscanf(inhangupc, "%30d", &inhangup); 00283 } 00284 ast_channel_unlock(chan); 00285 00286 if (depth >= maxdepth) { 00287 ast_log(LOG_ERROR, "Macro(): possible infinite loop detected. Returning early.\n"); 00288 return 0; 00289 } 00290 snprintf(depthc, sizeof(depthc), "%d", depth + 1); 00291 00292 tmp = ast_strdupa(data); 00293 rest = tmp; 00294 macro = strsep(&rest, ","); 00295 if (ast_strlen_zero(macro)) { 00296 ast_log(LOG_WARNING, "Invalid macro name specified\n"); 00297 return 0; 00298 } 00299 00300 snprintf(fullmacro, sizeof(fullmacro), "macro-%s", macro); 00301 if (!ast_exists_extension(chan, fullmacro, "s", 1, 00302 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 00303 if (!ast_context_find(fullmacro)) 00304 ast_log(LOG_WARNING, "No such context '%s' for macro '%s'\n", fullmacro, macro); 00305 else 00306 ast_log(LOG_WARNING, "Context '%s' for macro '%s' lacks 's' extension, priority 1\n", fullmacro, macro); 00307 return 0; 00308 } 00309 00310 /* If we are to run the macro exclusively, take the mutex */ 00311 if (exclusive) { 00312 ast_debug(1, "Locking macrolock for '%s'\n", fullmacro); 00313 ast_autoservice_start(chan); 00314 if (ast_context_lockmacro(fullmacro)) { 00315 ast_log(LOG_WARNING, "Failed to lock macro '%s' as in-use\n", fullmacro); 00316 ast_autoservice_stop(chan); 00317 return 0; 00318 } 00319 ast_autoservice_stop(chan); 00320 } 00321 00322 if (!(tmp_subst = ast_str_create(16))) { 00323 return -1; 00324 } 00325 00326 /* Save old info */ 00327 oldpriority = chan->priority; 00328 ast_copy_string(oldexten, chan->exten, sizeof(oldexten)); 00329 ast_copy_string(oldcontext, chan->context, sizeof(oldcontext)); 00330 if (ast_strlen_zero(chan->macrocontext)) { 00331 ast_copy_string(chan->macrocontext, chan->context, sizeof(chan->macrocontext)); 00332 ast_copy_string(chan->macroexten, chan->exten, sizeof(chan->macroexten)); 00333 chan->macropriority = chan->priority; 00334 setmacrocontext=1; 00335 } 00336 argc = 1; 00337 /* Save old macro variables */ 00338 save_macro_exten = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_EXTEN")); 00339 pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", oldexten); 00340 00341 save_macro_context = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_CONTEXT")); 00342 pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", oldcontext); 00343 00344 save_macro_priority = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_PRIORITY")); 00345 snprintf(pc, sizeof(pc), "%d", oldpriority); 00346 pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", pc); 00347 00348 save_macro_offset = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_OFFSET")); 00349 pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", NULL); 00350 00351 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); 00352 00353 /* Setup environment for new run */ 00354 chan->exten[0] = 's'; 00355 chan->exten[1] = '\0'; 00356 ast_copy_string(chan->context, fullmacro, sizeof(chan->context)); 00357 chan->priority = 1; 00358 00359 ast_channel_lock(chan); 00360 while((cur = strsep(&rest, ",")) && (argc < MAX_ARGS)) { 00361 const char *argp; 00362 /* Save copy of old arguments if we're overwriting some, otherwise 00363 let them pass through to the other macro */ 00364 snprintf(varname, sizeof(varname), "ARG%d", argc); 00365 if ((argp = pbx_builtin_getvar_helper(chan, varname))) { 00366 oldargs[argc] = ast_strdup(argp); 00367 } 00368 pbx_builtin_setvar_helper(chan, varname, cur); 00369 argc++; 00370 } 00371 ast_channel_unlock(chan); 00372 autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP); 00373 ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP); 00374 while (ast_exists_extension(chan, chan->context, chan->exten, chan->priority, 00375 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 00376 struct ast_context *c; 00377 struct ast_exten *e; 00378 int foundx; 00379 runningapp[0] = '\0'; 00380 runningdata[0] = '\0'; 00381 00382 /* What application will execute? */ 00383 if (ast_rdlock_contexts()) { 00384 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 00385 } else { 00386 for (c = ast_walk_contexts(NULL), e = NULL; c; c = ast_walk_contexts(c)) { 00387 if (!strcmp(ast_get_context_name(c), chan->context)) { 00388 if (ast_rdlock_context(c)) { 00389 ast_log(LOG_WARNING, "Unable to lock context?\n"); 00390 } else { 00391 e = find_matching_priority(c, chan->exten, chan->priority, 00392 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)); 00393 if (e) { /* This will only be undefined for pbx_realtime, which is majorly broken. */ 00394 ast_copy_string(runningapp, ast_get_extension_app(e), sizeof(runningapp)); 00395 ast_copy_string(runningdata, ast_get_extension_app_data(e), sizeof(runningdata)); 00396 } 00397 ast_unlock_context(c); 00398 } 00399 break; 00400 } 00401 } 00402 } 00403 ast_unlock_contexts(); 00404 00405 /* Reset the macro depth, if it was changed in the last iteration */ 00406 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); 00407 00408 res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, 00409 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 00410 &foundx, 1); 00411 if (res) { 00412 /* Something bad happened, or a hangup has been requested. */ 00413 if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) || 00414 (res == '*') || (res == '#')) { 00415 /* Just return result as to the previous application as if it had been dialed */ 00416 ast_debug(1, "Oooh, got something to jump out with ('%c')!\n", res); 00417 break; 00418 } 00419 switch(res) { 00420 case MACRO_EXIT_RESULT: 00421 res = 0; 00422 goto out; 00423 default: 00424 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); 00425 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); 00426 goto out; 00427 } 00428 } 00429 00430 ast_debug(1, "Executed application: %s\n", runningapp); 00431 00432 if (!strcasecmp(runningapp, "GOSUB")) { 00433 gosub_level++; 00434 ast_debug(1, "Incrementing gosub_level\n"); 00435 } else if (!strcasecmp(runningapp, "GOSUBIF")) { 00436 char *cond, *app_arg; 00437 char *app2; 00438 ast_str_substitute_variables(&tmp_subst, 0, chan, runningdata); 00439 app2 = ast_str_buffer(tmp_subst); 00440 cond = strsep(&app2, "?"); 00441 app_arg = strsep(&app2, ":"); 00442 if (pbx_checkcondition(cond)) { 00443 if (!ast_strlen_zero(app_arg)) { 00444 gosub_level++; 00445 ast_debug(1, "Incrementing gosub_level\n"); 00446 } 00447 } else { 00448 if (!ast_strlen_zero(app2)) { 00449 gosub_level++; 00450 ast_debug(1, "Incrementing gosub_level\n"); 00451 } 00452 } 00453 } else if (!strcasecmp(runningapp, "RETURN")) { 00454 gosub_level--; 00455 ast_debug(1, "Decrementing gosub_level\n"); 00456 } else if (!strcasecmp(runningapp, "STACKPOP")) { 00457 gosub_level--; 00458 ast_debug(1, "Decrementing gosub_level\n"); 00459 } else if (!strncasecmp(runningapp, "EXEC", 4)) { 00460 /* Must evaluate args to find actual app */ 00461 char *tmp2, *tmp3 = NULL; 00462 ast_str_substitute_variables(&tmp_subst, 0, chan, runningdata); 00463 tmp2 = ast_str_buffer(tmp_subst); 00464 if (!strcasecmp(runningapp, "EXECIF")) { 00465 if ((tmp3 = strchr(tmp2, '|'))) { 00466 *tmp3++ = '\0'; 00467 } 00468 if (!pbx_checkcondition(tmp2)) { 00469 tmp3 = NULL; 00470 } 00471 } else { 00472 tmp3 = tmp2; 00473 } 00474 00475 if (tmp3) { 00476 ast_debug(1, "Last app: %s\n", tmp3); 00477 } 00478 00479 if (tmp3 && !strncasecmp(tmp3, "GOSUB", 5)) { 00480 gosub_level++; 00481 ast_debug(1, "Incrementing gosub_level\n"); 00482 } else if (tmp3 && !strncasecmp(tmp3, "RETURN", 6)) { 00483 gosub_level--; 00484 ast_debug(1, "Decrementing gosub_level\n"); 00485 } else if (tmp3 && !strncasecmp(tmp3, "STACKPOP", 8)) { 00486 gosub_level--; 00487 ast_debug(1, "Decrementing gosub_level\n"); 00488 } 00489 } 00490 00491 if (gosub_level == 0 && strcasecmp(chan->context, fullmacro)) { 00492 ast_verb(2, "Channel '%s' jumping out of macro '%s'\n", chan->name, macro); 00493 break; 00494 } 00495 00496 /* don't stop executing extensions when we're in "h" */ 00497 if (ast_check_hangup(chan) && !inhangup) { 00498 ast_debug(1, "Extension %s, macroexten %s, priority %d returned normally even though call was hung up\n", chan->exten, chan->macroexten, chan->priority); 00499 goto out; 00500 } 00501 chan->priority++; 00502 } 00503 out: 00504 00505 /* Don't let the channel change now. */ 00506 ast_channel_lock(chan); 00507 00508 /* Reset the depth back to what it was when the routine was entered (like if we called Macro recursively) */ 00509 snprintf(depthc, sizeof(depthc), "%d", depth); 00510 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); 00511 ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP); 00512 00513 for (x = 1; x < argc; x++) { 00514 /* Restore old arguments and delete ours */ 00515 snprintf(varname, sizeof(varname), "ARG%d", x); 00516 if (oldargs[x]) { 00517 pbx_builtin_setvar_helper(chan, varname, oldargs[x]); 00518 ast_free(oldargs[x]); 00519 } else { 00520 pbx_builtin_setvar_helper(chan, varname, NULL); 00521 } 00522 } 00523 00524 /* Restore macro variables */ 00525 pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten); 00526 pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context); 00527 pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority); 00528 if (save_macro_exten) 00529 ast_free(save_macro_exten); 00530 if (save_macro_context) 00531 ast_free(save_macro_context); 00532 if (save_macro_priority) 00533 ast_free(save_macro_priority); 00534 00535 if (setmacrocontext) { 00536 chan->macrocontext[0] = '\0'; 00537 chan->macroexten[0] = '\0'; 00538 chan->macropriority = 0; 00539 } 00540 00541 if (!strcasecmp(chan->context, fullmacro)) { 00542 const char *offsets; 00543 00544 /* If we're leaving the macro normally, restore original information */ 00545 chan->priority = oldpriority; 00546 ast_copy_string(chan->context, oldcontext, sizeof(chan->context)); 00547 ast_copy_string(chan->exten, oldexten, sizeof(chan->exten)); 00548 if ((offsets = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"))) { 00549 /* Handle macro offset if it's set by checking the availability of step n + offset + 1, otherwise continue 00550 normally if there is any problem */ 00551 if (sscanf(offsets, "%30d", &offset) == 1) { 00552 if (ast_exists_extension(chan, chan->context, chan->exten, 00553 chan->priority + offset + 1, 00554 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 00555 chan->priority += offset; 00556 } 00557 } 00558 } 00559 } 00560 00561 pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset); 00562 if (save_macro_offset) 00563 ast_free(save_macro_offset); 00564 00565 /* Unlock the macro */ 00566 if (exclusive) { 00567 ast_debug(1, "Unlocking macrolock for '%s'\n", fullmacro); 00568 if (ast_context_unlockmacro(fullmacro)) { 00569 ast_log(LOG_ERROR, "Failed to unlock macro '%s' - that isn't good\n", fullmacro); 00570 res = 0; 00571 } 00572 } 00573 ast_channel_unlock(chan); 00574 ast_free(tmp_subst); 00575 00576 return res; 00577 }
static struct ast_exten* find_matching_priority | ( | struct ast_context * | c, | |
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) | [static] |
Definition at line 185 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().
00186 { 00187 struct ast_exten *e; 00188 struct ast_include *i; 00189 struct ast_context *c2; 00190 00191 for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) { 00192 if (ast_extension_match(ast_get_extension_name(e), exten)) { 00193 int needmatch = ast_get_extension_matchcid(e); 00194 if ((needmatch && ast_extension_match(ast_get_extension_cidmatch(e), callerid)) || 00195 (!needmatch)) { 00196 /* This is the matching extension we want */ 00197 struct ast_exten *p; 00198 for (p=ast_walk_extension_priorities(e, NULL); p; p=ast_walk_extension_priorities(e, p)) { 00199 if (priority != ast_get_extension_priority(p)) 00200 continue; 00201 return p; 00202 } 00203 } 00204 } 00205 } 00206 00207 /* No match; run through includes */ 00208 for (i=ast_walk_context_includes(c, NULL); i; i=ast_walk_context_includes(c, i)) { 00209 for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) { 00210 if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) { 00211 e = find_matching_priority(c2, exten, priority, callerid); 00212 if (e) 00213 return e; 00214 } 00215 } 00216 } 00217 return NULL; 00218 }
static int load_module | ( | void | ) | [static] |
Definition at line 631 of file app_macro.c.
References ast_register_application_xml, macro_exec(), macro_exit_exec(), macroexclusive_exec(), and macroif_exec().
00632 { 00633 int res; 00634 00635 res = ast_register_application_xml(exit_app, macro_exit_exec); 00636 res |= ast_register_application_xml(if_app, macroif_exec); 00637 res |= ast_register_application_xml(exclusive_app, macroexclusive_exec); 00638 res |= ast_register_application_xml(app, macro_exec); 00639 00640 return res; 00641 }
static int macro_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 579 of file app_macro.c.
References _macro_exec().
Referenced by load_module(), and macroif_exec().
00580 { 00581 return _macro_exec(chan, data, 0); 00582 }
static int macro_exit_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 614 of file app_macro.c.
References MACRO_EXIT_RESULT.
Referenced by load_module().
00615 { 00616 return MACRO_EXIT_RESULT; 00617 }
static void macro_fixup | ( | void * | data, | |
struct ast_channel * | old_chan, | |||
struct ast_channel * | new_chan | |||
) | [static] |
Definition at line 167 of file app_macro.c.
References pbx_builtin_getvar_helper(), and pbx_builtin_setvar_helper().
00168 { 00169 int i; 00170 char varname[10]; 00171 pbx_builtin_setvar_helper(new_chan, "MACRO_DEPTH", "0"); 00172 pbx_builtin_setvar_helper(new_chan, "MACRO_CONTEXT", NULL); 00173 pbx_builtin_setvar_helper(new_chan, "MACRO_EXTEN", NULL); 00174 pbx_builtin_setvar_helper(new_chan, "MACRO_PRIORITY", NULL); 00175 pbx_builtin_setvar_helper(new_chan, "MACRO_OFFSET", NULL); 00176 for (i = 1; i < 100; i++) { 00177 snprintf(varname, sizeof(varname), "ARG%d", i); 00178 while (pbx_builtin_getvar_helper(new_chan, varname)) { 00179 /* Kill all levels of arguments */ 00180 pbx_builtin_setvar_helper(new_chan, varname, NULL); 00181 } 00182 } 00183 }
static int macroexclusive_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 584 of file app_macro.c.
References _macro_exec().
Referenced by load_module().
00585 { 00586 return _macro_exec(chan, data, 1); 00587 }
static int macroif_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 589 of file app_macro.c.
References ast_log(), ast_strdupa, LOG_WARNING, macro_exec(), and pbx_checkcondition().
Referenced by load_module().
00590 { 00591 char *expr = NULL, *label_a = NULL, *label_b = NULL; 00592 int res = 0; 00593 00594 if (!(expr = ast_strdupa(data))) 00595 return -1; 00596 00597 if ((label_a = strchr(expr, '?'))) { 00598 *label_a = '\0'; 00599 label_a++; 00600 if ((label_b = strchr(label_a, ':'))) { 00601 *label_b = '\0'; 00602 label_b++; 00603 } 00604 if (pbx_checkcondition(expr)) 00605 res = macro_exec(chan, label_a); 00606 else if (label_b) 00607 res = macro_exec(chan, label_b); 00608 } else 00609 ast_log(LOG_WARNING, "Invalid Syntax.\n"); 00610 00611 return res; 00612 }
static int unload_module | ( | void | ) | [static] |
Definition at line 619 of file app_macro.c.
References ast_unregister_application().
00620 { 00621 int res; 00622 00623 res = ast_unregister_application(if_app); 00624 res |= ast_unregister_application(exit_app); 00625 res |= ast_unregister_application(app); 00626 res |= ast_unregister_application(exclusive_app); 00627 00628 return res; 00629 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static] |
Definition at line 643 of file app_macro.c.
char* app = "Macro" [static] |
Definition at line 155 of file app_macro.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 643 of file app_macro.c.
char* exclusive_app = "MacroExclusive" [static] |
Definition at line 157 of file app_macro.c.
char* exit_app = "MacroExit" [static] |
Definition at line 158 of file app_macro.c.
char* if_app = "MacroIf" [static] |
Definition at line 156 of file app_macro.c.
struct ast_datastore_info macro_ds_info [static] |
Initial value:
{ .type = "MACRO", .chan_fixup = macro_fixup, }
Definition at line 162 of file app_macro.c.
Referenced by _macro_exec().