#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/options.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 int | _macro_exec (struct ast_channel *chan, void *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, void *data) |
static int | macro_exit_exec (struct ast_channel *chan, void *data) |
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 char * | app = "Macro" |
static char * | descrip |
static char * | exclusive_app = "MacroExclusive" |
static char * | exclusive_descrip |
static char * | exclusive_synopsis = "Exclusive Macro Implementation" |
static char * | exit_app = "MacroExit" |
static char * | exit_descrip |
static char * | exit_synopsis = "Exit From Macro" |
static char * | if_app = "MacroIf" |
static char * | if_descrip |
static char * | if_synopsis = "Conditional Macro Implementation" |
static char * | synopsis = "Macro Implementation" |
Definition in file app_macro.c.
#define MACRO_EXIT_RESULT 1024 |
#define MAX_ARGS 80 |
Definition at line 48 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, | |
void * | data, | |||
int | exclusive | |||
) | [static] |
Definition at line 142 of file app_macro.c.
References ast_channel::_softhangup, app2, ast_autoservice_start(), ast_autoservice_stop(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_exists_extension(), AST_FLAG_IN_AUTOLOOP, ast_get_context_name(), ast_get_extension_app(), ast_get_extension_app_data(), ast_lock_context(), ast_log(), AST_MAX_CONTEXT, ast_module_user_add, ast_module_user_remove, AST_PBX_KEEPALIVE, ast_rdlock_contexts(), ast_set2_flag, ast_set_flag, AST_SOFTHANGUP_ASYNCGOTO, ast_spawn_extension(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_unlock_context(), ast_unlock_contexts(), ast_verbose(), ast_walk_contexts(), ast_module_user::chan, ast_channel::cid, ast_callerid::cid_num, cond, ast_channel::context, ast_channel::exten, find_matching_priority(), free, LOG_DEBUG, LOG_ERROR, LOG_WARNING, MACRO_EXIT_RESULT, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::macropriority, MAX_ARGS, offset, option_debug, option_verbose, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_checkcondition(), pbx_substitute_variables_helper(), ast_channel::priority, s, strsep(), and VERBOSE_PREFIX_2.
Referenced by macro_exec(), and macroexclusive_exec().
00143 { 00144 const char *s; 00145 char *tmp; 00146 char *cur, *rest; 00147 char *macro; 00148 char fullmacro[80]; 00149 char varname[80]; 00150 char runningapp[80], runningdata[1024]; 00151 char *oldargs[MAX_ARGS + 1] = { NULL, }; 00152 int argc, x; 00153 int res=0; 00154 char oldexten[256]=""; 00155 int oldpriority, gosub_level = 0; 00156 char pc[80], depthc[12]; 00157 char oldcontext[AST_MAX_CONTEXT] = ""; 00158 const char *inhangupc; 00159 int offset, depth = 0, maxdepth = 7; 00160 int setmacrocontext=0; 00161 int autoloopflag, dead = 0, inhangup = 0; 00162 00163 char *save_macro_exten; 00164 char *save_macro_context; 00165 char *save_macro_priority; 00166 char *save_macro_offset; 00167 struct ast_module_user *u; 00168 00169 if (ast_strlen_zero(data)) { 00170 ast_log(LOG_WARNING, "Macro() requires arguments. See \"show application macro\" for help.\n"); 00171 return -1; 00172 } 00173 00174 u = ast_module_user_add(chan); 00175 00176 /* does the user want a deeper rabbit hole? */ 00177 s = pbx_builtin_getvar_helper(chan, "MACRO_RECURSION"); 00178 if (s) 00179 sscanf(s, "%d", &maxdepth); 00180 00181 /* Count how many levels deep the rabbit hole goes */ 00182 s = pbx_builtin_getvar_helper(chan, "MACRO_DEPTH"); 00183 if (s) 00184 sscanf(s, "%d", &depth); 00185 /* Used for detecting whether to return when a Macro is called from another Macro after hangup */ 00186 if (strcmp(chan->exten, "h") == 0) 00187 pbx_builtin_setvar_helper(chan, "MACRO_IN_HANGUP", "1"); 00188 inhangupc = pbx_builtin_getvar_helper(chan, "MACRO_IN_HANGUP"); 00189 if (!ast_strlen_zero(inhangupc)) 00190 sscanf(inhangupc, "%d", &inhangup); 00191 00192 if (depth >= maxdepth) { 00193 ast_log(LOG_ERROR, "Macro(): possible infinite loop detected. Returning early.\n"); 00194 ast_module_user_remove(u); 00195 return 0; 00196 } 00197 snprintf(depthc, sizeof(depthc), "%d", depth + 1); 00198 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); 00199 00200 tmp = ast_strdupa(data); 00201 rest = tmp; 00202 macro = strsep(&rest, "|"); 00203 if (ast_strlen_zero(macro)) { 00204 ast_log(LOG_WARNING, "Invalid macro name specified\n"); 00205 ast_module_user_remove(u); 00206 return 0; 00207 } 00208 00209 snprintf(fullmacro, sizeof(fullmacro), "macro-%s", macro); 00210 if (!ast_exists_extension(chan, fullmacro, "s", 1, chan->cid.cid_num)) { 00211 if (!ast_context_find(fullmacro)) 00212 ast_log(LOG_WARNING, "No such context '%s' for macro '%s'\n", fullmacro, macro); 00213 else 00214 ast_log(LOG_WARNING, "Context '%s' for macro '%s' lacks 's' extension, priority 1\n", fullmacro, macro); 00215 ast_module_user_remove(u); 00216 return 0; 00217 } 00218 00219 /* If we are to run the macro exclusively, take the mutex */ 00220 if (exclusive) { 00221 ast_log(LOG_DEBUG, "Locking macrolock for '%s'\n", fullmacro); 00222 ast_autoservice_start(chan); 00223 if (ast_context_lockmacro(fullmacro)) { 00224 ast_log(LOG_WARNING, "Failed to lock macro '%s' as in-use\n", fullmacro); 00225 ast_autoservice_stop(chan); 00226 ast_module_user_remove(u); 00227 00228 return 0; 00229 } 00230 ast_autoservice_stop(chan); 00231 } 00232 00233 /* Save old info */ 00234 oldpriority = chan->priority; 00235 ast_copy_string(oldexten, chan->exten, sizeof(oldexten)); 00236 ast_copy_string(oldcontext, chan->context, sizeof(oldcontext)); 00237 if (ast_strlen_zero(chan->macrocontext)) { 00238 ast_copy_string(chan->macrocontext, chan->context, sizeof(chan->macrocontext)); 00239 ast_copy_string(chan->macroexten, chan->exten, sizeof(chan->macroexten)); 00240 chan->macropriority = chan->priority; 00241 setmacrocontext=1; 00242 } 00243 argc = 1; 00244 /* Save old macro variables */ 00245 save_macro_exten = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_EXTEN")); 00246 pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", oldexten); 00247 00248 save_macro_context = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_CONTEXT")); 00249 pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", oldcontext); 00250 00251 save_macro_priority = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_PRIORITY")); 00252 snprintf(pc, sizeof(pc), "%d", oldpriority); 00253 pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", pc); 00254 00255 save_macro_offset = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_OFFSET")); 00256 pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", NULL); 00257 00258 /* Setup environment for new run */ 00259 chan->exten[0] = 's'; 00260 chan->exten[1] = '\0'; 00261 ast_copy_string(chan->context, fullmacro, sizeof(chan->context)); 00262 chan->priority = 1; 00263 00264 while((cur = strsep(&rest, "|")) && (argc < MAX_ARGS)) { 00265 const char *s; 00266 /* Save copy of old arguments if we're overwriting some, otherwise 00267 let them pass through to the other macro */ 00268 snprintf(varname, sizeof(varname), "ARG%d", argc); 00269 s = pbx_builtin_getvar_helper(chan, varname); 00270 if (s) 00271 oldargs[argc] = ast_strdup(s); 00272 pbx_builtin_setvar_helper(chan, varname, cur); 00273 argc++; 00274 } 00275 autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP); 00276 ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP); 00277 while(ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) { 00278 struct ast_context *c; 00279 struct ast_exten *e; 00280 runningapp[0] = '\0'; 00281 runningdata[0] = '\0'; 00282 00283 /* What application will execute? */ 00284 if (ast_rdlock_contexts()) { 00285 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 00286 } else { 00287 for (c = ast_walk_contexts(NULL), e = NULL; c; c = ast_walk_contexts(c)) { 00288 if (!strcmp(ast_get_context_name(c), chan->context)) { 00289 if (ast_lock_context(c)) { 00290 ast_log(LOG_WARNING, "Unable to lock context?\n"); 00291 } else { 00292 e = find_matching_priority(c, chan->exten, chan->priority, chan->cid.cid_num); 00293 if (e) { /* This will only be undefined for pbx_realtime, which is majorly broken. */ 00294 ast_copy_string(runningapp, ast_get_extension_app(e), sizeof(runningapp)); 00295 ast_copy_string(runningdata, ast_get_extension_app_data(e), sizeof(runningdata)); 00296 } 00297 ast_unlock_context(c); 00298 } 00299 break; 00300 } 00301 } 00302 } 00303 ast_unlock_contexts(); 00304 00305 /* Reset the macro depth, if it was changed in the last iteration */ 00306 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); 00307 00308 if ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num))) { 00309 /* Something bad happened, or a hangup has been requested. */ 00310 if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) || 00311 (res == '*') || (res == '#')) { 00312 /* Just return result as to the previous application as if it had been dialed */ 00313 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res); 00314 break; 00315 } 00316 switch(res) { 00317 case MACRO_EXIT_RESULT: 00318 res = 0; 00319 goto out; 00320 case AST_PBX_KEEPALIVE: 00321 if (option_debug) 00322 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE in macro %s on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name); 00323 else if (option_verbose > 1) 00324 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE in macro '%s' on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name); 00325 goto out; 00326 break; 00327 default: 00328 if (option_debug) 00329 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro); 00330 else if (option_verbose > 1) 00331 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro); 00332 dead = 1; 00333 goto out; 00334 } 00335 } 00336 00337 ast_log(LOG_DEBUG, "Executed application: %s\n", runningapp); 00338 00339 if (!strcasecmp(runningapp, "GOSUB")) { 00340 gosub_level++; 00341 ast_log(LOG_DEBUG, "Incrementing gosub_level\n"); 00342 } else if (!strcasecmp(runningapp, "GOSUBIF")) { 00343 char tmp2[1024] = "", *cond, *app, *app2 = tmp2; 00344 pbx_substitute_variables_helper(chan, runningdata, tmp2, sizeof(tmp2) - 1); 00345 cond = strsep(&app2, "?"); 00346 app = strsep(&app2, ":"); 00347 if (pbx_checkcondition(cond)) { 00348 if (!ast_strlen_zero(app)) { 00349 gosub_level++; 00350 ast_log(LOG_DEBUG, "Incrementing gosub_level\n"); 00351 } 00352 } else { 00353 if (!ast_strlen_zero(app2)) { 00354 gosub_level++; 00355 ast_log(LOG_DEBUG, "Incrementing gosub_level\n"); 00356 } 00357 } 00358 } else if (!strcasecmp(runningapp, "RETURN")) { 00359 gosub_level--; 00360 ast_log(LOG_DEBUG, "Decrementing gosub_level\n"); 00361 } else if (!strcasecmp(runningapp, "STACKPOP")) { 00362 gosub_level--; 00363 ast_log(LOG_DEBUG, "Decrementing gosub_level\n"); 00364 } else if (!strncasecmp(runningapp, "EXEC", 4)) { 00365 /* Must evaluate args to find actual app */ 00366 char tmp2[1024] = "", *tmp3 = NULL; 00367 pbx_substitute_variables_helper(chan, runningdata, tmp2, sizeof(tmp2) - 1); 00368 if (!strcasecmp(runningapp, "EXECIF")) { 00369 tmp3 = strchr(tmp2, '|'); 00370 if (tmp3) 00371 *tmp3++ = '\0'; 00372 if (!pbx_checkcondition(tmp2)) 00373 tmp3 = NULL; 00374 } else 00375 tmp3 = tmp2; 00376 00377 if (tmp3) 00378 ast_log(LOG_DEBUG, "Last app: %s\n", tmp3); 00379 00380 if (tmp3 && !strncasecmp(tmp3, "GOSUB", 5)) { 00381 gosub_level++; 00382 ast_log(LOG_DEBUG, "Incrementing gosub_level\n"); 00383 } else if (tmp3 && !strncasecmp(tmp3, "RETURN", 6)) { 00384 gosub_level--; 00385 ast_log(LOG_DEBUG, "Decrementing gosub_level\n"); 00386 } else if (tmp3 && !strncasecmp(tmp3, "STACKPOP", 8)) { 00387 gosub_level--; 00388 ast_log(LOG_DEBUG, "Decrementing gosub_level\n"); 00389 } 00390 } 00391 00392 if (gosub_level == 0 && strcasecmp(chan->context, fullmacro)) { 00393 if (option_verbose > 1) 00394 ast_verbose(VERBOSE_PREFIX_2 "Channel '%s' jumping out of macro '%s'\n", chan->name, macro); 00395 break; 00396 } 00397 00398 /* don't stop executing extensions when we're in "h" */ 00399 if (chan->_softhangup && !inhangup) { 00400 ast_log(LOG_DEBUG, "Extension %s, macroexten %s, priority %d returned normally even though call was hung up\n", 00401 chan->exten, chan->macroexten, chan->priority); 00402 goto out; 00403 } 00404 chan->priority++; 00405 } 00406 out: 00407 /* Reset the depth back to what it was when the routine was entered (like if we called Macro recursively) */ 00408 snprintf(depthc, sizeof(depthc), "%d", depth); 00409 if (!dead) { 00410 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); 00411 ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP); 00412 } 00413 00414 for (x = 1; x < argc; x++) { 00415 /* Restore old arguments and delete ours */ 00416 snprintf(varname, sizeof(varname), "ARG%d", x); 00417 if (oldargs[x]) { 00418 if (!dead) 00419 pbx_builtin_setvar_helper(chan, varname, oldargs[x]); 00420 free(oldargs[x]); 00421 } else if (!dead) { 00422 pbx_builtin_setvar_helper(chan, varname, NULL); 00423 } 00424 } 00425 00426 /* Restore macro variables */ 00427 if (!dead) { 00428 pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten); 00429 pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context); 00430 pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority); 00431 } 00432 if (save_macro_exten) 00433 free(save_macro_exten); 00434 if (save_macro_context) 00435 free(save_macro_context); 00436 if (save_macro_priority) 00437 free(save_macro_priority); 00438 00439 if (!dead && setmacrocontext) { 00440 chan->macrocontext[0] = '\0'; 00441 chan->macroexten[0] = '\0'; 00442 chan->macropriority = 0; 00443 } 00444 00445 if (!dead && !strcasecmp(chan->context, fullmacro)) { 00446 /* If we're leaving the macro normally, restore original information */ 00447 chan->priority = oldpriority; 00448 ast_copy_string(chan->context, oldcontext, sizeof(chan->context)); 00449 if (!(chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO)) { 00450 /* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */ 00451 const char *offsets; 00452 ast_copy_string(chan->exten, oldexten, sizeof(chan->exten)); 00453 if ((offsets = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"))) { 00454 /* Handle macro offset if it's set by checking the availability of step n + offset + 1, otherwise continue 00455 normally if there is any problem */ 00456 if (sscanf(offsets, "%d", &offset) == 1) { 00457 if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + offset + 1, chan->cid.cid_num)) { 00458 chan->priority += offset; 00459 } 00460 } 00461 } 00462 } 00463 } 00464 00465 if (!dead) 00466 pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset); 00467 if (save_macro_offset) 00468 free(save_macro_offset); 00469 00470 /* Unlock the macro */ 00471 if (exclusive) { 00472 ast_log(LOG_DEBUG, "Unlocking macrolock for '%s'\n", fullmacro); 00473 if (ast_context_unlockmacro(fullmacro)) { 00474 ast_log(LOG_ERROR, "Failed to unlock macro '%s' - that isn't good\n", fullmacro); 00475 res = 0; 00476 } 00477 } 00478 00479 ast_module_user_remove(u); 00480 00481 return res; 00482 }
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] |
Definition at line 107 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().
00108 { 00109 struct ast_exten *e; 00110 struct ast_include *i; 00111 struct ast_context *c2; 00112 00113 for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) { 00114 if (ast_extension_match(ast_get_extension_name(e), exten)) { 00115 int needmatch = ast_get_extension_matchcid(e); 00116 if ((needmatch && ast_extension_match(ast_get_extension_cidmatch(e), callerid)) || 00117 (!needmatch)) { 00118 /* This is the matching extension we want */ 00119 struct ast_exten *p; 00120 for (p=ast_walk_extension_priorities(e, NULL); p; p=ast_walk_extension_priorities(e, p)) { 00121 if (priority != ast_get_extension_priority(p)) 00122 continue; 00123 return p; 00124 } 00125 } 00126 } 00127 } 00128 00129 /* No match; run through includes */ 00130 for (i=ast_walk_context_includes(c, NULL); i; i=ast_walk_context_includes(c, i)) { 00131 for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) { 00132 if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) { 00133 e = find_matching_priority(c2, exten, priority, callerid); 00134 if (e) 00135 return e; 00136 } 00137 } 00138 } 00139 return NULL; 00140 }
static int load_module | ( | void | ) | [static] |
Definition at line 545 of file app_macro.c.
References ast_register_application(), macro_exec(), macro_exit_exec(), macroexclusive_exec(), and macroif_exec().
00546 { 00547 int res; 00548 00549 res = ast_register_application(exit_app, macro_exit_exec, exit_synopsis, exit_descrip); 00550 res |= ast_register_application(if_app, macroif_exec, if_synopsis, if_descrip); 00551 res |= ast_register_application(exclusive_app, macroexclusive_exec, exclusive_synopsis, exclusive_descrip); 00552 res |= ast_register_application(app, macro_exec, synopsis, descrip); 00553 00554 return res; 00555 }
static int macro_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 484 of file app_macro.c.
References _macro_exec().
Referenced by load_module(), and macroif_exec().
00485 { 00486 return _macro_exec(chan, data, 0); 00487 }
static int macro_exit_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 526 of file app_macro.c.
References MACRO_EXIT_RESULT.
Referenced by load_module().
00527 { 00528 return MACRO_EXIT_RESULT; 00529 }
static int macroexclusive_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 489 of file app_macro.c.
References _macro_exec().
Referenced by load_module().
00490 { 00491 return _macro_exec(chan, data, 1); 00492 }
static int macroif_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 494 of file app_macro.c.
References ast_log(), ast_module_user_add, ast_module_user_remove, ast_strdupa, ast_module_user::chan, LOG_WARNING, macro_exec(), and pbx_checkcondition().
Referenced by load_module().
00495 { 00496 char *expr = NULL, *label_a = NULL, *label_b = NULL; 00497 int res = 0; 00498 struct ast_module_user *u; 00499 00500 u = ast_module_user_add(chan); 00501 00502 if (!(expr = ast_strdupa(data))) { 00503 ast_module_user_remove(u); 00504 return -1; 00505 } 00506 00507 if ((label_a = strchr(expr, '?'))) { 00508 *label_a = '\0'; 00509 label_a++; 00510 if ((label_b = strchr(label_a, ':'))) { 00511 *label_b = '\0'; 00512 label_b++; 00513 } 00514 if (pbx_checkcondition(expr)) 00515 res = macro_exec(chan, label_a); 00516 else if (label_b) 00517 res = macro_exec(chan, label_b); 00518 } else 00519 ast_log(LOG_WARNING, "Invalid Syntax.\n"); 00520 00521 ast_module_user_remove(u); 00522 00523 return res; 00524 }
static int unload_module | ( | void | ) | [static] |
Definition at line 531 of file app_macro.c.
References ast_module_user_hangup_all, and ast_unregister_application().
00532 { 00533 int res; 00534 00535 res = ast_unregister_application(if_app); 00536 res |= ast_unregister_application(exit_app); 00537 res |= ast_unregister_application(app); 00538 res |= ast_unregister_application(exclusive_app); 00539 00540 ast_module_user_hangup_all(); 00541 00542 return res; 00543 }
char* app = "Macro" [static] |
Definition at line 96 of file app_macro.c.
char* descrip [static] |
Definition at line 53 of file app_macro.c.
char* exclusive_app = "MacroExclusive" [static] |
Definition at line 98 of file app_macro.c.
char* exclusive_descrip [static] |
Definition at line 82 of file app_macro.c.
char* exclusive_synopsis = "Exclusive Macro Implementation" [static] |
Definition at line 103 of file app_macro.c.
char* exit_app = "MacroExit" [static] |
char* exit_descrip [static] |
Definition at line 89 of file app_macro.c.
char* exit_synopsis = "Exit From Macro" [static] |
Definition at line 104 of file app_macro.c.
char* if_app = "MacroIf" [static] |
Definition at line 97 of file app_macro.c.
char* if_descrip [static] |
Initial value:
" MacroIf(<expr>?macroname_a[|arg1][:macroname_b[|arg1]])\n" "Executes macro defined in <macroname_a> if <expr> is true\n" "(otherwise <macroname_b> if provided)\n" "Arguments and return values as in application macro()\n"
Definition at line 76 of file app_macro.c.
char* if_synopsis = "Conditional Macro Implementation" [static] |
Definition at line 102 of file app_macro.c.
char* synopsis = "Macro Implementation" [static] |
Definition at line 101 of file app_macro.c.