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