Fri Jun 19 12:09:57 2009

Asterisk developer's documentation


app_macro.c File Reference

Dial plan macro Implementation. More...

#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

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_extenfind_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_infoast_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"


Detailed Description

Dial plan macro Implementation.

Author:
Mark Spencer <markster@digium.com>

Definition in file app_macro.c.


Define Documentation

#define MACRO_EXIT_RESULT   1024

Definition at line 43 of file app_macro.c.

Referenced by _macro_exec(), and macro_exit_exec().

#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().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 560 of file app_macro.c.

static void __unreg_module ( void   )  [static]

Definition at line 560 of file app_macro.c.

static int _macro_exec ( struct ast_channel chan,
void *  data,
int  exclusive 
) [static]

Definition at line 156 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().

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

static struct ast_exten* find_matching_priority ( struct ast_context c,
const char *  exten,
int  priority,
const char *  callerid 
) [static]

Definition at line 121 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().

00122 {
00123    struct ast_exten *e;
00124    struct ast_include *i;
00125    struct ast_context *c2;
00126 
00127    for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) {
00128       if (ast_extension_match(ast_get_extension_name(e), exten)) {
00129          int needmatch = ast_get_extension_matchcid(e);
00130          if ((needmatch && ast_extension_match(ast_get_extension_cidmatch(e), callerid)) ||
00131             (!needmatch)) {
00132             /* This is the matching extension we want */
00133             struct ast_exten *p;
00134             for (p=ast_walk_extension_priorities(e, NULL); p; p=ast_walk_extension_priorities(e, p)) {
00135                if (priority != ast_get_extension_priority(p))
00136                   continue;
00137                return p;
00138             }
00139          }
00140       }
00141    }
00142 
00143    /* No match; run through includes */
00144    for (i=ast_walk_context_includes(c, NULL); i; i=ast_walk_context_includes(c, i)) {
00145       for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) {
00146          if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) {
00147             e = find_matching_priority(c2, exten, priority, callerid);
00148             if (e)
00149                return e;
00150          }
00151       }
00152    }
00153    return NULL;
00154 }

static int load_module ( void   )  [static]

Definition at line 548 of file app_macro.c.

References ast_register_application, macro_exec(), macro_exit_exec(), macroexclusive_exec(), and macroif_exec().

static int macro_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 496 of file app_macro.c.

References _macro_exec(), and chan.

Referenced by load_module(), and macroif_exec().

00497 {
00498    return _macro_exec(chan, data, 0);
00499 }

static int macro_exit_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 531 of file app_macro.c.

References MACRO_EXIT_RESULT.

Referenced by load_module().

00532 {
00533    return MACRO_EXIT_RESULT;
00534 }

static void macro_fixup ( void *  data,
struct ast_channel old_chan,
struct ast_channel new_chan 
) [static]

Definition at line 103 of file app_macro.c.

References pbx_builtin_getvar_helper(), and pbx_builtin_setvar_helper().

00104 {
00105    int i;
00106    char varname[10];
00107    pbx_builtin_setvar_helper(new_chan, "MACRO_DEPTH", "0");
00108    pbx_builtin_setvar_helper(new_chan, "MACRO_CONTEXT", NULL);
00109    pbx_builtin_setvar_helper(new_chan, "MACRO_EXTEN", NULL);
00110    pbx_builtin_setvar_helper(new_chan, "MACRO_PRIORITY", NULL);
00111    pbx_builtin_setvar_helper(new_chan, "MACRO_OFFSET", NULL);
00112    for (i = 1; i < 100; i++) {
00113       snprintf(varname, sizeof(varname), "ARG%d", i);
00114       while (pbx_builtin_getvar_helper(new_chan, varname)) {
00115          /* Kill all levels of arguments */
00116          pbx_builtin_setvar_helper(new_chan, varname, NULL);
00117       }
00118    }
00119 }

static int macroexclusive_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 501 of file app_macro.c.

References _macro_exec(), and chan.

Referenced by load_module().

00502 {
00503    return _macro_exec(chan, data, 1);
00504 }

static int macroif_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 506 of file app_macro.c.

References ast_log(), ast_strdupa, chan, LOG_WARNING, macro_exec(), and pbx_checkcondition().

Referenced by load_module().

00507 {
00508    char *expr = NULL, *label_a = NULL, *label_b = NULL;
00509    int res = 0;
00510 
00511    if (!(expr = ast_strdupa(data)))
00512       return -1;
00513 
00514    if ((label_a = strchr(expr, '?'))) {
00515       *label_a = '\0';
00516       label_a++;
00517       if ((label_b = strchr(label_a, ':'))) {
00518          *label_b = '\0';
00519          label_b++;
00520       }
00521       if (pbx_checkcondition(expr))
00522          res = macro_exec(chan, label_a);
00523       else if (label_b) 
00524          res = macro_exec(chan, label_b);
00525    } else
00526       ast_log(LOG_WARNING, "Invalid Syntax.\n");
00527 
00528    return res;
00529 }

static int unload_module ( void   )  [static]

Definition at line 536 of file app_macro.c.

References ast_unregister_application().

00537 {
00538    int res;
00539 
00540    res = ast_unregister_application(if_app);
00541    res |= ast_unregister_application(exit_app);
00542    res |= ast_unregister_application(app);
00543    res |= ast_unregister_application(exclusive_app);
00544 
00545    return res;
00546 }


Variable Documentation

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 560 of file app_macro.c.

char* app = "Macro" [static]

Definition at line 86 of file app_macro.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 560 of file app_macro.c.

char* descrip [static]

Definition at line 45 of file app_macro.c.

char* exclusive_app = "MacroExclusive" [static]

Definition at line 88 of file app_macro.c.

char* exclusive_descrip [static]

Definition at line 72 of file app_macro.c.

char* exclusive_synopsis = "Exclusive Macro Implementation" [static]

Definition at line 93 of file app_macro.c.

char* exit_app = "MacroExit" [static]

Definition at line 89 of file app_macro.c.

char* exit_descrip [static]

Definition at line 79 of file app_macro.c.

char* exit_synopsis = "Exit From Macro" [static]

Definition at line 94 of file app_macro.c.

char* if_app = "MacroIf" [static]

Definition at line 87 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 66 of file app_macro.c.

char* if_synopsis = "Conditional Macro Implementation" [static]

Definition at line 92 of file app_macro.c.

struct ast_datastore_info macro_ds_info

Initial value:

 {
   .type = "MACRO",
   .chan_fixup = macro_fixup,
}

Definition at line 98 of file app_macro.c.

Referenced by _macro_exec().

char* synopsis = "Macro Implementation" [static]

Definition at line 91 of file app_macro.c.


Generated on Fri Jun 19 12:09:57 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7