ael_main.c File Reference

#include "asterisk.h"
#include <locale.h>
#include <ctype.h>
#include <regex.h>
#include <limits.h>
#include "asterisk/backtrace.h"
#include "asterisk/channel.h"
#include "asterisk/ast_expr.h"
#include "asterisk/module.h"
#include "asterisk/app.h"
#include "asterisk/lock.h"
#include "asterisk/hashtab.h"
#include "asterisk/ael_structs.h"
#include "asterisk/extconf.h"

Include dependency graph for ael_main.c:

Go to the source code of this file.

Data Structures

struct  ast_context
 ast_context: An extension context More...
struct  namelist

Defines

#define ADD_LAST(headptr, memptr)   if(!headptr){ headptr=(memptr); (headptr##_last)=(memptr);} else {(headptr##_last)->next = (memptr); (headptr##_last) = (memptr);}

Functions

void __ast_verbose (const char *file, int line, const char *func, int level, const char *fmt,...)
 Send a verbose message (based on verbose level).
int ael_external_load_module (void)
int ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Main interface to add extensions to the list for out context.
int ast_add_profile (const char *x, uint64_t scale)
 support for event profiling
void ast_cli_register_multiple (void)
void ast_cli_unregister_multiple (void)
void ast_context_add_ignorepat2 (struct ast_context *con, const char *value, const char *registrar)
void ast_context_add_include2 (struct ast_context *con, const char *value, const char *registrar)
 Add a context include.
void ast_context_add_switch2 (struct ast_context *con, const char *value, const char *data, int eval, const char *registrar)
 Adds a switch (first param is a ast_context).
struct ast_contextast_context_create (void **extcontexts, const char *name, const char *registrar)
void ast_context_destroy (void)
struct ast_contextast_context_find_or_create (void **extcontexts, void *tab, const char *name, const char *registrar)
void ast_context_verify_includes (void)
struct ast_custom_functionast_custom_function_find (const char *name)
const char * ast_get_context_name (struct ast_context *con)
int ast_hashtab_compare_contexts (const void *ah_a, const void *ah_b)
 hashtable functions for contexts
unsigned int ast_hashtab_hash_contexts (const void *obj)
int ast_loader_register (int(*updater)(void))
 Add a procedure to be run when modules have been updated.
int ast_loader_unregister (int(*updater)(void))
 Remove a procedure to be run when modules are updated.
void ast_log (int level, const char *file, int line, const char *function, const char *fmt,...)
 Used for sending a log message This is the standard logger function. Probably the only way you will invoke it would be something like this: ast_log(AST_LOG_WHATEVER, "Problem with the %s Captain. We should get some more. Will %d be enough?\n", "flux capacitor", 10); where WHATEVER is one of ERROR, DEBUG, EVENT, NOTICE, or WARNING depending on which log you wish to output to. These are implemented as macros, that will provide the function with the needed arguments.
void ast_merge_contexts_and_delete (void)
void ast_module_register (const struct ast_module_info *x)
void ast_module_unregister (const struct ast_module_info *x)
char * ast_process_quotes_and_slashes (char *start, char find, char replace_with)
 Process a string to find and replace characters.
void ast_register_file_version (const char *file, const char *version)
 Register the version of a source code file with the core.
void ast_unregister_file_version (const char *file)
 Unregister a source code file from the core.
struct ast_extenast_walk_context_extensions (struct ast_context *con, struct ast_exten *exten)
struct ast_ignorepatast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip)
struct ast_includeast_walk_context_includes (struct ast_context *con, struct ast_include *inc)
struct ast_swast_walk_context_switches (struct ast_context *con, struct ast_sw *sw)
struct ast_contextast_walk_contexts (void)
struct namelistcreate_name (const char *name)
void destroy_namelist (struct namelist *x)
void filter_leading_space_from_exprs (char *str)
void filter_newlines (char *str)
int main (int argc, char **argv)
void pbx_builtin_setvar (void *chan, void *data)
struct ast_extenpbx_find_extension (struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
struct ast_apppbx_findapp (const char *app)
 Look up an application.
void pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count)

Variables

const char * ast_config_AST_CONFIG_DIR = config_dir
const char * ast_config_AST_VAR_DIR = var_dir
static char config_dir [PATH_MAX]
struct ast_contextcontext_list
int conts = 0
static int dump_extensions = 0
static FILE * dumpfile
int extens = 0
static int FIRST_TIME = 0
struct namelistglobalvars
struct namelistglobalvars_last
struct ast_contextlast_context
char last_exten [18000]
struct module_symbols mod_data
static int no_comp = 0
int option_debug = 0
int option_verbose = 0
int priors = 0
static int quiet = 0
static int use_curr_dir = 0
static char var_dir [PATH_MAX]


Define Documentation

#define ADD_LAST ( headptr,
memptr   )     if(!headptr){ headptr=(memptr); (headptr##_last)=(memptr);} else {(headptr##_last)->next = (memptr); (headptr##_last) = (memptr);}


Function Documentation

void __ast_verbose ( const char *  file,
int  line,
const char *  func,
int  level,
const char *  fmt,
  ... 
)

Send a verbose message (based on verbose level).

This works like ast_log, but prints verbose messages to the console depending on verbosity level set.

ast_verbose(VERBOSE_PREFIX_3 "Whatever %s is happening\n", "nothing");

This will print the message to the console if the verbose level is set to a level >= 3

Note the absence of a comma after the VERBOSE_PREFIX_3. This is important. VERBOSE_PREFIX_1 through VERBOSE_PREFIX_4 are defined.

Version:
11 added level parameter

Definition at line 1837 of file logger.c.

References __ast_verbose_ap(), and ast_read_threadstorage_callid().

01838 {
01839    ast_callid callid;
01840    va_list ap;
01841 
01842    callid = ast_read_threadstorage_callid();
01843 
01844    va_start(ap, fmt);
01845    __ast_verbose_ap(file, line, func, level, callid, fmt, ap);
01846    va_end(ap);
01847 }

int ael_external_load_module ( void   ) 

Referenced by main().

int ast_add_extension2 ( struct ast_context con,
int  replace,
const char *  extension,
int  priority,
const char *  label,
const char *  callerid,
const char *  application,
void *  data,
void(*)(void *)  datad,
const char *  registrar 
)

Main interface to add extensions to the list for out context.

Add an extension to an extension context, this time with an ast_context *.

We sort extensions in order of matching preference, so that we can stop the search as soon as we find a suitable match. This ordering also takes care of wildcards such as '.' (meaning "one or more of any character") and '!' (which is 'earlymatch', meaning "zero or more of any character" but also impacts the return value from CANMATCH and EARLYMATCH.

The extension match rules defined in the devmeeting 2006.05.05 are quite simple: WE SELECT THE LONGEST MATCH. In detail, "longest" means the number of matched characters in the extension. In case of ties (e.g. _XXX and 333) in the length of a pattern, we give priority to entries with the smallest cardinality (e.g, [5-9] comes before [2-8] before the former has only 5 elements, while the latter has 7, etc. In case of same cardinality, the first element in the range counts. If we still have a tie, any final '!' will make this as a possibly less specific pattern.

EBUSY - can't lock EEXIST - extension with the same priority exist and no replace is set

Main interface to add extensions to the list for out context.

Note:
For details about the arguments, check ast_add_extension()
Add an extension to an extension context, this time with an ast_context *.

We sort extensions in order of matching preference, so that we can stop the search as soon as we find a suitable match. This ordering also takes care of wildcards such as '.' (meaning "one or more of any character") and '!' (which is 'earlymatch', meaning "zero or more of any character" but also impacts the return value from CANMATCH and EARLYMATCH.

The extension match rules defined in the devmeeting 2006.05.05 are quite simple: WE SELECT THE LONGEST MATCH. In detail, "longest" means the number of matched characters in the extension. In case of ties (e.g. _XXX and 333) in the length of a pattern, we give priority to entries with the smallest cardinality (e.g, [5-9] comes before [2-8] before the former has only 5 elements, while the latter has 7, etc. In case of same cardinality, the first element in the range counts. If we still have a tie, any final '!' will make this as a possibly less specific pattern.

EBUSY - can't lock EEXIST - extension with the same priority exist and no replace is set

Definition at line 9951 of file pbx.c.

References ast_add_extension2_lockopt(), and localized_add_extension2().

09955 {
09956    return ast_add_extension2_lockopt(con, replace, extension, priority, label, callerid,
09957       application, data, datad, registrar, 1);
09958 }

int ast_add_profile ( const char *  x,
uint64_t  scale 
)

support for event profiling

allocates a counter with a given name and scale.

(note, this must be documented a lot more) ast_add_profile allocates a generic 'counter' with a given name, which can be shown with the command 'core show profile <name>'

The counter accumulates positive or negative values supplied by

See also:
ast_add_profile(), dividing them by the 'scale' value passed in the create call, and also counts the number of 'events'. Values can also be taked by the TSC counter on ia32 architectures, in which case you can mark the start of an event calling ast_mark(id, 1) and then the end of the event with ast_mark(id, 0). For non-i386 architectures, these two calls return 0.
support for event profiling

Returns:
Returns the identifier of the counter.

Definition at line 184 of file ael_main.c.

00185 {
00186    if (!no_comp)
00187       printf("Executed ast_add_profile();\n");
00188 
00189    return 0;
00190 }

void ast_cli_register_multiple ( void   ) 

Definition at line 211 of file ael_main.c.

00212 {
00213    if(!no_comp)
00214          printf("Executed ast_cli_register_multiple();\n");
00215 }

void ast_cli_unregister_multiple ( void   ) 

Definition at line 415 of file ael_main.c.

00416 {
00417    if(!no_comp)
00418       printf("Executed ast_cli_unregister_multiple();\n");
00419 }

void ast_context_add_ignorepat2 ( struct ast_context con,
const char *  value,
const char *  registrar 
)

Definition at line 9564 of file pbx.c.

09565 {
09566    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
09567    int length;
09568    char *pattern;
09569    length = sizeof(struct ast_ignorepat);
09570    length += strlen(value) + 1;
09571    if (!(ignorepat = ast_calloc(1, length)))
09572       return -1;
09573    /* The cast to char * is because we need to write the initial value.
09574     * The field is not supposed to be modified otherwise.  Also, gcc 4.2
09575     * sees the cast as dereferencing a type-punned pointer and warns about
09576     * it.  This is the workaround (we're telling gcc, yes, that's really
09577     * what we wanted to do).
09578     */
09579    pattern = (char *) ignorepat->pattern;
09580    strcpy(pattern, value);
09581    ignorepat->next = NULL;
09582    ignorepat->registrar = registrar;
09583    ast_wrlock_context(con);
09584    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
09585       ignorepatl = ignorepatc;
09586       if (!strcasecmp(ignorepatc->pattern, value)) {
09587          /* Already there */
09588          ast_unlock_context(con);
09589          ast_free(ignorepat);
09590          errno = EEXIST;
09591          return -1;
09592       }
09593    }
09594    if (ignorepatl)
09595       ignorepatl->next = ignorepat;
09596    else
09597       con->ignorepats = ignorepat;
09598    ast_unlock_context(con);
09599    return 0;
09600 
09601 }

void ast_context_add_include2 ( struct ast_context con,
const char *  value,
const char *  registrar 
)

Add a context include.

Parameters:
con context to add the include to
value include value to add
registrar who registered the context
Adds an include taking a struct ast_context as the first parameter

Return values:
0 on success
-1 on failure

Definition at line 9364 of file pbx.c.

09366 {
09367    struct ast_include *new_include;
09368    char *c;
09369    struct ast_include *i, *il = NULL; /* include, include_last */
09370    int length;
09371    char *p;
09372 
09373    length = sizeof(struct ast_include);
09374    length += 2 * (strlen(value) + 1);
09375 
09376    /* allocate new include structure ... */
09377    if (!(new_include = ast_calloc(1, length)))
09378       return -1;
09379    /* Fill in this structure. Use 'p' for assignments, as the fields
09380     * in the structure are 'const char *'
09381     */
09382    p = new_include->stuff;
09383    new_include->name = p;
09384    strcpy(p, value);
09385    p += strlen(value) + 1;
09386    new_include->rname = p;
09387    strcpy(p, value);
09388    /* Strip off timing info, and process if it is there */
09389    if ( (c = strchr(p, ',')) ) {
09390       *c++ = '\0';
09391       new_include->hastime = ast_build_timing(&(new_include->timing), c);
09392    }
09393    new_include->next      = NULL;
09394    new_include->registrar = registrar;
09395 
09396    ast_wrlock_context(con);
09397 
09398    /* ... go to last include and check if context is already included too... */
09399    for (i = con->includes; i; i = i->next) {
09400       if (!strcasecmp(i->name, new_include->name)) {
09401          ast_destroy_timing(&(new_include->timing));
09402          ast_free(new_include);
09403          ast_unlock_context(con);
09404          errno = EEXIST;
09405          return -1;
09406       }
09407       il = i;
09408    }
09409 
09410    /* ... include new context into context list, unlock, return */
09411    if (il)
09412       il->next = new_include;
09413    else
09414       con->includes = new_include;
09415    ast_verb(3, "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
09416 
09417    ast_unlock_context(con);
09418 
09419    return 0;
09420 }

void ast_context_add_switch2 ( struct ast_context con,
const char *  value,
const char *  data,
int  eval,
const char *  registrar 
)

Adds a switch (first param is a ast_context).

Note:
See ast_context_add_switch() for argument information, with the exception of the first argument. In this case, it's a pointer to an ast_context structure as opposed to the name.

Definition at line 9447 of file pbx.c.

09449 {
09450    struct ast_sw *new_sw;
09451    struct ast_sw *i;
09452    int length;
09453    char *p;
09454 
09455    length = sizeof(struct ast_sw);
09456    length += strlen(value) + 1;
09457    if (data)
09458       length += strlen(data);
09459    length++;
09460 
09461    /* allocate new sw structure ... */
09462    if (!(new_sw = ast_calloc(1, length)))
09463       return -1;
09464    /* ... fill in this structure ... */
09465    p = new_sw->stuff;
09466    new_sw->name = p;
09467    strcpy(new_sw->name, value);
09468    p += strlen(value) + 1;
09469    new_sw->data = p;
09470    if (data) {
09471       strcpy(new_sw->data, data);
09472       p += strlen(data) + 1;
09473    } else {
09474       strcpy(new_sw->data, "");
09475       p++;
09476    }
09477    new_sw->eval     = eval;
09478    new_sw->registrar = registrar;
09479 
09480    /* ... try to lock this context ... */
09481    ast_wrlock_context(con);
09482 
09483    /* ... go to last sw and check if context is already swd too... */
09484    AST_LIST_TRAVERSE(&con->alts, i, list) {
09485       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
09486          ast_free(new_sw);
09487          ast_unlock_context(con);
09488          errno = EEXIST;
09489          return -1;
09490       }
09491    }
09492 
09493    /* ... sw new context into context list, unlock, return */
09494    AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
09495 
09496    ast_verb(3, "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
09497 
09498    ast_unlock_context(con);
09499 
09500    return 0;
09501 }

struct ast_context * ast_context_create ( void **  extcontexts,
const char *  name,
const char *  registrar 
) [read]

Definition at line 325 of file ael_main.c.

References calloc, ast_context::name, ast_context::next, NULL, and ast_context::registrar.

00326 {
00327    struct ast_context *x = calloc(1, sizeof(*x));
00328    if (!x)
00329       return NULL;
00330    x->next = context_list;
00331    context_list = x;
00332    if (!no_comp)
00333       printf("Executed ast_context_create(conts, name=%s, registrar=%s);\n", name, registrar);
00334    conts++;
00335    strncpy(x->name, name, sizeof(x->name) - 1);
00336    strncpy(x->registrar, registrar, sizeof(x->registrar) - 1);
00337    return x;
00338 }

void ast_context_destroy ( void   ) 

Definition at line 421 of file ael_main.c.

00422 {
00423    if( !no_comp)
00424       printf("Executed ast_context_destroy();\n");
00425 }

struct ast_context * ast_context_find_or_create ( void **  extcontexts,
void *  tab,
const char *  name,
const char *  registrar 
) [read]

Definition at line 340 of file ael_main.c.

References calloc, ast_context::name, ast_context::next, NULL, and ast_context::registrar.

00341 {
00342    struct ast_context *x = calloc(1, sizeof(*x));
00343    if (!x)
00344       return NULL;
00345    x->next = context_list;
00346    context_list = x;
00347    if (!no_comp)
00348       printf("Executed ast_context_find_or_create(conts, name=%s, registrar=%s);\n", name, registrar);
00349    conts++;
00350    strncpy(x->name, name, sizeof(x->name) - 1);
00351    strncpy(x->registrar, registrar, sizeof(x->registrar) - 1);
00352    return x;
00353 }

void ast_context_verify_includes ( void   ) 

Definition at line 402 of file ael_main.c.

00403 {
00404    if(!no_comp)
00405       printf("Executed ast_context_verify_includes();\n");
00406 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  )  [read]

Definition at line 4019 of file pbx.c.

04020 {
04021    struct ast_custom_function *acf;
04022 
04023    AST_RWLIST_RDLOCK(&acf_root);
04024    acf = ast_custom_function_find_nolock(name);
04025    AST_RWLIST_UNLOCK(&acf_root);
04026 
04027    return acf;
04028 }

const char* ast_get_context_name ( struct ast_context con  ) 

Definition at line 12182 of file pbx.c.

12183 {
12184    return con ? con->name : NULL;
12185 }

int ast_hashtab_compare_contexts ( const void *  ah_a,
const void *  ah_b 
)

hashtable functions for contexts

Definition at line 1283 of file pbx.c.

01284 {
01285    const struct ast_context *ac = ah_a;
01286    const struct ast_context *bc = ah_b;
01287    if (!ac || !bc) /* safety valve, but it might prevent a crash you'd rather have happen */
01288       return 1;
01289    /* assume context names are registered in a string table! */
01290    return strcmp(ac->name, bc->name);
01291 }

unsigned int ast_hashtab_hash_contexts ( const void *  obj  ) 

Definition at line 1335 of file pbx.c.

01336 {
01337    const struct ast_context *ac = obj;
01338    return ast_hashtab_hash_string(ac->name);
01339 }

int ast_loader_register ( int(*)(void)  updater  ) 

Add a procedure to be run when modules have been updated.

Parameters:
updater The function to run when modules have been updated.
This function adds the given function to a linked list of functions to be run when the modules are updated.

Return values:
0 on success
-1 on failure.

Definition at line 193 of file ael_main.c.

00194 {
00195    return 1;
00196 }

int ast_loader_unregister ( int(*)(void)  updater  ) 

Remove a procedure to be run when modules are updated.

Parameters:
updater The updater function to unregister.
This removes the given function from the updater list.

Return values:
0 on success
-1 on failure.

Definition at line 198 of file ael_main.c.

00199 {
00200    return 1;
00201 }

void ast_log ( int  level,
const char *  file,
int  line,
const char *  function,
const char *  fmt,
  ... 
)

Used for sending a log message This is the standard logger function. Probably the only way you will invoke it would be something like this: ast_log(AST_LOG_WHATEVER, "Problem with the %s Captain. We should get some more. Will %d be enough?\n", "flux capacitor", 10); where WHATEVER is one of ERROR, DEBUG, EVENT, NOTICE, or WARNING depending on which log you wish to output to. These are implemented as macros, that will provide the function with the needed arguments.

Parameters:
level Type of log event
file Will be provided by the AST_LOG_* macro
line Will be provided by the AST_LOG_* macro
function Will be provided by the AST_LOG_* macro
fmt This is what is important. The format is the same as your favorite breed of printf. You know how that works, right? :-)

Definition at line 1707 of file logger.c.

01708 {
01709    ast_callid callid;
01710    va_list ap;
01711 
01712    callid = ast_read_threadstorage_callid();
01713 
01714    va_start(ap, fmt);
01715    if (level == __LOG_VERBOSE) {
01716       __ast_verbose_ap(file, line, function, 0, callid, fmt, ap);
01717    } else {
01718       ast_log_full(level, file, line, function, callid, fmt, ap);
01719    }
01720    va_end(ap);
01721 }

void ast_merge_contexts_and_delete ( void   ) 

Definition at line 396 of file ael_main.c.

00397 {
00398    if(!no_comp)
00399       printf("Executed ast_merge_contexts_and_delete();\n");
00400 }

void ast_module_register ( const struct ast_module_info x  ) 

Definition at line 202 of file ael_main.c.

00203 {
00204 }

void ast_module_unregister ( const struct ast_module_info x  ) 

Definition at line 206 of file ael_main.c.

00207 {
00208 }

char* ast_process_quotes_and_slashes ( char *  start,
char  find,
char  replace_with 
)

Process a string to find and replace characters.

Parameters:
start The string to analyze
find The character to find
replace_with The character that will replace the one we are looking for

Definition at line 1825 of file main/utils.c.

01826 {
01827    char *dataPut = start;
01828    int inEscape = 0;
01829    int inQuotes = 0;
01830 
01831    for (; *start; start++) {
01832       if (inEscape) {
01833          *dataPut++ = *start;       /* Always goes verbatim */
01834          inEscape = 0;
01835       } else {
01836          if (*start == '\\') {
01837             inEscape = 1;      /* Do not copy \ into the data */
01838          } else if (*start == '\'') {
01839             inQuotes = 1 - inQuotes;   /* Do not copy ' into the data */
01840          } else {
01841             /* Replace , with |, unless in quotes */
01842             *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
01843          }
01844       }
01845    }
01846    if (start != dataPut)
01847       *dataPut = 0;
01848    return dataPut;
01849 }

void ast_register_file_version ( const char *  file,
const char *  version 
)

Register the version of a source code file with the core.

Parameters:
file the source file name
version the version string (typically a SVN revision keyword string)
Returns:
nothing
This function should not be called directly, but instead the ASTERISK_FILE_VERSION macro should be used to register a file with the core.

Definition at line 36 of file ael_main.c.

References ast_calloc, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdupa, ast_strip(), and ast_strip_quoted().

00036 { }

void ast_unregister_file_version ( const char *  file  ) 

Unregister a source code file from the core.

Parameters:
file the source file name
Returns:
nothing
This function should not be called directly, but instead the ASTERISK_FILE_VERSION macro should be used to automatically unregister the file when the module is unloaded.

Definition at line 37 of file ael_main.c.

References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, file_version::file, and ast_atexit::list.

00037 { }

struct ast_exten* ast_walk_context_extensions ( struct ast_context con,
struct ast_exten exten 
) [read]

Definition at line 12288 of file pbx.c.

12290 {
12291    if (!exten)
12292       return con ? con->root : NULL;
12293    else
12294       return exten->next;
12295 }

struct ast_ignorepat* ast_walk_context_ignorepats ( struct ast_context con,
struct ast_ignorepat ip 
) [read]

Definition at line 12321 of file pbx.c.

12323 {
12324    if (!ip)
12325       return con ? con->ignorepats : NULL;
12326    else
12327       return ip->next;
12328 }

struct ast_include* ast_walk_context_includes ( struct ast_context con,
struct ast_include inc 
) [read]

Definition at line 12312 of file pbx.c.

12314 {
12315    if (!inc)
12316       return con ? con->includes : NULL;
12317    else
12318       return inc->next;
12319 }

struct ast_sw* ast_walk_context_switches ( struct ast_context con,
struct ast_sw sw 
) [read]

Definition at line 12297 of file pbx.c.

12299 {
12300    if (!sw)
12301       return con ? AST_LIST_FIRST(&con->alts) : NULL;
12302    else
12303       return AST_LIST_NEXT(sw, list);
12304 }

struct ast_context * ast_walk_contexts ( void   )  [read]

Definition at line 408 of file ael_main.c.

00409 {
00410    if(!no_comp)
00411       printf("Executed ast_walk_contexts();\n");
00412    return 0;
00413 }

struct namelist * create_name ( const char *  name  )  [read]

Definition at line 84 of file ael_main.c.

References calloc, namelist::name, and NULL.

Referenced by ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), and pbx_builtin_setvar().

00085 {
00086    struct namelist *x = calloc(1, sizeof(*x));
00087    if (!x)
00088       return NULL;
00089    strncpy(x->name, name, sizeof(x->name) - 1);
00090    return x;
00091 }

void destroy_namelist ( struct namelist x  ) 

Definition at line 72 of file ael_main.c.

References free, and namelist::next.

Referenced by main().

00073 {
00074    struct namelist *z,*z2;
00075    for(z=x; z; z = z2)
00076    {
00077       z2 = z->next;
00078       z->next = 0;
00079       free(z);
00080    }
00081 }

void filter_leading_space_from_exprs ( char *  str  ) 

Definition at line 457 of file ael_main.c.

Referenced by ast_add_extension2().

00458 {
00459    /*  Mainly for aesthetics */
00460    char *t, *v, *u = str;
00461    
00462    while ( u && *u ) {
00463 
00464       if( *u == '$' && *(u+1) == '[' ) {
00465          t = u+2;
00466          while( *t == '\n' || *t == '\r' || *t == '\t' || *t == ' ' ) {
00467             v = t;
00468             while ( *v ) {
00469                *v = *(v+1);
00470                v++;
00471             }
00472          }
00473       }
00474       
00475       u++;
00476    }
00477 }

void filter_newlines ( char *  str  ) 

Definition at line 479 of file ael_main.c.

Referenced by ast_add_extension2().

00480 {
00481    /* remove all newlines, returns  */
00482    char *t=str;
00483    while( t && *t ) {
00484       if( *t == '\n' || *t == '\r' ) {
00485          *t = ' '; /* just replace newlines and returns with spaces; they act as
00486                    token separators, and just blindly removing them could be
00487                    harmful. */
00488       }
00489       t++;
00490    }
00491 }

int main ( int  argc,
char **  argv 
)

Definition at line 498 of file ael_main.c.

References ael_external_load_module(), ast_log, destroy_namelist(), ast_context::eswitches, extens, ast_context::extension_count, free, ast_context::ignorepats, ast_context::includes, localized_use_conf_dir(), localized_use_local_dir(), namelist::name, ast_context::name, namelist::name2, namelist::next, ast_context::next, priors, and ast_context::switches.

00499 {
00500    int i;
00501    struct namelist *n;
00502    struct ast_context *lp,*lp2;
00503    
00504    for(i=1;i<argc;i++) {
00505       if( argv[i][0] == '-' && argv[i][1] == 'n' )
00506          no_comp =1;
00507       if( argv[i][0] == '-' && argv[i][1] == 'q' ) {
00508          quiet = 1;
00509          no_comp =1;
00510       }
00511       if( argv[i][0] == '-' && argv[i][1] == 'd' )
00512          use_curr_dir =1;
00513       if( argv[i][0] == '-' && argv[i][1] == 'w' )
00514          dump_extensions =1;
00515    }
00516    
00517    if( !quiet ) {
00518       printf("\n(If you find progress and other non-error messages irritating, you can use -q to suppress them)\n");
00519       if( !no_comp )
00520          printf("\n(You can use the -n option if you aren't interested in seeing all the instructions generated by the compiler)\n\n");
00521       if( !use_curr_dir )
00522          printf("\n(You can use the -d option if you want to use the current working directory as the CONFIG_DIR. I will look in this dir for extensions.ael* and its included files)\n\n");
00523       if( !dump_extensions )
00524          printf("\n(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)\n");
00525    }
00526 
00527    if( use_curr_dir ) {
00528       strcpy(config_dir, ".");
00529       localized_use_local_dir();
00530    }
00531    else {
00532       strcpy(config_dir, "/etc/asterisk");
00533       localized_use_conf_dir();
00534    }
00535    strcpy(var_dir, "/var/lib/asterisk");
00536    
00537    if( dump_extensions ) {
00538       dumpfile = fopen("extensions.conf.aeldump","w");
00539       if( !dumpfile ) {
00540          printf("\n\nSorry, cannot open extensions.conf.aeldump for writing! Correct the situation and try again!\n\n");
00541          exit(10);
00542       }
00543       
00544    }
00545 
00546    FIRST_TIME = 1;
00547    
00548    ael_external_load_module();
00549    
00550    ast_log(4, "ael2_parse", __LINE__, "main", "%d contexts, %d extensions, %d priorities\n", conts, extens, priors);
00551 
00552    if( dump_extensions && dumpfile ) {
00553    
00554       for( lp = context_list; lp; lp = lp->next ) { /* print out any contexts that didn't have any
00555                                            extensions in them */
00556          if( lp->extension_count == 0 ) {
00557             
00558             fprintf(dumpfile,"\n\n[%s]\n", lp->name);
00559             
00560             for(n=lp->ignorepats;n;n=n->next) {
00561                fprintf(dumpfile, "ignorepat => %s\n", n->name);
00562             }
00563             for(n=lp->includes;n;n=n->next) {
00564                fprintf(dumpfile, "include => %s\n", n->name);
00565             }
00566             for(n=lp->switches;n;n=n->next) {
00567                fprintf(dumpfile, "switch => %s/%s\n", n->name, n->name2);
00568             }
00569             for(n=lp->eswitches;n;n=n->next) {
00570                fprintf(dumpfile, "eswitch => %s/%s\n", n->name, n->name2);
00571             }
00572          }
00573       }
00574    }
00575    
00576    if( dump_extensions && dumpfile )
00577       fclose(dumpfile);
00578    
00579    for( lp = context_list; lp; lp = lp2 ) { /* free the ast_context structs */
00580       lp2 = lp->next;
00581       lp->next = 0;
00582 
00583       destroy_namelist(lp->includes);
00584       destroy_namelist(lp->ignorepats);
00585       destroy_namelist(lp->switches);
00586       destroy_namelist(lp->eswitches);
00587 
00588       free(lp);
00589    }
00590    
00591     return 0;
00592 }

void pbx_builtin_setvar ( void *  chan,
void *  data 
)

Definition at line 312 of file ael_main.c.

References ADD_LAST, and create_name().

00313 {
00314    struct namelist *x = create_name(data);
00315    if(!no_comp)
00316       printf("Executed pbx_builtin_setvar(chan, data=%s);\n", (char*)data);
00317 
00318    if( dump_extensions ) {
00319       x = create_name(data);
00320       ADD_LAST(globalvars,x);
00321    }
00322 }

struct ast_exten* pbx_find_extension ( struct ast_channel chan,
struct ast_context bypass,
struct pbx_find_info q,
const char *  context,
const char *  exten,
int  priority,
const char *  label,
const char *  callerid,
enum ext_match_t  action 
) [read]

Definition at line 3166 of file pbx.c.

03170 {
03171    int x, res;
03172    struct ast_context *tmp = NULL;
03173    struct ast_exten *e = NULL, *eroot = NULL;
03174    struct ast_include *i = NULL;
03175    struct ast_sw *sw = NULL;
03176    struct ast_exten pattern = {NULL, };
03177    struct scoreboard score = {0, };
03178    struct ast_str *tmpdata = NULL;
03179 
03180    pattern.label = label;
03181    pattern.priority = priority;
03182 #ifdef NEED_DEBUG_HERE
03183    ast_log(LOG_NOTICE, "Looking for cont/ext/prio/label/action = %s/%s/%d/%s/%d\n", context, exten, priority, label, (int) action);
03184 #endif
03185 
03186    /* Initialize status if appropriate */
03187    if (q->stacklen == 0) {
03188       q->status = STATUS_NO_CONTEXT;
03189       q->swo = NULL;
03190       q->data = NULL;
03191       q->foundcontext = NULL;
03192    } else if (q->stacklen >= AST_PBX_MAX_STACK) {
03193       ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
03194       return NULL;
03195    }
03196 
03197    /* Check first to see if we've already been checked */
03198    for (x = 0; x < q->stacklen; x++) {
03199       if (!strcasecmp(q->incstack[x], context))
03200          return NULL;
03201    }
03202 
03203    if (bypass) { /* bypass means we only look there */
03204       tmp = bypass;
03205    } else {      /* look in contexts */
03206       tmp = find_context(context);
03207       if (!tmp) {
03208          return NULL;
03209       }
03210    }
03211 
03212    if (q->status < STATUS_NO_EXTENSION)
03213       q->status = STATUS_NO_EXTENSION;
03214 
03215    /* Do a search for matching extension */
03216 
03217    eroot = NULL;
03218    score.total_specificity = 0;
03219    score.exten = 0;
03220    score.total_length = 0;
03221    if (!tmp->pattern_tree && tmp->root_table) {
03222       create_match_char_tree(tmp);
03223 #ifdef NEED_DEBUG
03224       ast_debug(1, "Tree Created in context %s:\n", context);
03225       log_match_char_tree(tmp->pattern_tree," ");
03226 #endif
03227    }
03228 #ifdef NEED_DEBUG
03229    ast_log(LOG_NOTICE, "The Trie we are searching in:\n");
03230    log_match_char_tree(tmp->pattern_tree, "::  ");
03231 #endif
03232 
03233    do {
03234       if (!ast_strlen_zero(overrideswitch)) {
03235          char *osw = ast_strdupa(overrideswitch), *name;
03236          struct ast_switch *asw;
03237          ast_switch_f *aswf = NULL;
03238          char *datap;
03239          int eval = 0;
03240 
03241          name = strsep(&osw, "/");
03242          asw = pbx_findswitch(name);
03243 
03244          if (!asw) {
03245             ast_log(LOG_WARNING, "No such switch '%s'\n", name);
03246             break;
03247          }
03248 
03249          if (osw && strchr(osw, '$')) {
03250             eval = 1;
03251          }
03252 
03253          if (eval && !(tmpdata = ast_str_thread_get(&switch_data, 512))) {
03254             ast_log(LOG_WARNING, "Can't evaluate overrideswitch?!\n");
03255             break;
03256          } else if (eval) {
03257             /* Substitute variables now */
03258             pbx_substitute_variables_helper(chan, osw, ast_str_buffer(tmpdata), ast_str_size(tmpdata));
03259             datap = ast_str_buffer(tmpdata);
03260          } else {
03261             datap = osw;
03262          }
03263 
03264          /* equivalent of extension_match_core() at the switch level */
03265          if (action == E_CANMATCH)
03266             aswf = asw->canmatch;
03267          else if (action == E_MATCHMORE)
03268             aswf = asw->matchmore;
03269          else /* action == E_MATCH */
03270             aswf = asw->exists;
03271          if (!aswf) {
03272             res = 0;
03273          } else {
03274             if (chan) {
03275                ast_autoservice_start(chan);
03276             }
03277             res = aswf(chan, context, exten, priority, callerid, datap);
03278             if (chan) {
03279                ast_autoservice_stop(chan);
03280             }
03281          }
03282          if (res) {  /* Got a match */
03283             q->swo = asw;
03284             q->data = datap;
03285             q->foundcontext = context;
03286             /* XXX keep status = STATUS_NO_CONTEXT ? */
03287             return NULL;
03288          }
03289       }
03290    } while (0);
03291 
03292    if (extenpatternmatchnew) {
03293       new_find_extension(exten, &score, tmp->pattern_tree, 0, 0, callerid, label, action);
03294       eroot = score.exten;
03295 
03296       if (score.last_char == '!' && action == E_MATCHMORE) {
03297          /* We match an extension ending in '!'.
03298           * The decision in this case is final and is NULL (no match).
03299           */
03300 #ifdef NEED_DEBUG_HERE
03301          ast_log(LOG_NOTICE,"Returning MATCHMORE NULL with exclamation point.\n");
03302 #endif
03303          return NULL;
03304       }
03305 
03306       if (!eroot && (action == E_CANMATCH || action == E_MATCHMORE) && score.canmatch_exten) {
03307          q->status = STATUS_SUCCESS;
03308 #ifdef NEED_DEBUG_HERE
03309          ast_log(LOG_NOTICE,"Returning CANMATCH exten %s\n", score.canmatch_exten->exten);
03310 #endif
03311          return score.canmatch_exten;
03312       }
03313 
03314       if ((action == E_MATCHMORE || action == E_CANMATCH)  && eroot) {
03315          if (score.node) {
03316             struct ast_exten *z = trie_find_next_match(score.node);
03317             if (z) {
03318 #ifdef NEED_DEBUG_HERE
03319                ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten %s\n", z->exten);
03320 #endif
03321             } else {
03322                if (score.canmatch_exten) {
03323 #ifdef NEED_DEBUG_HERE
03324                   ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE canmatchmatch exten %s(%p)\n", score.canmatch_exten->exten, score.canmatch_exten);
03325 #endif
03326                   return score.canmatch_exten;
03327                } else {
03328 #ifdef NEED_DEBUG_HERE
03329                   ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten NULL\n");
03330 #endif
03331                }
03332             }
03333             return z;
03334          }
03335 #ifdef NEED_DEBUG_HERE
03336          ast_log(LOG_NOTICE, "Returning CANMATCH/MATCHMORE NULL (no next_match)\n");
03337 #endif
03338          return NULL;  /* according to the code, complete matches are null matches in MATCHMORE mode */
03339       }
03340 
03341       if (eroot) {
03342          /* found entry, now look for the right priority */
03343          if (q->status < STATUS_NO_PRIORITY)
03344             q->status = STATUS_NO_PRIORITY;
03345          e = NULL;
03346          if (action == E_FINDLABEL && label ) {
03347             if (q->status < STATUS_NO_LABEL)
03348                q->status = STATUS_NO_LABEL;
03349             e = ast_hashtab_lookup(eroot->peer_label_table, &pattern);
03350          } else {
03351             e = ast_hashtab_lookup(eroot->peer_table, &pattern);
03352          }
03353          if (e) { /* found a valid match */
03354             q->status = STATUS_SUCCESS;
03355             q->foundcontext = context;
03356 #ifdef NEED_DEBUG_HERE
03357             ast_log(LOG_NOTICE,"Returning complete match of exten %s\n", e->exten);
03358 #endif
03359             return e;
03360          }
03361       }
03362    } else {   /* the old/current default exten pattern match algorithm */
03363 
03364       /* scan the list trying to match extension and CID */
03365       eroot = NULL;
03366       while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) {
03367          int match = extension_match_core(eroot->exten, exten, action);
03368          /* 0 on fail, 1 on match, 2 on earlymatch */
03369 
03370          if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid)))
03371             continue;   /* keep trying */
03372          if (match == 2 && action == E_MATCHMORE) {
03373             /* We match an extension ending in '!'.
03374              * The decision in this case is final and is NULL (no match).
03375              */
03376             return NULL;
03377          }
03378          /* found entry, now look for the right priority */
03379          if (q->status < STATUS_NO_PRIORITY)
03380             q->status = STATUS_NO_PRIORITY;
03381          e = NULL;
03382          if (action == E_FINDLABEL && label ) {
03383             if (q->status < STATUS_NO_LABEL)
03384                q->status = STATUS_NO_LABEL;
03385             e = ast_hashtab_lookup(eroot->peer_label_table, &pattern);
03386          } else {
03387             e = ast_hashtab_lookup(eroot->peer_table, &pattern);
03388          }
03389          if (e) { /* found a valid match */
03390             q->status = STATUS_SUCCESS;
03391             q->foundcontext = context;
03392             return e;
03393          }
03394       }
03395    }
03396 
03397    /* Check alternative switches */
03398    AST_LIST_TRAVERSE(&tmp->alts, sw, list) {
03399       struct ast_switch *asw = pbx_findswitch(sw->name);
03400       ast_switch_f *aswf = NULL;
03401       char *datap;
03402 
03403       if (!asw) {
03404          ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name);
03405          continue;
03406       }
03407 
03408       /* Substitute variables now */
03409       if (sw->eval) {
03410          if (!(tmpdata = ast_str_thread_get(&switch_data, 512))) {
03411             ast_log(LOG_WARNING, "Can't evaluate switch?!\n");
03412             continue;
03413          }
03414          pbx_substitute_variables_helper(chan, sw->data, ast_str_buffer(tmpdata), ast_str_size(tmpdata));
03415       }
03416 
03417       /* equivalent of extension_match_core() at the switch level */
03418       if (action == E_CANMATCH)
03419          aswf = asw->canmatch;
03420       else if (action == E_MATCHMORE)
03421          aswf = asw->matchmore;
03422       else /* action == E_MATCH */
03423          aswf = asw->exists;
03424       datap = sw->eval ? ast_str_buffer(tmpdata) : sw->data;
03425       if (!aswf)
03426          res = 0;
03427       else {
03428          if (chan)
03429             ast_autoservice_start(chan);
03430          res = aswf(chan, context, exten, priority, callerid, datap);
03431          if (chan)
03432             ast_autoservice_stop(chan);
03433       }
03434       if (res) {  /* Got a match */
03435          q->swo = asw;
03436          q->data = datap;
03437          q->foundcontext = context;
03438          /* XXX keep status = STATUS_NO_CONTEXT ? */
03439          return NULL;
03440       }
03441    }
03442    q->incstack[q->stacklen++] = tmp->name;   /* Setup the stack */
03443    /* Now try any includes we have in this context */
03444    for (i = tmp->includes; i; i = i->next) {
03445       if (include_valid(i)) {
03446          if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action))) {
03447 #ifdef NEED_DEBUG_HERE
03448             ast_log(LOG_NOTICE,"Returning recursive match of %s\n", e->exten);
03449 #endif
03450             return e;
03451          }
03452          if (q->swo)
03453             return NULL;
03454       }
03455    }
03456    return NULL;
03457 }

struct ast_app* pbx_findapp ( const char *  app  )  [read]

Look up an application.

Parameters:
app name of the app
This function searches for the ast_app structure within the apps that are registered for the one with the name you passed in.

Returns:
the ast_app structure that matches on success, or NULL on failure

Definition at line 1693 of file pbx.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, and pbx_findapp_nolock().

01694 {
01695    struct ast_app *ret;
01696 
01697    AST_RWLIST_RDLOCK(&apps);
01698    ret = pbx_findapp_nolock(app);
01699    AST_RWLIST_UNLOCK(&apps);
01700 
01701    return ret;
01702 }

void pbx_substitute_variables_helper ( struct ast_channel c,
const char *  cp1,
char *  cp2,
int  count 
)

Definition at line 4839 of file pbx.c.

04840 {
04841    size_t used;
04842    pbx_substitute_variables_helper_full(c, (c) ? ast_channel_varshead(c) : NULL, cp1, cp2, count, &used);
04843 }


Variable Documentation

Definition at line 103 of file ael_main.c.

char config_dir[PATH_MAX] [static]

Definition at line 101 of file ael_main.c.

Definition at line 93 of file ael_main.c.

int conts = 0

Definition at line 98 of file ael_main.c.

int dump_extensions = 0 [static]

Definition at line 131 of file ael_main.c.

FILE* dumpfile [static]

Definition at line 133 of file ael_main.c.

int extens = 0

Definition at line 98 of file ael_main.c.

Referenced by ast_add_extension2(), and main().

int FIRST_TIME = 0 [static]

Definition at line 132 of file ael_main.c.

Definition at line 95 of file ael_main.c.

Definition at line 96 of file ael_main.c.

Definition at line 94 of file ael_main.c.

char last_exten[18000]

Definition at line 99 of file ael_main.c.

struct module_symbols mod_data

int no_comp = 0 [static]

Definition at line 129 of file ael_main.c.

int priors = 0

Definition at line 98 of file ael_main.c.

Referenced by ast_add_extension2(), and main().

int quiet = 0 [static]

Definition at line 128 of file ael_main.c.

Referenced by confbridge_exec().

int use_curr_dir = 0 [static]

Definition at line 130 of file ael_main.c.

char var_dir[PATH_MAX] [static]

Definition at line 102 of file ael_main.c.


Generated on Thu Apr 16 06:28:11 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6