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