#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_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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } |
| 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 637 of file app_macro.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 637 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_SOFTHANGUP_ASYNCGOTO, 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::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_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(), ast_channel::priority, s, and strsep().
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, chan->cid.cid_num)) { 00302 if (!ast_context_find(fullmacro)) 00303 ast_log(LOG_WARNING, "No such context '%s' for macro '%s'\n", fullmacro, macro); 00304 else 00305 ast_log(LOG_WARNING, "Context '%s' for macro '%s' lacks 's' extension, priority 1\n", fullmacro, macro); 00306 return 0; 00307 } 00308 00309 /* If we are to run the macro exclusively, take the mutex */ 00310 if (exclusive) { 00311 ast_debug(1, "Locking macrolock for '%s'\n", fullmacro); 00312 ast_autoservice_start(chan); 00313 if (ast_context_lockmacro(fullmacro)) { 00314 ast_log(LOG_WARNING, "Failed to lock macro '%s' as in-use\n", fullmacro); 00315 ast_autoservice_stop(chan); 00316 return 0; 00317 } 00318 ast_autoservice_stop(chan); 00319 } 00320 00321 if (!(tmp_subst = ast_str_create(16))) { 00322 return -1; 00323 } 00324 00325 /* Save old info */ 00326 oldpriority = chan->priority; 00327 ast_copy_string(oldexten, chan->exten, sizeof(oldexten)); 00328 ast_copy_string(oldcontext, chan->context, sizeof(oldcontext)); 00329 if (ast_strlen_zero(chan->macrocontext)) { 00330 ast_copy_string(chan->macrocontext, chan->context, sizeof(chan->macrocontext)); 00331 ast_copy_string(chan->macroexten, chan->exten, sizeof(chan->macroexten)); 00332 chan->macropriority = chan->priority; 00333 setmacrocontext=1; 00334 } 00335 argc = 1; 00336 /* Save old macro variables */ 00337 save_macro_exten = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_EXTEN")); 00338 pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", oldexten); 00339 00340 save_macro_context = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_CONTEXT")); 00341 pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", oldcontext); 00342 00343 save_macro_priority = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_PRIORITY")); 00344 snprintf(pc, sizeof(pc), "%d", oldpriority); 00345 pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", pc); 00346 00347 save_macro_offset = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_OFFSET")); 00348 pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", NULL); 00349 00350 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); 00351 00352 /* Setup environment for new run */ 00353 chan->exten[0] = 's'; 00354 chan->exten[1] = '\0'; 00355 ast_copy_string(chan->context, fullmacro, sizeof(chan->context)); 00356 chan->priority = 1; 00357 00358 ast_channel_lock(chan); 00359 while((cur = strsep(&rest, ",")) && (argc < MAX_ARGS)) { 00360 const char *argp; 00361 /* Save copy of old arguments if we're overwriting some, otherwise 00362 let them pass through to the other macro */ 00363 snprintf(varname, sizeof(varname), "ARG%d", argc); 00364 if ((argp = pbx_builtin_getvar_helper(chan, varname))) { 00365 oldargs[argc] = ast_strdup(argp); 00366 } 00367 pbx_builtin_setvar_helper(chan, varname, cur); 00368 argc++; 00369 } 00370 ast_channel_unlock(chan); 00371 autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP); 00372 ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP); 00373 while(ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) { 00374 struct ast_context *c; 00375 struct ast_exten *e; 00376 int foundx; 00377 runningapp[0] = '\0'; 00378 runningdata[0] = '\0'; 00379 00380 /* What application will execute? */ 00381 if (ast_rdlock_contexts()) { 00382 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 00383 } else { 00384 for (c = ast_walk_contexts(NULL), e = NULL; c; c = ast_walk_contexts(c)) { 00385 if (!strcmp(ast_get_context_name(c), chan->context)) { 00386 if (ast_rdlock_context(c)) { 00387 ast_log(LOG_WARNING, "Unable to lock context?\n"); 00388 } else { 00389 e = find_matching_priority(c, chan->exten, chan->priority, chan->cid.cid_num); 00390 if (e) { /* This will only be undefined for pbx_realtime, which is majorly broken. */ 00391 ast_copy_string(runningapp, ast_get_extension_app(e), sizeof(runningapp)); 00392 ast_copy_string(runningdata, ast_get_extension_app_data(e), sizeof(runningdata)); 00393 } 00394 ast_unlock_context(c); 00395 } 00396 break; 00397 } 00398 } 00399 } 00400 ast_unlock_contexts(); 00401 00402 /* Reset the macro depth, if it was changed in the last iteration */ 00403 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); 00404 00405 if ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &foundx,1))) { 00406 /* Something bad happened, or a hangup has been requested. */ 00407 if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) || 00408 (res == '*') || (res == '#')) { 00409 /* Just return result as to the previous application as if it had been dialed */ 00410 ast_debug(1, "Oooh, got something to jump out with ('%c')!\n", res); 00411 break; 00412 } 00413 switch(res) { 00414 case MACRO_EXIT_RESULT: 00415 res = 0; 00416 goto out; 00417 default: 00418 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); 00419 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); 00420 goto out; 00421 } 00422 } 00423 00424 ast_debug(1, "Executed application: %s\n", runningapp); 00425 00426 if (!strcasecmp(runningapp, "GOSUB")) { 00427 gosub_level++; 00428 ast_debug(1, "Incrementing gosub_level\n"); 00429 } else if (!strcasecmp(runningapp, "GOSUBIF")) { 00430 char *cond, *app_arg; 00431 char *app2; 00432 ast_str_substitute_variables(&tmp_subst, 0, chan, runningdata); 00433 app2 = ast_str_buffer(tmp_subst); 00434 cond = strsep(&app2, "?"); 00435 app_arg = strsep(&app2, ":"); 00436 if (pbx_checkcondition(cond)) { 00437 if (!ast_strlen_zero(app_arg)) { 00438 gosub_level++; 00439 ast_debug(1, "Incrementing gosub_level\n"); 00440 } 00441 } else { 00442 if (!ast_strlen_zero(app2)) { 00443 gosub_level++; 00444 ast_debug(1, "Incrementing gosub_level\n"); 00445 } 00446 } 00447 } else if (!strcasecmp(runningapp, "RETURN")) { 00448 gosub_level--; 00449 ast_debug(1, "Decrementing gosub_level\n"); 00450 } else if (!strcasecmp(runningapp, "STACKPOP")) { 00451 gosub_level--; 00452 ast_debug(1, "Decrementing gosub_level\n"); 00453 } else if (!strncasecmp(runningapp, "EXEC", 4)) { 00454 /* Must evaluate args to find actual app */ 00455 char *tmp2, *tmp3 = NULL; 00456 ast_str_substitute_variables(&tmp_subst, 0, chan, runningdata); 00457 tmp2 = ast_str_buffer(tmp_subst); 00458 if (!strcasecmp(runningapp, "EXECIF")) { 00459 if ((tmp3 = strchr(tmp2, '|'))) { 00460 *tmp3++ = '\0'; 00461 } 00462 if (!pbx_checkcondition(tmp2)) { 00463 tmp3 = NULL; 00464 } 00465 } else { 00466 tmp3 = tmp2; 00467 } 00468 00469 if (tmp3) { 00470 ast_debug(1, "Last app: %s\n", tmp3); 00471 } 00472 00473 if (tmp3 && !strncasecmp(tmp3, "GOSUB", 5)) { 00474 gosub_level++; 00475 ast_debug(1, "Incrementing gosub_level\n"); 00476 } else if (tmp3 && !strncasecmp(tmp3, "RETURN", 6)) { 00477 gosub_level--; 00478 ast_debug(1, "Decrementing gosub_level\n"); 00479 } else if (tmp3 && !strncasecmp(tmp3, "STACKPOP", 8)) { 00480 gosub_level--; 00481 ast_debug(1, "Decrementing gosub_level\n"); 00482 } 00483 } 00484 00485 if (gosub_level == 0 && strcasecmp(chan->context, fullmacro)) { 00486 ast_verb(2, "Channel '%s' jumping out of macro '%s'\n", chan->name, macro); 00487 break; 00488 } 00489 00490 /* don't stop executing extensions when we're in "h" */ 00491 if (ast_check_hangup(chan) && !inhangup) { 00492 ast_debug(1, "Extension %s, macroexten %s, priority %d returned normally even though call was hung up\n", chan->exten, chan->macroexten, chan->priority); 00493 goto out; 00494 } 00495 chan->priority++; 00496 } 00497 out: 00498 00499 /* Don't let the channel change now. */ 00500 ast_channel_lock(chan); 00501 00502 /* Reset the depth back to what it was when the routine was entered (like if we called Macro recursively) */ 00503 snprintf(depthc, sizeof(depthc), "%d", depth); 00504 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); 00505 ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP); 00506 00507 for (x = 1; x < argc; x++) { 00508 /* Restore old arguments and delete ours */ 00509 snprintf(varname, sizeof(varname), "ARG%d", x); 00510 if (oldargs[x]) { 00511 pbx_builtin_setvar_helper(chan, varname, oldargs[x]); 00512 ast_free(oldargs[x]); 00513 } else { 00514 pbx_builtin_setvar_helper(chan, varname, NULL); 00515 } 00516 } 00517 00518 /* Restore macro variables */ 00519 pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten); 00520 pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context); 00521 pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority); 00522 if (save_macro_exten) 00523 ast_free(save_macro_exten); 00524 if (save_macro_context) 00525 ast_free(save_macro_context); 00526 if (save_macro_priority) 00527 ast_free(save_macro_priority); 00528 00529 if (setmacrocontext) { 00530 chan->macrocontext[0] = '\0'; 00531 chan->macroexten[0] = '\0'; 00532 chan->macropriority = 0; 00533 } 00534 00535 if (!strcasecmp(chan->context, fullmacro)) { 00536 /* If we're leaving the macro normally, restore original information */ 00537 chan->priority = oldpriority; 00538 ast_copy_string(chan->context, oldcontext, sizeof(chan->context)); 00539 if (!(ast_check_hangup(chan) & AST_SOFTHANGUP_ASYNCGOTO)) { 00540 /* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */ 00541 const char *offsets; 00542 ast_copy_string(chan->exten, oldexten, sizeof(chan->exten)); 00543 if ((offsets = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"))) { 00544 /* Handle macro offset if it's set by checking the availability of step n + offset + 1, otherwise continue 00545 normally if there is any problem */ 00546 if (sscanf(offsets, "%30d", &offset) == 1) { 00547 if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + offset + 1, chan->cid.cid_num)) { 00548 chan->priority += offset; 00549 } 00550 } 00551 } 00552 } 00553 } 00554 00555 pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset); 00556 if (save_macro_offset) 00557 ast_free(save_macro_offset); 00558 00559 /* Unlock the macro */ 00560 if (exclusive) { 00561 ast_debug(1, "Unlocking macrolock for '%s'\n", fullmacro); 00562 if (ast_context_unlockmacro(fullmacro)) { 00563 ast_log(LOG_ERROR, "Failed to unlock macro '%s' - that isn't good\n", fullmacro); 00564 res = 0; 00565 } 00566 } 00567 ast_channel_unlock(chan); 00568 ast_free(tmp_subst); 00569 00570 return res; 00571 }
| static struct ast_exten* find_matching_priority | ( | struct ast_context * | c, | |
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid | |||
| ) | [static, read] |
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 625 of file app_macro.c.
References ast_register_application_xml, macro_exec(), macro_exit_exec(), macroexclusive_exec(), and macroif_exec().
00626 { 00627 int res; 00628 00629 res = ast_register_application_xml(exit_app, macro_exit_exec); 00630 res |= ast_register_application_xml(if_app, macroif_exec); 00631 res |= ast_register_application_xml(exclusive_app, macroexclusive_exec); 00632 res |= ast_register_application_xml(app, macro_exec); 00633 00634 return res; 00635 }
| static int macro_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 573 of file app_macro.c.
References _macro_exec().
Referenced by load_module(), and macroif_exec().
00574 { 00575 return _macro_exec(chan, data, 0); 00576 }
| static int macro_exit_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 608 of file app_macro.c.
References MACRO_EXIT_RESULT.
Referenced by load_module().
00609 { 00610 return MACRO_EXIT_RESULT; 00611 }
| 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 578 of file app_macro.c.
References _macro_exec().
Referenced by load_module().
00579 { 00580 return _macro_exec(chan, data, 1); 00581 }
| static int macroif_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 583 of file app_macro.c.
References ast_log(), ast_strdupa, LOG_WARNING, macro_exec(), and pbx_checkcondition().
Referenced by load_module().
00584 { 00585 char *expr = NULL, *label_a = NULL, *label_b = NULL; 00586 int res = 0; 00587 00588 if (!(expr = ast_strdupa(data))) 00589 return -1; 00590 00591 if ((label_a = strchr(expr, '?'))) { 00592 *label_a = '\0'; 00593 label_a++; 00594 if ((label_b = strchr(label_a, ':'))) { 00595 *label_b = '\0'; 00596 label_b++; 00597 } 00598 if (pbx_checkcondition(expr)) 00599 res = macro_exec(chan, label_a); 00600 else if (label_b) 00601 res = macro_exec(chan, label_b); 00602 } else 00603 ast_log(LOG_WARNING, "Invalid Syntax.\n"); 00604 00605 return res; 00606 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 613 of file app_macro.c.
References ast_unregister_application().
00614 { 00615 int res; 00616 00617 res = ast_unregister_application(if_app); 00618 res |= ast_unregister_application(exit_app); 00619 res |= ast_unregister_application(app); 00620 res |= ast_unregister_application(exclusive_app); 00621 00622 return res; 00623 }
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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static] |
Definition at line 637 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 637 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.
1.5.6