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