Dial plan macro Implementation. More...
#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 int | _macro_exec (struct ast_channel *chan, const char *data, int exclusive) |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Extension Macros") | |
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 char * | app = "Macro" |
static char * | exclusive_app = "MacroExclusive" |
static char * | exit_app = "MacroExit" |
static char * | if_app = "MacroIf" |
static struct ast_datastore_info | macro_ds_info |
Dial plan macro Implementation.
Definition in file app_macro.c.
#define MACRO_EXIT_RESULT 1024 |
Definition at line 158 of file app_macro.c.
Referenced by _macro_exec(), and macro_exit_exec().
#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 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_EXIT_RESULT, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::macropriority, MAX_ARGS, ast_party_id::number, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_checkcondition(), ast_channel::priority, S_COR, ast_party_number::str, 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 }
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"Extension Macros" | ||||
) |
static struct ast_exten* find_matching_priority | ( | struct ast_context * | c, | |
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) | [static, read] |
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().
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 635 of file app_macro.c.
References ast_register_application_xml, macro_exec(), macro_exit_exec(), macroexclusive_exec(), and macroif_exec().
00636 { 00637 int res; 00638 00639 res = ast_register_application_xml(exit_app, macro_exit_exec); 00640 res |= ast_register_application_xml(if_app, macroif_exec); 00641 res |= ast_register_application_xml(exclusive_app, macroexclusive_exec); 00642 res |= ast_register_application_xml(app, macro_exec); 00643 00644 return res; 00645 }
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 618 of file app_macro.c.
References MACRO_EXIT_RESULT.
Referenced by load_module().
00619 { 00620 return MACRO_EXIT_RESULT; 00621 }
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 expr = ast_strdupa(data); 00600 00601 if ((label_a = strchr(expr, '?'))) { 00602 *label_a = '\0'; 00603 label_a++; 00604 if ((label_b = strchr(label_a, ':'))) { 00605 *label_b = '\0'; 00606 label_b++; 00607 } 00608 if (pbx_checkcondition(expr)) 00609 res = macro_exec(chan, label_a); 00610 else if (label_b) 00611 res = macro_exec(chan, label_b); 00612 } else 00613 ast_log(LOG_WARNING, "Invalid Syntax.\n"); 00614 00615 return res; 00616 }
static int unload_module | ( | void | ) | [static] |
Definition at line 623 of file app_macro.c.
References ast_unregister_application().
00624 { 00625 int res; 00626 00627 res = ast_unregister_application(if_app); 00628 res |= ast_unregister_application(exit_app); 00629 res |= ast_unregister_application(app); 00630 res |= ast_unregister_application(exclusive_app); 00631 00632 return res; 00633 }
char* app = "Macro" [static] |
Definition at line 160 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] |
{ .type = "MACRO", .chan_fixup = macro_fixup, }
Definition at line 167 of file app_macro.c.