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