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