mirror of https://github.com/asterisk/asterisk
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@79623 65c4cc65-6c06-0410-ace0-fbb531ad65f31.6.0
parent
eaeec33a5c
commit
918348f03c
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Asterisk -- An open source telephony toolkit.
|
||||
*
|
||||
* Copyright (C) 2007, Digium, Inc.
|
||||
*
|
||||
* Steve Murphy <murf@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2. See the LICENSE file
|
||||
* at the top of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef _ASTERISK_EXTCONF_H
|
||||
#define _ASTERISK_EXTCONF_H
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef NOTYET
|
||||
/* I'm going to define all the structs mentioned below, to avoid
|
||||
possible conflicts in declarations that might be introduced,
|
||||
if we just include the files that define them-- this may be
|
||||
unnecessary */
|
||||
|
||||
struct ast_comment {
|
||||
struct ast_comment *next;
|
||||
char cmt[0];
|
||||
};
|
||||
|
||||
struct ast_variable {
|
||||
char *name;
|
||||
char *value;
|
||||
int lineno;
|
||||
int object; /*!< 0 for variable, 1 for object */
|
||||
int blanklines; /*!< Number of blanklines following entry */
|
||||
struct ast_comment *precomments;
|
||||
struct ast_comment *sameline;
|
||||
struct ast_variable *next;
|
||||
char stuff[0];
|
||||
};
|
||||
|
||||
struct ast_category {
|
||||
char name[80];
|
||||
int ignored; /*!< do not let user of the config see this category */
|
||||
int include_level;
|
||||
struct ast_comment *precomments;
|
||||
struct ast_comment *sameline;
|
||||
struct ast_variable *root;
|
||||
struct ast_variable *last;
|
||||
struct ast_category *next;
|
||||
};
|
||||
|
||||
struct ast_config {
|
||||
struct ast_category *root;
|
||||
struct ast_category *last;
|
||||
struct ast_category *current;
|
||||
struct ast_category *last_browse; /*!< used to cache the last category supplied via category_browse */
|
||||
int include_level;
|
||||
int max_include_level;
|
||||
};
|
||||
|
||||
/* ================== above: the config world; below, the dialplan world */
|
||||
|
||||
/*! \brief ast_app: A registered application */
|
||||
struct ast_app {
|
||||
int (*execute)(struct ast_channel *chan, void *data);
|
||||
const char *synopsis; /*!< Synopsis text for 'show applications' */
|
||||
const char *description; /*!< Description (help text) for 'show application <name>' */
|
||||
AST_RWLIST_ENTRY(ast_app) list; /*!< Next app in list */
|
||||
void *module; /*!< Module this app belongs to */
|
||||
char name[0]; /*!< Name of the application */
|
||||
};
|
||||
/*!
|
||||
\brief ast_exten: An extension
|
||||
The dialplan is saved as a linked list with each context
|
||||
having it's own linked list of extensions - one item per
|
||||
priority.
|
||||
*/
|
||||
struct ast_exten {
|
||||
char *exten; /*!< Extension name */
|
||||
int matchcid; /*!< Match caller id ? */
|
||||
const char *cidmatch; /*!< Caller id to match for this extension */
|
||||
int priority; /*!< Priority */
|
||||
const char *label; /*!< Label */
|
||||
struct ast_context *parent; /*!< The context this extension belongs to */
|
||||
const char *app; /*!< Application to execute */
|
||||
struct ast_app *cached_app; /*!< Cached location of application */
|
||||
void *data; /*!< Data to use (arguments) */
|
||||
void (*datad)(void *); /*!< Data destructor */
|
||||
struct ast_exten *peer; /*!< Next higher priority with our extension */
|
||||
const char *registrar; /*!< Registrar */
|
||||
struct ast_exten *next; /*!< Extension with a greater ID */
|
||||
char stuff[0];
|
||||
};
|
||||
/* from pbx.h */
|
||||
typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data);
|
||||
struct ast_timing {
|
||||
int hastime; /*!< If time construct exists */
|
||||
unsigned int monthmask; /*!< Mask for month */
|
||||
unsigned int daymask; /*!< Mask for date */
|
||||
unsigned int dowmask; /*!< Mask for day of week (mon-sun) */
|
||||
unsigned int minmask[24]; /*!< Mask for minute */
|
||||
};
|
||||
/*! \brief ast_include: include= support in extensions.conf */
|
||||
struct ast_include {
|
||||
const char *name;
|
||||
const char *rname; /*!< Context to include */
|
||||
const char *registrar; /*!< Registrar */
|
||||
int hastime; /*!< If time construct exists */
|
||||
struct ast_timing timing; /*!< time construct */
|
||||
struct ast_include *next; /*!< Link them together */
|
||||
char stuff[0];
|
||||
};
|
||||
|
||||
/*! \brief ast_sw: Switch statement in extensions.conf */
|
||||
struct ast_sw {
|
||||
char *name;
|
||||
const char *registrar; /*!< Registrar */
|
||||
char *data; /*!< Data load */
|
||||
int eval;
|
||||
AST_LIST_ENTRY(ast_sw) list;
|
||||
char *tmpdata;
|
||||
char stuff[0];
|
||||
};
|
||||
|
||||
*! \brief ast_ignorepat: Ignore patterns in dial plan */
|
||||
struct ast_ignorepat {
|
||||
const char *registrar;
|
||||
struct ast_ignorepat *next;
|
||||
const char pattern[0];
|
||||
};
|
||||
|
||||
/*! \brief ast_context: An extension context */
|
||||
struct ast_context {
|
||||
ast_rwlock_t lock; /*!< A lock to prevent multiple threads from clobbering the context */
|
||||
struct ast_exten *root; /*!< The root of the list of extensions */
|
||||
struct ast_context *next; /*!< Link them together */
|
||||
struct ast_include *includes; /*!< Include other contexts */
|
||||
struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
|
||||
const char *registrar; /*!< Registrar */
|
||||
AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
|
||||
ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
|
||||
char name[0]; /*!< Name of the context */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
struct ast_config *localized_config_load(const char *filename);
|
||||
struct ast_config *localized_config_load_with_comments(const char *filename);
|
||||
struct ast_category *localized_category_get(const struct ast_config *config, const char *category_name);
|
||||
int localized_config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator);
|
||||
struct ast_context *localized_walk_contexts(struct ast_context *con);
|
||||
struct ast_exten *localized_walk_context_extensions(struct ast_context *con,
|
||||
struct ast_exten *exten);
|
||||
struct ast_exten *localized_walk_extension_priorities(struct ast_exten *exten,
|
||||
struct ast_exten *priority);
|
||||
struct ast_include *localized_walk_context_includes(struct ast_context *con,
|
||||
struct ast_include *inc);
|
||||
struct ast_sw *localized_walk_context_switches(struct ast_context *con,
|
||||
struct ast_sw *sw);
|
||||
|
||||
void localized_context_destroy(struct ast_context *con, const char *registrar);
|
||||
int localized_pbx_load_module(void);
|
||||
|
||||
struct ast_context *localized_context_create(struct ast_context **extcontexts, const char *name, const char *registrar);
|
||||
int localized_pbx_builtin_setvar(struct ast_channel *chan, void *data);
|
||||
int localized_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar);
|
||||
int localized_context_add_switch2(struct ast_context *con, const char *value,
|
||||
const char *data, int eval, const char *registrar);
|
||||
int localized_context_add_include2(struct ast_context *con, const char *value,
|
||||
const char *registrar);
|
||||
int localized_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);
|
||||
void localized_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar);
|
||||
int localized_context_verify_includes(struct ast_context *con);
|
||||
void localized_use_conf_dir(void);
|
||||
void localized_use_local_dir(void);
|
||||
|
||||
|
||||
#ifndef _ASTERISK_PBX_H
|
||||
/*!
|
||||
* When looking up extensions, we can have different requests
|
||||
* identified by the 'action' argument, as follows.
|
||||
* Note that the coding is such that the low 4 bits are the
|
||||
* third argument to extension_match_core.
|
||||
*/
|
||||
enum ext_match_t {
|
||||
E_MATCHMORE = 0x00, /* extension can match but only with more 'digits' */
|
||||
E_CANMATCH = 0x01, /* extension can match with or without more 'digits' */
|
||||
E_MATCH = 0x02, /* extension is an exact match */
|
||||
E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */
|
||||
E_SPAWN = 0x12, /* want to spawn an extension. Requires exact match */
|
||||
E_FINDLABEL = 0x22 /* returns the priority for a given label. Requires exact match */
|
||||
};
|
||||
#define AST_PBX_MAX_STACK 128
|
||||
|
||||
/* request and result for pbx_find_extension */
|
||||
struct pbx_find_info {
|
||||
#if 0
|
||||
const char *context;
|
||||
const char *exten;
|
||||
int priority;
|
||||
#endif
|
||||
|
||||
char *incstack[AST_PBX_MAX_STACK]; /* filled during the search */
|
||||
int stacklen; /* modified during the search */
|
||||
int status; /* set on return */
|
||||
struct ast_switch *swo; /* set on return */
|
||||
const char *data; /* set on return */
|
||||
const char *foundcontext; /* set on return */
|
||||
};
|
||||
|
||||
#define STATUS_NO_CONTEXT 1
|
||||
#define STATUS_NO_EXTENSION 2
|
||||
#define STATUS_NO_PRIORITY 3
|
||||
#define STATUS_NO_LABEL 4
|
||||
#define STATUS_SUCCESS 5
|
||||
|
||||
#endif
|
||||
|
||||
struct ast_exten *localized_find_extension(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);
|
||||
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ASTERISK_PBX_H */
|
@ -0,0 +1,272 @@
|
||||
#ifndef _ASTERISK_PVAL_H
|
||||
#define _ASTERISK_PVAL_H
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PV_WORD, /* an ident, string, name, label, etc. A user-supplied string. */ /* 0 */
|
||||
PV_MACRO, /* 1 */
|
||||
PV_CONTEXT, /* 2 */
|
||||
PV_MACRO_CALL, /* 3 */
|
||||
PV_APPLICATION_CALL, /* 4 */
|
||||
PV_CASE, /* 5 */
|
||||
PV_PATTERN, /* 6 */
|
||||
PV_DEFAULT, /* 7 */
|
||||
PV_CATCH, /* 8 */
|
||||
PV_SWITCHES, /* 9 */
|
||||
PV_ESWITCHES, /* 10 */
|
||||
PV_INCLUDES, /* 11 */
|
||||
PV_STATEMENTBLOCK, /* 12 */
|
||||
PV_VARDEC, /* you know, var=val; */ /* 13 */
|
||||
PV_GOTO, /* 14 */
|
||||
PV_LABEL, /* 15 */
|
||||
PV_FOR, /* 16 */
|
||||
PV_WHILE, /* 17 */
|
||||
PV_BREAK, /* 18 */
|
||||
PV_RETURN, /* 19 */
|
||||
PV_CONTINUE, /* 20 */
|
||||
PV_IF, /* 21 */
|
||||
PV_IFTIME, /* 22 */
|
||||
PV_RANDOM, /* 23 */
|
||||
PV_SWITCH, /* 24 */
|
||||
PV_EXTENSION, /* 25 */
|
||||
PV_IGNOREPAT, /* 26 */
|
||||
PV_GLOBALS, /* 27 */
|
||||
PV_LOCALVARDEC, /* 28 */
|
||||
} pvaltype;
|
||||
|
||||
/* why this horrible mess? It's always been a tradeoff-- tons of structs,
|
||||
each storing it's specific lists of goodies, or a 'simple' single struct,
|
||||
with lots of fields, that catches all uses at once. Either you have a long
|
||||
list of struct names and subnames, or you have a long list of field names,
|
||||
and where/how they are used. I'm going with a single struct, using unions
|
||||
to reduce storage. Some simple generalizations, and a long list of types,
|
||||
and a book about what is used with what types.... Sorry!
|
||||
*/
|
||||
|
||||
struct pval
|
||||
{
|
||||
pvaltype type;
|
||||
int startline;
|
||||
int endline;
|
||||
int startcol;
|
||||
int endcol;
|
||||
char *filename;
|
||||
|
||||
union
|
||||
{
|
||||
char *str; /* wow, used almost everywhere! */
|
||||
struct pval *list; /* used in SWITCHES, ESWITCHES, INCLUDES, STATEMENTBLOCK, GOTO */
|
||||
struct pval *statements;/* used in EXTENSION */
|
||||
char *for_init; /* used in FOR */
|
||||
} u1;
|
||||
struct pval *u1_last; /* to build in-order lists -- looks like we only need one */
|
||||
|
||||
union
|
||||
{
|
||||
struct pval *arglist; /* used in macro_call, application_call, MACRO def, also attached to PWORD, the 4 timevals for includes */
|
||||
struct pval *statements; /* used in case, default, catch, while's statement, CONTEXT elements, GLOBALS */
|
||||
char *val; /* used in VARDEC */
|
||||
char *for_test; /* used in FOR */
|
||||
int label_in_case; /* a boolean for LABELs */
|
||||
struct pval *goto_target; /* used in GOTO */
|
||||
} u2;
|
||||
|
||||
union
|
||||
{
|
||||
char *for_inc; /* used in FOR */
|
||||
struct pval *else_statements; /* used in IF */
|
||||
struct pval *macro_statements; /* used in MACRO */
|
||||
int abstract; /* used for context */
|
||||
char *hints; /* used in EXTENSION */
|
||||
int goto_target_in_case; /* used in GOTO */
|
||||
struct ael_extension *compiled_label;
|
||||
} u3;
|
||||
|
||||
union
|
||||
{
|
||||
struct pval *for_statements; /* used in PV_FOR */
|
||||
int regexten; /* used in EXTENSION */
|
||||
} u4;
|
||||
|
||||
struct pval *next; /* the pval at the end of this ptr will ALWAYS be of the same type as this one!
|
||||
EXCEPT for objects of the different types, that are in the same list, like contexts & macros, etc */
|
||||
|
||||
struct pval *dad; /* the 'container' of this struct instance */
|
||||
struct pval *prev; /* the opposite of the 'next' pointer */
|
||||
} ;
|
||||
|
||||
|
||||
typedef struct pval pval;
|
||||
|
||||
#ifndef AAL_ARGCHECK
|
||||
/* for the time being, short circuit all the AAL related structures
|
||||
without permanently removing the code; after/during the AAL
|
||||
development, this code can be properly re-instated
|
||||
*/
|
||||
|
||||
/* null definitions for structs passed down the infrastructure */
|
||||
struct argapp
|
||||
{
|
||||
struct argapp *next;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
struct ast_context;
|
||||
|
||||
#ifdef AAL_ARGCHECK
|
||||
int option_matches_j( struct argdesc *should, pval *is, struct argapp *app);
|
||||
int option_matches( struct argdesc *should, pval *is, struct argapp *app);
|
||||
int ael_is_funcname(char *name);
|
||||
#endif
|
||||
|
||||
int do_pbx_load_module(void);
|
||||
int count_labels_in_current_context(char *label);
|
||||
int check_app_args(pval *appcall, pval *arglist, struct argapp *app);
|
||||
void check_pval(pval *item, struct argapp *apps, int in_globals);
|
||||
void check_pval_item(pval *item, struct argapp *apps, int in_globals);
|
||||
void check_switch_expr(pval *item, struct argapp *apps);
|
||||
void ast_expr_register_extra_error_info(char *errmsg);
|
||||
void ast_expr_clear_extra_error_info(void);
|
||||
int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan);
|
||||
struct pval *find_macro(char *name);
|
||||
struct pval *find_context(char *name);
|
||||
struct pval *find_context(char *name);
|
||||
struct pval *find_macro(char *name);
|
||||
struct ael_priority *new_prio(void);
|
||||
struct ael_extension *new_exten(void);
|
||||
void linkprio(struct ael_extension *exten, struct ael_priority *prio);
|
||||
void destroy_extensions(struct ael_extension *exten);
|
||||
/* static void linkexten(struct ael_extension *exten, struct ael_extension *add);
|
||||
static void gen_prios(struct ael_extension *exten, char *label, pval *statement, struct ael_extension *mother_exten, struct ast_context *context ); */
|
||||
void set_priorities(struct ael_extension *exten);
|
||||
void add_extensions(struct ael_extension *exten);
|
||||
void ast_compile_ael2(struct ast_context **local_contexts, struct pval *root);
|
||||
void destroy_pval(pval *item);
|
||||
void destroy_pval_item(pval *item);
|
||||
int is_float(char *arg );
|
||||
int is_int(char *arg );
|
||||
int is_empty(char *arg);
|
||||
|
||||
/* PVAL PI */
|
||||
|
||||
|
||||
pval *pvalCreateNode( pvaltype type );
|
||||
pvaltype pvalObjectGetType( pval *p );
|
||||
|
||||
void pvalWordSetString( pval *p, char *str);
|
||||
char *pvalWordGetString( pval *p );
|
||||
|
||||
void pvalMacroSetName( pval *p, char *name);
|
||||
char *pvalMacroGetName( pval *p );
|
||||
void pvalMacroSetArglist( pval *p, pval *arglist );
|
||||
void pvalMacroAddArg( pval *p, pval *arg );
|
||||
pval *pvalMacroWalkArgs( pval *p, pval **arg );
|
||||
void pvalMacroAddStatement( pval *p, pval *statement );
|
||||
pval *pvalMacroWalkStatements( pval *p, pval **next_statement );
|
||||
|
||||
void pvalContextSetName( pval *p, char *name);
|
||||
char *pvalContextGetName( pval *p );
|
||||
void pvalContextSetAbstract( pval *p );
|
||||
void pvalContextUnsetAbstract( pval *p );
|
||||
int pvalContextGetAbstract( pval *p );
|
||||
void pvalContextAddStatement( pval *p, pval *statement);
|
||||
pval *pvalContextWalkStatements( pval *p, pval **statements );
|
||||
|
||||
void pvalMacroCallSetMacroName( pval *p, char *name );
|
||||
char* pvalMacroCallGetMacroName( pval *p );
|
||||
void pvalMacroCallSetArglist( pval *p, pval *arglist );
|
||||
void pvalMacroCallAddArg( pval *p, pval *arg );
|
||||
pval *pvalMacroCallWalkArgs( pval *p, pval **args );
|
||||
|
||||
void pvalAppCallSetAppName( pval *p, char *name );
|
||||
char* pvalAppCallGetAppName( pval *p );
|
||||
void pvalAppCallSetArglist( pval *p, pval *arglist );
|
||||
void pvalAppCallAddArg( pval *p, pval *arg );
|
||||
pval *pvalAppCallWalkArgs( pval *p, pval **args );
|
||||
|
||||
void pvalCasePatSetVal( pval *p, char *val );
|
||||
char* pvalCasePatGetVal( pval *p );
|
||||
void pvalCasePatDefAddStatement( pval *p, pval *statement );
|
||||
pval *pvalCasePatDefWalkStatements( pval *p, pval **statement );
|
||||
|
||||
void pvalCatchSetExtName( pval *p, char *name );
|
||||
char* pvalCatchGetExtName( pval *p );
|
||||
void pvalCatchSetStatement( pval *p, pval *statement );
|
||||
pval *pvalCatchGetStatement( pval *p );
|
||||
|
||||
void pvalSwitchesAddSwitch( pval *p, char *name );
|
||||
char* pvalSwitchesWalkNames( pval *p, pval **next_item );
|
||||
void pvalESwitchesAddSwitch( pval *p, char *name );
|
||||
char* pvalESwitchesWalkNames( pval *p, pval **next_item );
|
||||
|
||||
void pvalIncludesAddInclude( pval *p, const char *include );
|
||||
|
||||
void pvalIncludesAddIncludeWithTimeConstraints( pval *p, const char *include, char *hour_range, char *dom_range, char *dow_range, char *month_range );
|
||||
void pvalIncludeGetTimeConstraints( pval *p, char **hour_range, char **dom_range, char **dow_range, char **month_range );
|
||||
char* pvalIncludesWalk( pval *p, pval **next_item );
|
||||
|
||||
void pvalStatementBlockAddStatement( pval *p, pval *statement);
|
||||
pval *pvalStatementBlockWalkStatements( pval *p, pval **next_statement);
|
||||
|
||||
void pvalVarDecSetVarname( pval *p, char *name );
|
||||
void pvalVarDecSetValue( pval *p, char *value );
|
||||
char* pvalVarDecGetVarname( pval *p );
|
||||
char* pvalVarDecGetValue( pval *p );
|
||||
|
||||
void pvalGotoSetTarget( pval *p, char *context, char *exten, char *label );
|
||||
void pvalGotoGetTarget( pval *p, char **context, char **exten, char **label );
|
||||
|
||||
void pvalLabelSetName( pval *p, char *name );
|
||||
char* pvalLabelGetName( pval *p );
|
||||
|
||||
void pvalForSetInit( pval *p, char *init );
|
||||
void pvalForSetTest( pval *p, char *test );
|
||||
void pvalForSetInc( pval *p, char *inc );
|
||||
void pvalForSetStatement( pval *p, pval *statement );
|
||||
char* pvalForGetInit( pval *p );
|
||||
char* pvalForGetTest( pval *p );
|
||||
char* pvalForGetInc( pval *p );
|
||||
pval* pvalForGetStatement( pval *p );
|
||||
|
||||
|
||||
void pvalIfSetCondition( pval *p, char *expr );
|
||||
char* pvalIfGetCondition( pval *p );
|
||||
void pvalIfTimeSetCondition( pval *p, char *hour_range, char *dow_range, char *dom_range, char *mon_range ); /* time range format: 24-hour format begin-end|dow range|dom range|month range */
|
||||
void pvalIfTimeGetCondition( pval *p, char **hour_range, char **dow_range, char **dom_range, char **month_range );
|
||||
void pvalRandomSetCondition( pval *p, char *percent );
|
||||
char* pvalRandomGetCondition( pval *p );
|
||||
void pvalConditionalSetThenStatement( pval *p, pval *statement );
|
||||
void pvalConditionalSetElseStatement( pval *p, pval *statement );
|
||||
pval* pvalConditionalGetThenStatement( pval *p );
|
||||
pval* pvalConditionalGetElseStatement( pval *p );
|
||||
|
||||
void pvalSwitchSetTestexpr( pval *p, char *expr );
|
||||
char* pvalSwitchGetTestexpr( pval *p );
|
||||
void pvalSwitchAddCase( pval *p, pval *Case );
|
||||
pval* pvalSwitchWalkCases( pval *p, pval **next_case );
|
||||
|
||||
void pvalExtenSetName( pval *p, char *name );
|
||||
char *pvalExtenGetName( pval *p );
|
||||
void pvalExtenSetRegexten( pval *p );
|
||||
void pvalExtenUnSetRegexten( pval *p );
|
||||
int pvalExtenGetRegexten( pval *p );
|
||||
void pvalExtenSetHints( pval *p, char *hints );
|
||||
char* pvalExtenGetHints( pval *p );
|
||||
void pvalExtenSetStatement( pval *p, pval *statement );
|
||||
pval* pvalExtenGetStatement( pval *p );
|
||||
|
||||
void pvalIgnorePatSetPattern( pval *p, char *pat );
|
||||
char* pvalIgnorePatGetPattern( pval *p );
|
||||
|
||||
void pvalGlobalsAddStatement( pval *p, pval *statement );
|
||||
pval* pvalGlobalsWalkStatements( pval *p, pval **next_statement );
|
||||
|
||||
void pvalTopLevAddObject( pval *p, pval *contextOrObj );
|
||||
pval* pvalTopLevWalkObjects( pval *p, pval **next_obj );
|
||||
|
||||
int pvalCheckType( pval *p, char *funcname, pvaltype type );
|
||||
|
||||
|
||||
#endif
|
@ -0,0 +1,685 @@
|
||||
/*
|
||||
* Asterisk -- An open source telephony toolkit.
|
||||
*
|
||||
* Copyright (C) 2006, Digium, Inc.
|
||||
*
|
||||
* Steve Murphy <murf@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2. See the LICENSE file
|
||||
* at the top of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Reverse compile extensions.conf code into prototype AEL code
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "asterisk/autoconfig.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <ctype.h>
|
||||
#if !defined(SOLARIS) && !defined(__CYGWIN__)
|
||||
#include <err.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <regex.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "asterisk/compat.h"
|
||||
#include "asterisk/pbx.h"
|
||||
#include "asterisk/ast_expr.h"
|
||||
#include "asterisk/channel.h"
|
||||
#include "asterisk/chanvars.h"
|
||||
#include "asterisk/module.h"
|
||||
#include "asterisk/app.h"
|
||||
#include "asterisk/config.h"
|
||||
#include "asterisk/options.h"
|
||||
#include "asterisk/callerid.h"
|
||||
#include "asterisk/ael_structs.h"
|
||||
#include "asterisk/devicestate.h"
|
||||
#include "asterisk/stringfields.h"
|
||||
#include "asterisk/ael_structs.h"
|
||||
#include "asterisk/pval.h"
|
||||
#include "asterisk/extconf.h"
|
||||
|
||||
void get_start_stop(unsigned int *word, int bitsperword, int totalbits, int *start, int *end);
|
||||
int all_bits_set(unsigned int *word, int bitsperword, int totalbits);
|
||||
void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
|
||||
{
|
||||
va_list vars;
|
||||
va_start(vars,fmt);
|
||||
|
||||
printf("LOG: lev:%d file:%s line:%d func: %s ",
|
||||
level, file, line, function);
|
||||
vprintf(fmt, vars);
|
||||
fflush(stdout);
|
||||
va_end(vars);
|
||||
}
|
||||
|
||||
extern char *days[];
|
||||
extern char *months[];
|
||||
char ast_config_AST_CONFIG_DIR[PATH_MAX];
|
||||
|
||||
char *config = "extensions.conf";
|
||||
|
||||
/*
|
||||
static char *registrar = "conf2ael";
|
||||
static char userscontext[AST_MAX_EXTENSION] = "default";
|
||||
static int static_config = 0;
|
||||
static int write_protect_config = 1;
|
||||
static int autofallthrough_config = 0;
|
||||
static int clearglobalvars_config = 0;
|
||||
char ast_config_AST_SYSTEM_NAME[20] = ""; */
|
||||
|
||||
/*! Go no deeper than this through includes (not counting loops) */
|
||||
#define AST_PBX_MAX_STACK 128
|
||||
/* static AST_RWLIST_HEAD_STATIC(acf_root, ast_custom_function); */
|
||||
extern char ast_config_AST_CONFIG_DIR[PATH_MAX];
|
||||
|
||||
/* modulation */
|
||||
void ast_register_file_version(void);
|
||||
void ast_unregister_file_version(void);
|
||||
|
||||
void ast_register_file_version(void)
|
||||
{
|
||||
/* if(!no_comp)
|
||||
printf("Executed ast_register_file_version();\n"); */
|
||||
/* I'm erasing this, because I don't think anyone really ever needs to see it anyway */
|
||||
}
|
||||
|
||||
void ast_unregister_file_version(void)
|
||||
{
|
||||
/* if(!no_comp)
|
||||
printf("Executed ast_unregister_file_version();\n"); */
|
||||
/* I'm erasing this, because I don't think anyone really ever needs to see it anyway */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* experiment 1: see if it's easier just to use existing config code
|
||||
* to read in the extensions.conf file. In this scenario,
|
||||
I have to rip/copy code from other modules, because they
|
||||
are staticly declared as-is. A solution would be to move
|
||||
the ripped code to another location and make them available
|
||||
to other modules and standalones */
|
||||
|
||||
/* Our own version of ast_log, since the expr parser uses it. -- stolen from utils/check_expr.c */
|
||||
void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__ ((format (printf,5,6)));
|
||||
|
||||
/* stolen from pbx.c */
|
||||
struct ast_context;
|
||||
struct ast_app;
|
||||
#ifdef LOW_MEMORY
|
||||
#define EXT_DATA_SIZE 256
|
||||
#else
|
||||
#define EXT_DATA_SIZE 8192
|
||||
#endif
|
||||
|
||||
#define SWITCH_DATA_LENGTH 256
|
||||
|
||||
#define VAR_BUF_SIZE 4096
|
||||
|
||||
#define VAR_NORMAL 1
|
||||
#define VAR_SOFTTRAN 2
|
||||
#define VAR_HARDTRAN 3
|
||||
|
||||
#define BACKGROUND_SKIP (1 << 0)
|
||||
#define BACKGROUND_NOANSWER (1 << 1)
|
||||
#define BACKGROUND_MATCHEXTEN (1 << 2)
|
||||
#define BACKGROUND_PLAYBACK (1 << 3)
|
||||
|
||||
/*!
|
||||
\brief ast_exten: An extension
|
||||
The dialplan is saved as a linked list with each context
|
||||
having it's own linked list of extensions - one item per
|
||||
priority.
|
||||
*/
|
||||
struct ast_exten {
|
||||
char *exten; /*!< Extension name */
|
||||
int matchcid; /*!< Match caller id ? */
|
||||
const char *cidmatch; /*!< Caller id to match for this extension */
|
||||
int priority; /*!< Priority */
|
||||
const char *label; /*!< Label */
|
||||
struct ast_context *parent; /*!< The context this extension belongs to */
|
||||
const char *app; /*!< Application to execute */
|
||||
struct ast_app *cached_app; /*!< Cached location of application */
|
||||
void *data; /*!< Data to use (arguments) */
|
||||
void (*datad)(void *); /*!< Data destructor */
|
||||
struct ast_exten *peer; /*!< Next higher priority with our extension */
|
||||
const char *registrar; /*!< Registrar */
|
||||
struct ast_exten *next; /*!< Extension with a greater ID */
|
||||
char stuff[0];
|
||||
};
|
||||
|
||||
|
||||
/*! \brief ast_include: include= support in extensions.conf */
|
||||
struct ast_include {
|
||||
const char *name;
|
||||
const char *rname; /*!< Context to include */
|
||||
const char *registrar; /*!< Registrar */
|
||||
int hastime; /*!< If time construct exists */
|
||||
struct ast_timing timing; /*!< time construct */
|
||||
struct ast_include *next; /*!< Link them together */
|
||||
char stuff[0];
|
||||
};
|
||||
|
||||
/*! \brief ast_sw: Switch statement in extensions.conf */
|
||||
struct ast_sw {
|
||||
char *name;
|
||||
const char *registrar; /*!< Registrar */
|
||||
char *data; /*!< Data load */
|
||||
int eval;
|
||||
AST_LIST_ENTRY(ast_sw) list;
|
||||
char *tmpdata;
|
||||
char stuff[0];
|
||||
};
|
||||
|
||||
/*! \brief ast_ignorepat: Ignore patterns in dial plan */
|
||||
struct ast_ignorepat {
|
||||
const char *registrar;
|
||||
struct ast_ignorepat *next;
|
||||
const char pattern[0];
|
||||
};
|
||||
|
||||
/*! \brief ast_context: An extension context */
|
||||
struct ast_context {
|
||||
ast_rwlock_t lock; /*!< A lock to prevent multiple threads from clobbering the context */
|
||||
struct ast_exten *root; /*!< The root of the list of extensions */
|
||||
struct ast_context *next; /*!< Link them together */
|
||||
struct ast_include *includes; /*!< Include other contexts */
|
||||
struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
|
||||
const char *registrar; /*!< Registrar */
|
||||
AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
|
||||
ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
|
||||
char name[0]; /*!< Name of the context */
|
||||
};
|
||||
|
||||
|
||||
/*! \brief ast_app: A registered application */
|
||||
struct ast_app {
|
||||
int (*execute)(struct ast_channel *chan, void *data);
|
||||
const char *synopsis; /*!< Synopsis text for 'show applications' */
|
||||
const char *description; /*!< Description (help text) for 'show application <name>' */
|
||||
AST_RWLIST_ENTRY(ast_app) list; /*!< Next app in list */
|
||||
struct module *module; /*!< Module this app belongs to */
|
||||
char name[0]; /*!< Name of the application */
|
||||
};
|
||||
|
||||
/*! \brief ast_state_cb: An extension state notify register item */
|
||||
struct ast_state_cb {
|
||||
int id;
|
||||
void *data;
|
||||
ast_state_cb_type callback;
|
||||
struct ast_state_cb *next;
|
||||
};
|
||||
|
||||
/*! \brief Structure for dial plan hints
|
||||
|
||||
\note Hints are pointers from an extension in the dialplan to one or
|
||||
more devices (tech/name)
|
||||
- See \ref AstExtState
|
||||
*/
|
||||
struct ast_hint {
|
||||
struct ast_exten *exten; /*!< Extension */
|
||||
int laststate; /*!< Last known state */
|
||||
struct ast_state_cb *callbacks; /*!< Callback list for this extension */
|
||||
AST_RWLIST_ENTRY(ast_hint) list;/*!< Pointer to next hint in list */
|
||||
};
|
||||
|
||||
struct store_hint {
|
||||
char *context;
|
||||
char *exten;
|
||||
struct ast_state_cb *callbacks;
|
||||
int laststate;
|
||||
AST_LIST_ENTRY(store_hint) list;
|
||||
char data[1];
|
||||
};
|
||||
|
||||
AST_LIST_HEAD(store_hints, store_hint);
|
||||
|
||||
static const struct cfextension_states {
|
||||
int extension_state;
|
||||
const char * const text;
|
||||
} extension_states[] = {
|
||||
{ AST_EXTENSION_NOT_INUSE, "Idle" },
|
||||
{ AST_EXTENSION_INUSE, "InUse" },
|
||||
{ AST_EXTENSION_BUSY, "Busy" },
|
||||
{ AST_EXTENSION_UNAVAILABLE, "Unavailable" },
|
||||
{ AST_EXTENSION_RINGING, "Ringing" },
|
||||
{ AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
|
||||
{ AST_EXTENSION_ONHOLD, "Hold" },
|
||||
{ AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD, "InUse&Hold" }
|
||||
};
|
||||
#define STATUS_NO_CONTEXT 1
|
||||
#define STATUS_NO_EXTENSION 2
|
||||
#define STATUS_NO_PRIORITY 3
|
||||
#define STATUS_NO_LABEL 4
|
||||
#define STATUS_SUCCESS 5
|
||||
|
||||
extern struct ast_context *local_contexts;
|
||||
extern struct ast_context *contexts;
|
||||
|
||||
|
||||
struct ast_custom_function *ast_custom_function_find(const char *name);
|
||||
|
||||
|
||||
struct ast_custom_function *ast_custom_function_find(const char *name)
|
||||
{
|
||||
return 0; /* in "standalone" mode, functions are just not avail */
|
||||
}
|
||||
|
||||
|
||||
struct profile_entry {
|
||||
const char *name;
|
||||
uint64_t scale; /* if non-zero, values are scaled by this */
|
||||
int64_t mark;
|
||||
int64_t value;
|
||||
int64_t events;
|
||||
};
|
||||
|
||||
struct profile_data {
|
||||
int entries;
|
||||
int max_size;
|
||||
struct profile_entry e[0];
|
||||
};
|
||||
|
||||
static int bit_at(unsigned int *word, int bitsperword, int bitnum)
|
||||
{
|
||||
return word[bitnum/bitsperword] & (1 << (bitnum % bitsperword));
|
||||
}
|
||||
|
||||
void get_start_stop(unsigned int *word, int bitsperword, int totalbits, int *start, int *end)
|
||||
{
|
||||
int i;
|
||||
int thisbit, thatbit = bit_at(word, bitsperword, totalbits-1);
|
||||
|
||||
for (i=0; i<totalbits; i++) {
|
||||
thisbit = bit_at(word, bitsperword, i);
|
||||
|
||||
if (thisbit != thatbit ) {
|
||||
if (thisbit) {
|
||||
*start = i;
|
||||
} else {
|
||||
*end = i;
|
||||
}
|
||||
}
|
||||
thatbit = thisbit;
|
||||
}
|
||||
}
|
||||
|
||||
int all_bits_set(unsigned int *word, int bitsperword, int totalbits )
|
||||
{
|
||||
|
||||
int i, total=totalbits/bitsperword,bitmask = 0;
|
||||
|
||||
for (i=0; i<bitsperword; i++)
|
||||
{
|
||||
bitmask |= (1 << i);
|
||||
}
|
||||
|
||||
for (i=0; i<total; i++)
|
||||
{
|
||||
if (word[i] != bitmask)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct ast_context *tmp;
|
||||
struct ast_exten *e, *eroot;
|
||||
pval *tree, *tmptree, *sws;
|
||||
struct ast_include *tmpi;
|
||||
struct ast_sw *sw = 0;
|
||||
struct ast_ignorepat *ipi;
|
||||
pval *incl=0;
|
||||
|
||||
tree = 0;
|
||||
tmptree = 0;
|
||||
|
||||
/* 3 simple steps: */
|
||||
/* 1. read in the extensions.conf config file
|
||||
* 2. traverse, and build an AEL tree
|
||||
* 3. Output the AEL tree into a file
|
||||
*/
|
||||
printf("WARNING: This is an EXTREMELY preliminary version of a program\n");
|
||||
printf(" that will someday hopefully do a thoughful and intelligent\n");
|
||||
printf(" job of transforming your extensions.conf file into an\n");
|
||||
printf(" extensions.ael file.\n");
|
||||
printf(" This version has absolutely no intelligence, and pretty\n");
|
||||
printf(" much just does a direct conversion\n");
|
||||
printf(" The result will most likely need careful attention to\n");
|
||||
printf(" finish the job!!!!!\n");
|
||||
|
||||
|
||||
strcpy(ast_config_AST_CONFIG_DIR,"/etc/asterisk");
|
||||
|
||||
printf("Loading %s/%s...\n", ast_config_AST_CONFIG_DIR, config);
|
||||
|
||||
localized_pbx_load_module();
|
||||
|
||||
printf("... Done!\n");
|
||||
|
||||
tmp = 0;
|
||||
while ((tmp = localized_walk_contexts(tmp)) ) {
|
||||
printf("Context: %s\n", tmp->name);
|
||||
}
|
||||
printf("=========\n");
|
||||
printf("Sizeof(context)=%d\n", sizeof(struct ast_context));
|
||||
printf("Sizeof(exten)=%d\n", sizeof(struct ast_exten));
|
||||
printf("Sizeof(include)=%d\n", sizeof(struct ast_include));
|
||||
printf("Sizeof(ignorepat)=%d\n", sizeof(struct ast_ignorepat));
|
||||
printf("Sizeof(sw)=%d\n", sizeof(struct ast_sw));
|
||||
tmp = 0;
|
||||
while ((tmp = localized_walk_contexts(tmp)) ) {
|
||||
/* printf("Context: %s\n", tmp->name); */
|
||||
tmptree = pvalCreateNode(PV_CONTEXT);
|
||||
if (!tree)
|
||||
tree = tmptree;
|
||||
else
|
||||
pvalTopLevAddObject(tree, tmptree);
|
||||
|
||||
pvalContextSetName(tmptree, ast_strdup(tmp->name));
|
||||
|
||||
if (tmp->includes) {
|
||||
incl = pvalCreateNode(PV_INCLUDES);
|
||||
pvalContextAddStatement(tmptree, incl);
|
||||
for (tmpi = tmp->includes; tmpi; ) { /* includes */
|
||||
if (strchr(tmpi->name,'|')==0) {
|
||||
if (tmpi->hastime)
|
||||
{
|
||||
char timerange[15];
|
||||
char dowrange[10];
|
||||
char domrange[10];
|
||||
char monrange[10];
|
||||
int startbit=0, endbit=0;
|
||||
|
||||
if (all_bits_set(tmpi->timing.minmask, 30, 720))
|
||||
strcpy(timerange, "*");
|
||||
else {
|
||||
int hr, min;
|
||||
char tbuf[20];
|
||||
get_start_stop(tmpi->timing.minmask, 30, 720, &startbit, &endbit);
|
||||
hr = startbit/30;
|
||||
min = (startbit % 30) * 2;
|
||||
sprintf(tbuf,"%02d:%02d", hr, min);
|
||||
strcpy(timerange, tbuf);
|
||||
hr = endbit/30;
|
||||
min = (endbit % 30) * 2;
|
||||
sprintf(tbuf,"%02d:%02d", hr, min);
|
||||
strcat(timerange,"-");
|
||||
strcat(timerange,tbuf);
|
||||
}
|
||||
|
||||
if (all_bits_set(&tmpi->timing.dowmask, 7, 7))
|
||||
strcpy(dowrange, "*");
|
||||
else {
|
||||
get_start_stop(&tmpi->timing.dowmask, 7, 7, &startbit, &endbit);
|
||||
strcpy(dowrange, days[startbit]);
|
||||
strcat(dowrange,"-");
|
||||
strcat(dowrange, days[endbit]);
|
||||
}
|
||||
|
||||
if (all_bits_set(&tmpi->timing.monthmask, 12, 12))
|
||||
strcpy(monrange, "*");
|
||||
else {
|
||||
get_start_stop(&tmpi->timing.monthmask, 12, 12, &startbit, &endbit);
|
||||
strcpy(monrange, months[startbit]);
|
||||
strcat(monrange,"-");
|
||||
strcat(monrange, months[endbit]);
|
||||
}
|
||||
|
||||
if (all_bits_set(&tmpi->timing.daymask, 31, 31))
|
||||
strcpy(domrange, "*");
|
||||
else {
|
||||
char tbuf[20];
|
||||
get_start_stop(&tmpi->timing.daymask, 31, 31, &startbit, &endbit);
|
||||
sprintf(tbuf,"%d", startbit);
|
||||
strcpy(domrange, tbuf);
|
||||
strcat(domrange,"-");
|
||||
sprintf(tbuf,"%d", endbit);
|
||||
strcat(domrange, tbuf);
|
||||
}
|
||||
/* now all 4 fields are set; what do we do? */
|
||||
pvalIncludesAddIncludeWithTimeConstraints(incl, strdup(tmpi->name), strdup(timerange), strdup(domrange), strdup(dowrange), strdup(monrange));
|
||||
|
||||
} else {
|
||||
pvalIncludesAddInclude(incl, strdup(tmpi->name));
|
||||
}
|
||||
} else { /* it appears the timing constraint info is tacked onto the name, carve it up and divvy it out */
|
||||
char *dow,*dom,*mon;
|
||||
char *all = strdup(tmpi->name);
|
||||
char *hr = strchr(all,'|');
|
||||
if (hr) {
|
||||
*hr++ = 0;
|
||||
dow = strchr(hr,'|');
|
||||
if (dow) {
|
||||
*dow++ = 0;
|
||||
dom = strchr(dow,'|');
|
||||
if (dom) {
|
||||
*dom++ = 0;
|
||||
mon = strchr(dom,'|');
|
||||
if (mon) {
|
||||
*mon++ = 0;
|
||||
/* now all 4 fields are set; what do we do? */
|
||||
pvalIncludesAddIncludeWithTimeConstraints(incl, all, hr, dow, dom, mon);
|
||||
/* the original data is always best to keep (no 2-min rounding) */
|
||||
} else {
|
||||
ast_log(LOG_ERROR,"No month spec attached to include!\n");
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_ERROR,"No day of month spec attached to include!\n");
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_ERROR,"No day of week spec attached to include!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
tmpi = tmpi->next;
|
||||
}
|
||||
}
|
||||
for (ipi = tmp->ignorepats; ipi; ) { /* ignorepats */
|
||||
incl = pvalCreateNode(PV_IGNOREPAT);
|
||||
pvalIgnorePatSetPattern(incl,(char *)ipi->pattern);
|
||||
pvalContextAddStatement(tmptree, incl);
|
||||
ipi = ipi->next;
|
||||
}
|
||||
eroot=0;
|
||||
while ( (eroot = localized_walk_context_extensions(tmp, eroot)) ) {
|
||||
pval *exten = pvalCreateNode(PV_EXTENSION);
|
||||
pvalContextAddStatement(tmptree, exten);
|
||||
pvalExtenSetName(exten, ast_strdup(eroot->exten));
|
||||
|
||||
if (eroot->peer) {
|
||||
pval *block = pvalCreateNode(PV_STATEMENTBLOCK);
|
||||
pvalExtenSetStatement(exten, block);
|
||||
|
||||
e = 0;
|
||||
while ( (e = localized_walk_extension_priorities(eroot, e)) ) {
|
||||
/* printf(" %s(%s)\n", e->app, (char*)e->data); */
|
||||
|
||||
pval *statemnt = pvalCreateNode(PV_APPLICATION_CALL);
|
||||
pval *args = pvalCreateNode(PV_WORD);
|
||||
|
||||
pvalAppCallSetAppName(statemnt, ast_strdup(e->app));
|
||||
pvalWordSetString(args, ast_strdup(e->data));
|
||||
pvalAppCallAddArg(statemnt, args);
|
||||
|
||||
pvalStatementBlockAddStatement(block, statemnt);
|
||||
}
|
||||
} else {
|
||||
pval *statemnt = pvalCreateNode(PV_APPLICATION_CALL);
|
||||
pval *args = pvalCreateNode(PV_WORD);
|
||||
|
||||
/* printf(" %s (%s)\n", eroot->app, (char *)eroot->data); */
|
||||
|
||||
pvalAppCallSetAppName(statemnt, ast_strdup(eroot->app));
|
||||
pvalWordSetString(args, ast_strdup(eroot->data));
|
||||
|
||||
|
||||
pvalAppCallAddArg(statemnt, args);
|
||||
pvalExtenSetStatement(exten, statemnt);
|
||||
}
|
||||
|
||||
/* printf(" extension: %s\n", eroot->exten); */
|
||||
}
|
||||
if (AST_LIST_FIRST(&tmp->alts)) {
|
||||
sws = pvalCreateNode(PV_SWITCHES);
|
||||
pvalContextAddStatement(tmptree,sws);
|
||||
|
||||
sw = 0;
|
||||
while ((sw = localized_walk_context_switches(tmp,sw)) ) {
|
||||
pvalSwitchesAddSwitch(sws, ast_strdup(sw->name));
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("Generating aelout.ael file...\n");
|
||||
|
||||
ael2_print("aelout.ael", tree);
|
||||
|
||||
printf("...Done!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ==================================== for linking internal stuff to external stuff */
|
||||
|
||||
int pbx_builtin_setvar(struct ast_channel *chan, void *data)
|
||||
{
|
||||
return localized_pbx_builtin_setvar(chan, data);
|
||||
}
|
||||
|
||||
void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
|
||||
void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count)
|
||||
{
|
||||
if (cp1 && *cp1)
|
||||
strncpy(cp2,cp1,AST_MAX_EXTENSION); /* Right now, this routine is ONLY being called for
|
||||
a possible var substitution on extension names,
|
||||
so....! */
|
||||
else
|
||||
*cp2 = 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return localized_add_extension2(con, replace, extension, priority, label, callerid, application, data, datad, registrar);
|
||||
}
|
||||
|
||||
int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
|
||||
{
|
||||
|
||||
return localized_context_add_ignorepat2(con, value, registrar);
|
||||
}
|
||||
|
||||
int ast_context_add_switch2(struct ast_context *con, const char *value,
|
||||
const char *data, int eval, const char *registrar)
|
||||
{
|
||||
|
||||
return localized_context_add_switch2(con, value, data, eval, registrar);
|
||||
}
|
||||
|
||||
int ast_context_add_include2(struct ast_context *con, const char *value,
|
||||
const char *registrar)
|
||||
{
|
||||
|
||||
return localized_context_add_include2(con, value,registrar);
|
||||
}
|
||||
|
||||
struct ast_context *ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar)
|
||||
{
|
||||
printf("Creating context %s, registrar=%s\n", name, registrar);
|
||||
|
||||
return localized_context_create(extcontexts, name, registrar);
|
||||
}
|
||||
|
||||
void ast_cli_register_multiple(void);
|
||||
|
||||
void ast_cli_register_multiple(void)
|
||||
{
|
||||
}
|
||||
|
||||
void ast_module_register(const struct ast_module_info *x)
|
||||
{
|
||||
}
|
||||
|
||||
void ast_module_unregister(const struct ast_module_info *x)
|
||||
{
|
||||
}
|
||||
|
||||
void ast_cli_unregister_multiple(void);
|
||||
|
||||
void ast_cli_unregister_multiple(void)
|
||||
{
|
||||
}
|
||||
|
||||
struct ast_context *ast_walk_contexts(struct ast_context *con);
|
||||
struct ast_context *ast_walk_contexts(struct ast_context *con)
|
||||
{
|
||||
return localized_walk_contexts(con);
|
||||
}
|
||||
|
||||
void ast_context_destroy(struct ast_context *con, const char *registrar);
|
||||
|
||||
void ast_context_destroy(struct ast_context *con, const char *registrar)
|
||||
{
|
||||
return localized_context_destroy(con, registrar);
|
||||
}
|
||||
|
||||
int ast_context_verify_includes(struct ast_context *con);
|
||||
|
||||
int ast_context_verify_includes(struct ast_context *con)
|
||||
{
|
||||
return localized_context_verify_includes(con);
|
||||
}
|
||||
|
||||
void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar);
|
||||
|
||||
void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar)
|
||||
{
|
||||
localized_merge_contexts_and_delete(extcontexts, registrar);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
return localized_find_extension(bypass, q, context, exten, priority, label, callerid, action);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue