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