2 * XXX this file probably need a fair amount of cleanup, at the very least:
4 * - documenting its purpose;
5 * - removing all unnecessary headers and other stuff from the sources
7 * - fixing the formatting
16 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
18 #include "asterisk/channel.h"
19 #include "asterisk/ast_expr.h"
20 #include "asterisk/module.h"
21 #include "asterisk/app.h"
22 #include "asterisk/lock.h"
23 #include "asterisk/hashtab.h"
24 #include "asterisk/ael_structs.h"
25 #include "asterisk/extconf.h"
27 struct ast_flags ast_compat = { 7 };
30 <depend>res_ael_share</depend>
37 struct namelist *next;
45 struct namelist *includes;
46 struct namelist *ignorepats;
47 struct namelist *switches;
48 struct namelist *eswitches;
50 struct namelist *includes_last;
51 struct namelist *ignorepats_last;
52 struct namelist *switches_last;
53 struct namelist *eswitches_last;
55 struct ast_context *next;
58 #define ADD_LAST(headptr,memptr) if(!headptr){ headptr=(memptr); (headptr##_last)=(memptr);} else {(headptr##_last)->next = (memptr); (headptr##_last) = (memptr);}
60 void destroy_namelist(struct namelist *x);
61 void destroy_namelist(struct namelist *x)
63 struct namelist *z,*z2;
72 struct namelist *create_name(const char *name);
73 struct namelist *create_name(const char *name)
75 struct namelist *x = calloc(1, sizeof(*x));
78 strncpy(x->name, name, sizeof(x->name) - 1);
82 struct ast_context *context_list;
83 struct ast_context *last_context;
84 struct namelist *globalvars;
85 struct namelist *globalvars_last;
87 int conts=0, extens=0, priors=0;
88 char last_exten[18000];
90 static char config_dir[PATH_MAX];
91 static char var_dir[PATH_MAX];
92 const char *ast_config_AST_CONFIG_DIR = config_dir;
93 const char *ast_config_AST_VAR_DIR = var_dir;
95 void ast_cli_register_multiple(void);
96 int ast_add_extension2(struct ast_context *con,
97 int replace, const char *extension, int priority, const char *label, const char *callerid,
98 const char *application, void *data, void (*datad)(void *),
99 const char *registrar);
100 void pbx_builtin_setvar(void *chan, void *data);
101 struct ast_context * ast_context_create(void **extcontexts, const char *name, const char *registrar);
102 struct ast_context * ast_context_find_or_create(void **extcontexts, void *tab, const char *name, const char *registrar);
103 void ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar);
104 void ast_context_add_include2(struct ast_context *con, const char *value, const char *registrar);
105 void ast_context_add_switch2(struct ast_context *con, const char *value, const char *data, int eval, const char *registrar);
106 void ast_merge_contexts_and_delete(void);
107 void ast_context_verify_includes(void);
108 struct ast_context * ast_walk_contexts(void);
109 void ast_cli_unregister_multiple(void);
110 void ast_context_destroy(void);
111 void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...);
112 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
113 void __ast_verbose(const char *file, int line, const char *func, const char *fmt, ...);
114 struct ast_app *pbx_findapp(const char *app);
115 void filter_leading_space_from_exprs(char *str);
116 void filter_newlines(char *str);
117 static int quiet = 0;
118 static int no_comp = 0;
119 static int use_curr_dir = 0;
120 static int dump_extensions = 0;
121 static int FIRST_TIME = 0;
122 static FILE *dumpfile;
124 void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
129 printf("LOG: lev:%d file:%s line:%d func: %s ",
130 level, file, line, function);
136 struct ast_exten *pbx_find_extension(struct ast_channel *chan,
137 struct ast_context *bypass,
138 struct pbx_find_info *q,
143 const char *callerid,
144 enum ext_match_t action);
146 struct ast_exten *pbx_find_extension(struct ast_channel *chan,
147 struct ast_context *bypass,
148 struct pbx_find_info *q,
153 const char *callerid,
154 enum ext_match_t action)
156 return localized_find_extension(bypass, q, context, exten, priority, label, callerid, action);
159 struct ast_app *pbx_findapp(const char *app)
161 return (struct ast_app*)1; /* so as not to trigger an error */
164 struct ast_custom_function *ast_custom_function_find(const char *name);
167 struct ast_custom_function *ast_custom_function_find(const char *name)
169 return 0; /* in "standalone" mode, functions are just not avail */
172 void ast_register_file_version(const char *file, const char *version);
173 void ast_register_file_version(const char *file, const char *version)
177 void ast_unregister_file_version(const char *file);
178 void ast_unregister_file_version(const char *file)
182 #if !defined(LOW_MEMORY)
183 int ast_add_profile(const char *x, uint64_t scale)
186 printf("Executed ast_add_profile();\n");
192 int ast_loader_register(int (*updater)(void))
197 int ast_loader_unregister(int (*updater)(void))
201 void ast_module_register(const struct ast_module_info *x)
205 void ast_module_unregister(const struct ast_module_info *x)
210 void ast_cli_register_multiple(void)
213 printf("Executed ast_cli_register_multiple();\n");
216 void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
217 void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count)
220 strncpy(cp2,cp1,AST_MAX_EXTENSION); /* Right now, this routine is ONLY being called for
221 a possible var substitution on extension names,
227 int ast_add_extension2(struct ast_context *con,
228 int replace, const char *extension, int priority, const char *label, const char *callerid,
229 const char *application, void *data, void (*datad)(void *),
230 const char *registrar)
233 con->extension_count++;
234 if (strcmp(extension,last_exten) != 0) {
236 strcpy(last_exten, extension);
245 application = "(null)";
249 printf("Executed ast_add_extension2(context=%s, rep=%d, exten=%s, priority=%d, label=%s, callerid=%s, appl=%s, data=%s, FREE, registrar=%s);\n",
250 con->name, replace, extension, priority, label, callerid, application, (data?(char*)data:"(null)"), registrar);
252 if( dump_extensions && dumpfile ) {
259 fprintf(dumpfile,"[globals]\n");
261 for(n=globalvars;n;n=n->next) {
262 fprintf(dumpfile, "%s\n", n->name);
266 /* print out each extension , possibly the context header also */
267 if( con != last_context ) {
268 fprintf(dumpfile,"\n\n[%s]\n", con->name);
270 for(n=con->ignorepats;n;n=n->next) {
271 fprintf(dumpfile, "ignorepat => %s\n", n->name);
273 for(n=con->includes;n;n=n->next) {
274 fprintf(dumpfile, "include => %s\n", n->name);
276 for(n=con->switches;n;n=n->next) {
277 fprintf(dumpfile, "switch => %s/%s\n", n->name, n->name2);
279 for(n=con->eswitches;n;n=n->next) {
280 fprintf(dumpfile, "eswitch => %s/%s\n", n->name, n->name2);
285 filter_newlines((char*)data);
286 filter_leading_space_from_exprs((char*)data);
287 /* in previous versions, commas were converted to '|' to separate
288 args in app calls, but now, commas are used. There used to be
289 code here to insert backslashes (escapes) before any commas
290 that may have been embedded in the app args. This code is no more. */
292 if( strcmp(label,"(null)") != 0 )
293 fprintf(dumpfile,"exten => %s,%d(%s),%s(%s)\n", extension, priority, label, application, (char*)data);
295 fprintf(dumpfile,"exten => %s,%d,%s(%s)\n", extension, priority, application, (char*)data);
299 if( strcmp(label,"(null)") != 0 )
300 fprintf(dumpfile,"exten => %s,%d(%s),%s\n", extension, priority, label, application);
302 fprintf(dumpfile,"exten => %s,%d,%s\n", extension, priority, application);
306 /* since add_extension2 is responsible for the malloc'd data stuff */
312 void pbx_builtin_setvar(void *chan, void *data)
314 struct namelist *x = create_name(data);
316 printf("Executed pbx_builtin_setvar(chan, data=%s);\n", (char*)data);
318 if( dump_extensions ) {
319 x = create_name(data);
320 ADD_LAST(globalvars,x);
325 struct ast_context * ast_context_create(void **extcontexts, const char *name, const char *registrar)
327 struct ast_context *x = calloc(1, sizeof(*x));
330 x->next = context_list;
333 printf("Executed ast_context_create(conts, name=%s, registrar=%s);\n", name, registrar);
335 strncpy(x->name, name, sizeof(x->name) - 1);
336 strncpy(x->registrar, registrar, sizeof(x->registrar) - 1);
340 struct ast_context * ast_context_find_or_create(void **extcontexts, void *tab, const char *name, const char *registrar)
342 struct ast_context *x = calloc(1, sizeof(*x));
345 x->next = context_list;
348 printf("Executed ast_context_find_or_create(conts, name=%s, registrar=%s);\n", name, registrar);
350 strncpy(x->name, name, sizeof(x->name) - 1);
351 strncpy(x->registrar, registrar, sizeof(x->registrar) - 1);
355 void ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
358 printf("Executed ast_context_add_ignorepat2(con, value=%s, registrar=%s);\n", value, registrar);
359 if( dump_extensions ) {
361 x = create_name(value);
362 ADD_LAST(con->ignorepats,x);
366 void ast_context_add_include2(struct ast_context *con, const char *value, const char *registrar)
369 printf("Executed ast_context_add_include2(con, value=%s, registrar=%s);\n", value, registrar);
370 if( dump_extensions ) {
372 x = create_name((char*)value);
373 ADD_LAST(con->includes,x);
377 void ast_context_add_switch2(struct ast_context *con, const char *value, const char *data, int eval, const char *registrar)
380 printf("Executed ast_context_add_switch2(con, value=%s, data=%s, eval=%d, registrar=%s);\n", value, data, eval, registrar);
381 if( dump_extensions ) {
383 x = create_name((char*)value);
384 strncpy(x->name2,data,100);
387 ADD_LAST(con->switches,x);
391 ADD_LAST(con->eswitches,x);
396 void ast_merge_contexts_and_delete(void)
399 printf("Executed ast_merge_contexts_and_delete();\n");
402 void ast_context_verify_includes(void)
405 printf("Executed ast_context_verify_includes();\n");
408 struct ast_context * ast_walk_contexts(void)
411 printf("Executed ast_walk_contexts();\n");
415 void ast_cli_unregister_multiple(void)
418 printf("Executed ast_cli_unregister_multiple();\n");
421 void ast_context_destroy(void)
424 printf("Executed ast_context_destroy();\n");
427 void filter_leading_space_from_exprs(char *str)
429 /* Mainly for aesthetics */
430 char *t, *v, *u = str;
434 if( *u == '$' && *(u+1) == '[' ) {
436 while( *t == '\n' || *t == '\r' || *t == '\t' || *t == ' ' ) {
449 void filter_newlines(char *str)
451 /* remove all newlines, returns */
454 if( *t == '\n' || *t == '\r' ) {
455 *t = ' '; /* just replace newlines and returns with spaces; they act as
456 token separators, and just blindly removing them could be
464 extern struct module_symbols mod_data;
465 int ael_external_load_module(void);
468 int main(int argc, char **argv)
472 struct ast_context *lp,*lp2;
474 for(i=1;i<argc;i++) {
475 if( argv[i][0] == '-' && argv[i][1] == 'n' )
477 if( argv[i][0] == '-' && argv[i][1] == 'q' ) {
481 if( argv[i][0] == '-' && argv[i][1] == 'd' )
483 if( argv[i][0] == '-' && argv[i][1] == 'w' )
488 printf("\n(If you find progress and other non-error messages irritating, you can use -q to suppress them)\n");
490 printf("\n(You can use the -n option if you aren't interested in seeing all the instructions generated by the compiler)\n\n");
492 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");
493 if( !dump_extensions )
494 printf("\n(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)\n");
498 strcpy(config_dir, ".");
499 localized_use_local_dir();
502 strcpy(config_dir, "/etc/asterisk");
503 localized_use_conf_dir();
505 strcpy(var_dir, "/var/lib/asterisk");
507 if( dump_extensions ) {
508 dumpfile = fopen("extensions.conf.aeldump","w");
510 printf("\n\nSorry, cannot open extensions.conf.aeldump for writing! Correct the situation and try again!\n\n");
518 ael_external_load_module();
520 ast_log(4, "ael2_parse", __LINE__, "main", "%d contexts, %d extensions, %d priorities\n", conts, extens, priors);
522 if( dump_extensions && dumpfile ) {
524 for( lp = context_list; lp; lp = lp->next ) { /* print out any contexts that didn't have any
525 extensions in them */
526 if( lp->extension_count == 0 ) {
528 fprintf(dumpfile,"\n\n[%s]\n", lp->name);
530 for(n=lp->ignorepats;n;n=n->next) {
531 fprintf(dumpfile, "ignorepat => %s\n", n->name);
533 for(n=lp->includes;n;n=n->next) {
534 fprintf(dumpfile, "include => %s\n", n->name);
536 for(n=lp->switches;n;n=n->next) {
537 fprintf(dumpfile, "switch => %s/%s\n", n->name, n->name2);
539 for(n=lp->eswitches;n;n=n->next) {
540 fprintf(dumpfile, "eswitch => %s/%s\n", n->name, n->name2);
546 if( dump_extensions && dumpfile )
549 for( lp = context_list; lp; lp = lp2 ) { /* free the ast_context structs */
553 destroy_namelist(lp->includes);
554 destroy_namelist(lp->ignorepats);
555 destroy_namelist(lp->switches);
556 destroy_namelist(lp->eswitches);
564 int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b);
566 int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b)
571 unsigned int ast_hashtab_hash_contexts(const void *obj);
573 unsigned int ast_hashtab_hash_contexts(const void *obj)
579 #if !defined(LOW_MEMORY)
580 void ast_mark_lock_acquired(void *lock_addr)
584 void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt)
588 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
589 int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
593 int ast_bt_get_addresses(struct ast_bt *bt)
599 void ast_remove_lock_info(void *lock_addr)
603 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
604 int line_num, const char *func, const char *lock_name, void *lock_addr)
607 #endif /* HAVE_BKTR */
608 #endif /* !defined(LOW_MEMORY) */
609 #endif /* DEBUG_THREADS */