#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 runningapp[0] = '\0'; 00283 runningdata[0] = '\0'; 00284 00285 /* What application will execute? */ 00286 if (ast_lock_contexts()) { 00287 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 00288 } else { 00289 for (c = ast_walk_contexts(NULL), e = NULL; c; c = ast_walk_contexts(c)) { 00290 if (!strcmp(ast_get_context_name(c), chan->context)) { 00291 if (ast_lock_context(c)) { 00292 ast_log(LOG_WARNING, "Unable to lock context?\n"); 00293 } else { 00294 e = find_matching_priority(c, chan->exten, chan->priority, chan->cid.cid_num); 00295 if (e) { /* This will only be undefined for pbx_realtime, which is majorly broken. */ 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 } 00299 ast_unlock_context(c); 00300 } 00301 break; 00302 } 00303 } 00304 } 00305 ast_unlock_contexts(); 00306 00307 /* Reset the macro depth, if it was changed in the last iteration */ 00308 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); 00309 00310 if ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num))) { 00311 /* Something bad happened, or a hangup has been requested. */ 00312 if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) || 00313 (res == '*') || (res == '#')) { 00314 /* Just return result as to the previous application as if it had been dialed */ 00315 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res); 00316 break; 00317 } 00318 switch(res) { 00319 case MACRO_EXIT_RESULT: 00320 res = 0; 00321 goto out; 00322 case AST_PBX_KEEPALIVE: 00323 if (option_debug) 00324 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); 00325 else if (option_verbose > 1) 00326 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); 00327 goto out; 00328 break; 00329 default: 00330 if (option_debug) 00331 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); 00332 else if (option_verbose > 1) 00333 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); 00334 dead = 1; 00335 goto out; 00336 } 00337 } 00338 00339 ast_log(LOG_DEBUG, "Executed application: %s\n", runningapp); 00340 00341 if (!strcasecmp(runningapp, "GOSUB")) { 00342 gosub_level++; 00343 ast_log(LOG_DEBUG, "Incrementing gosub_level\n"); 00344 } else if (!strcasecmp(runningapp, "GOSUBIF")) { 00345 char tmp2[1024] = "", *cond, *app, *app2 = tmp2; 00346 pbx_substitute_variables_helper(chan, runningdata, tmp2, sizeof(tmp2) - 1); 00347 cond = strsep(&app2, "?"); 00348 app = strsep(&app2, ":"); 00349 if (pbx_checkcondition(cond)) { 00350 if (!ast_strlen_zero(app)) { 00351 gosub_level++; 00352 ast_log(LOG_DEBUG, "Incrementing gosub_level\n"); 00353 } 00354 } else { 00355 if (!ast_strlen_zero(app2)) { 00356 gosub_level++; 00357 ast_log(LOG_DEBUG, "Incrementing gosub_level\n"); 00358 } 00359 } 00360 } else if (!strcasecmp(runningapp, "RETURN")) { 00361 gosub_level--; 00362 ast_log(LOG_DEBUG, "Decrementing gosub_level\n"); 00363 } else if (!strcasecmp(runningapp, "STACKPOP")) { 00364 gosub_level--; 00365 ast_log(LOG_DEBUG, "Decrementing gosub_level\n"); 00366 } else if (!strncasecmp(runningapp, "EXEC", 4)) { 00367 /* Must evaluate args to find actual app */ 00368 char tmp2[1024] = "", *tmp3 = NULL; 00369 pbx_substitute_variables_helper(chan, runningdata, tmp2, sizeof(tmp2) - 1); 00370 if (!strcasecmp(runningapp, "EXECIF")) { 00371 tmp3 = strchr(tmp2, '|'); 00372 if (tmp3) 00373 *tmp3++ = '\0'; 00374 if (!pbx_checkcondition(tmp2)) 00375 tmp3 = NULL; 00376 } else 00377 tmp3 = tmp2; 00378 00379 if (tmp3) 00380 ast_log(LOG_DEBUG, "Last app: %s\n", tmp3); 00381 00382 if (tmp3 && !strncasecmp(tmp3, "GOSUB", 5)) { 00383 gosub_level++; 00384 ast_log(LOG_DEBUG, "Incrementing gosub_level\n"); 00385 } else if (tmp3 && !strncasecmp(tmp3, "RETURN", 6)) { 00386 gosub_level--; 00387 ast_log(LOG_DEBUG, "Decrementing gosub_level\n"); 00388 } else if (tmp3 && !strncasecmp(tmp3, "STACKPOP", 8)) { 00389 gosub_level--; 00390 ast_log(LOG_DEBUG, "Decrementing gosub_level\n"); 00391 } 00392 } 00393 00394 if (gosub_level == 0 && strcasecmp(chan->context, fullmacro)) { 00395 if (option_verbose > 1) 00396 ast_verbose(VERBOSE_PREFIX_2 "Channel '%s' jumping out of macro '%s'\n", chan->name, macro); 00397 break; 00398 } 00399 00400 /* don't stop executing extensions when we're in "h" */ 00401 if (chan->_softhangup && !inhangup) { 00402 ast_log(LOG_DEBUG, "Extension %s, macroexten %s, priority %d returned normally even though call was hung up\n", 00403 chan->exten, chan->macroexten, chan->priority); 00404 goto out; 00405 } 00406 chan->priority++; 00407 } 00408 out: 00409 /* Reset the depth back to what it was when the routine was entered (like if we called Macro recursively) */ 00410 snprintf(depthc, sizeof(depthc), "%d", depth); 00411 if (!dead) { 00412 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); 00413 ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP); 00414 } 00415 00416 for (x = 1; x < argc; x++) { 00417 /* Restore old arguments and delete ours */ 00418 snprintf(varname, sizeof(varname), "ARG%d", x); 00419 if (oldargs[x]) { 00420 if (!dead) 00421 pbx_builtin_setvar_helper(chan, varname, oldargs[x]); 00422 free(oldargs[x]); 00423 } else if (!dead) { 00424 pbx_builtin_setvar_helper(chan, varname, NULL); 00425 } 00426 } 00427 00428 /* Restore macro variables */ 00429 if (!dead) { 00430 pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten); 00431 pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context); 00432 pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority); 00433 } 00434 if (save_macro_exten) 00435 free(save_macro_exten); 00436 if (save_macro_context) 00437 free(save_macro_context); 00438 if (save_macro_priority) 00439 free(save_macro_priority); 00440 00441 if (!dead && setmacrocontext) { 00442 chan->macrocontext[0] = '\0'; 00443 chan->macroexten[0] = '\0'; 00444 chan->macropriority = 0; 00445 } 00446 00447 if (!dead && !strcasecmp(chan->context, fullmacro)) { 00448 /* If we're leaving the macro normally, restore original information */ 00449 chan->priority = oldpriority; 00450 ast_copy_string(chan->context, oldcontext, sizeof(chan->context)); 00451 if (!(chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO)) { 00452 /* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */ 00453 const char *offsets; 00454 ast_copy_string(chan->exten, oldexten, sizeof(chan->exten)); 00455 if ((offsets = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"))) { 00456 /* Handle macro offset if it's set by checking the availability of step n + offset + 1, otherwise continue 00457 normally if there is any problem */ 00458 if (sscanf(offsets, "%d", &offset) == 1) { 00459 if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + offset + 1, chan->cid.cid_num)) { 00460 chan->priority += offset; 00461 } 00462 } 00463 } 00464 } 00465 } 00466 00467 if (!dead) 00468 pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset); 00469 if (save_macro_offset) 00470 free(save_macro_offset); 00471 00472 /* Unlock the macro */ 00473 if (exclusive) { 00474 ast_log(LOG_DEBUG, "Unlocking macrolock for '%s'\n", fullmacro); 00475 if (ast_context_unlockmacro(fullmacro)) { 00476 ast_log(LOG_ERROR, "Failed to unlock macro '%s' - that isn't good\n", fullmacro); 00477 res = 0; 00478 } 00479 } 00480 00481 ast_module_user_remove(u); 00482 00483 return res; 00484 }
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 547 of file app_macro.c.
References ast_register_application(), macro_exec(), macro_exit_exec(), macroexclusive_exec(), and macroif_exec().
00548 { 00549 int res; 00550 00551 res = ast_register_application(exit_app, macro_exit_exec, exit_synopsis, exit_descrip); 00552 res |= ast_register_application(if_app, macroif_exec, if_synopsis, if_descrip); 00553 res |= ast_register_application(exclusive_app, macroexclusive_exec, exclusive_synopsis, exclusive_descrip); 00554 res |= ast_register_application(app, macro_exec, synopsis, descrip); 00555 00556 return res; 00557 }
static int macro_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 486 of file app_macro.c.
References _macro_exec().
Referenced by load_module(), and macroif_exec().
00487 { 00488 return _macro_exec(chan, data, 0); 00489 }
static int macro_exit_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 528 of file app_macro.c.
References MACRO_EXIT_RESULT.
Referenced by load_module().
00529 { 00530 return MACRO_EXIT_RESULT; 00531 }
static int macroexclusive_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 491 of file app_macro.c.
References _macro_exec().
Referenced by load_module().
00492 { 00493 return _macro_exec(chan, data, 1); 00494 }
static int macroif_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 496 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().
00497 { 00498 char *expr = NULL, *label_a = NULL, *label_b = NULL; 00499 int res = 0; 00500 struct ast_module_user *u; 00501 00502 u = ast_module_user_add(chan); 00503 00504 if (!(expr = ast_strdupa(data))) { 00505 ast_module_user_remove(u); 00506 return -1; 00507 } 00508 00509 if ((label_a = strchr(expr, '?'))) { 00510 *label_a = '\0'; 00511 label_a++; 00512 if ((label_b = strchr(label_a, ':'))) { 00513 *label_b = '\0'; 00514 label_b++; 00515 } 00516 if (pbx_checkcondition(expr)) 00517 res = macro_exec(chan, label_a); 00518 else if (label_b) 00519 res = macro_exec(chan, label_b); 00520 } else 00521 ast_log(LOG_WARNING, "Invalid Syntax.\n"); 00522 00523 ast_module_user_remove(u); 00524 00525 return res; 00526 }
static int unload_module | ( | void | ) | [static] |
Definition at line 533 of file app_macro.c.
References ast_module_user_hangup_all, and ast_unregister_application().
00534 { 00535 int res; 00536 00537 res = ast_unregister_application(if_app); 00538 res |= ast_unregister_application(exit_app); 00539 res |= ast_unregister_application(app); 00540 res |= ast_unregister_application(exclusive_app); 00541 00542 ast_module_user_hangup_all(); 00543 00544 return res; 00545 }
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.