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"
28 <depend>res_ael_share</depend>
35 struct namelist
*next
;
43 struct namelist
*includes
;
44 struct namelist
*ignorepats
;
45 struct namelist
*switches
;
46 struct namelist
*eswitches
;
48 struct namelist
*includes_last
;
49 struct namelist
*ignorepats_last
;
50 struct namelist
*switches_last
;
51 struct namelist
*eswitches_last
;
53 struct ast_context
*next
;
56 #define ADD_LAST(headptr,memptr) if(!headptr){ headptr=(memptr); (headptr##_last)=(memptr);} else {(headptr##_last)->next = (memptr); (headptr##_last) = (memptr);}
58 void destroy_namelist(struct namelist
*x
);
59 void destroy_namelist(struct namelist
*x
)
61 struct namelist
*z
,*z2
;
70 struct namelist
*create_name(const char *name
);
71 struct namelist
*create_name(const char *name
)
73 struct namelist
*x
= calloc(1, sizeof(*x
));
76 strncpy(x
->name
, name
, sizeof(x
->name
) - 1);
80 struct ast_context
*context_list
;
81 struct ast_context
*last_context
;
82 struct namelist
*globalvars
;
83 struct namelist
*globalvars_last
;
85 int conts
=0, extens
=0, priors
=0;
86 char last_exten
[18000];
88 static char config_dir
[PATH_MAX
];
89 static char var_dir
[PATH_MAX
];
90 const char *ast_config_AST_CONFIG_DIR
= config_dir
;
91 const char *ast_config_AST_VAR_DIR
= var_dir
;
93 void ast_cli_register_multiple(void);
94 int ast_add_extension2(struct ast_context
*con
,
95 int replace
, const char *extension
, int priority
, const char *label
, const char *callerid
,
96 const char *application
, void *data
, void (*datad
)(void *),
97 const char *registrar
);
98 void pbx_builtin_setvar(void *chan
, void *data
);
99 struct ast_context
* ast_context_create(void **extcontexts
, const char *name
, const char *registrar
);
100 struct ast_context
* ast_context_find_or_create(void **extcontexts
, void *tab
, const char *name
, const char *registrar
);
101 void ast_context_add_ignorepat2(struct ast_context
*con
, const char *value
, const char *registrar
);
102 void ast_context_add_include2(struct ast_context
*con
, const char *value
, const char *registrar
);
103 void ast_context_add_switch2(struct ast_context
*con
, const char *value
, const char *data
, int eval
, const char *registrar
);
104 void ast_merge_contexts_and_delete(void);
105 void ast_context_verify_includes(void);
106 struct ast_context
* ast_walk_contexts(void);
107 void ast_cli_unregister_multiple(void);
108 void ast_context_destroy(void);
109 void ast_log(int level
, const char *file
, int line
, const char *function
, const char *fmt
, ...);
110 char *ast_process_quotes_and_slashes(char *start
, char find
, char replace_with
);
111 void __ast_verbose(const char *file
, int line
, const char *func
, const char *fmt
, ...);
112 struct ast_app
*pbx_findapp(const char *app
);
113 void filter_leading_space_from_exprs(char *str
);
114 void filter_newlines(char *str
);
115 static int quiet
= 0;
116 static int no_comp
= 0;
117 static int use_curr_dir
= 0;
118 static int dump_extensions
= 0;
119 static int FIRST_TIME
= 0;
120 static FILE *dumpfile
;
122 void ast_log(int level
, const char *file
, int line
, const char *function
, const char *fmt
, ...)
127 printf("LOG: lev:%d file:%s line:%d func: %s ",
128 level
, file
, line
, function
);
134 struct ast_exten
*pbx_find_extension(struct ast_channel
*chan
,
135 struct ast_context
*bypass
,
136 struct pbx_find_info
*q
,
141 const char *callerid
,
142 enum ext_match_t action
);
144 struct ast_exten
*pbx_find_extension(struct ast_channel
*chan
,
145 struct ast_context
*bypass
,
146 struct pbx_find_info
*q
,
151 const char *callerid
,
152 enum ext_match_t action
)
154 return localized_find_extension(bypass
, q
, context
, exten
, priority
, label
, callerid
, action
);
157 struct ast_app
*pbx_findapp(const char *app
)
159 return (struct ast_app
*)1; /* so as not to trigger an error */
162 struct ast_custom_function
*ast_custom_function_find(const char *name
);
165 struct ast_custom_function
*ast_custom_function_find(const char *name
)
167 return 0; /* in "standalone" mode, functions are just not avail */
170 void ast_register_file_version(const char *file
, const char *version
);
171 void ast_register_file_version(const char *file
, const char *version
)
175 void ast_unregister_file_version(const char *file
);
176 void ast_unregister_file_version(const char *file
)
180 #if !defined(LOW_MEMORY)
181 int ast_add_profile(const char *x
, uint64_t scale
)
184 printf("Executed ast_add_profile();\n");
190 int ast_loader_register(int (*updater
)(void))
195 int ast_loader_unregister(int (*updater
)(void))
199 void ast_module_register(const struct ast_module_info
*x
)
203 void ast_module_unregister(const struct ast_module_info
*x
)
208 void ast_cli_register_multiple(void)
211 printf("Executed ast_cli_register_multiple();\n");
214 void pbx_substitute_variables_helper(struct ast_channel
*c
,const char *cp1
,char *cp2
,int count
);
215 void pbx_substitute_variables_helper(struct ast_channel
*c
,const char *cp1
,char *cp2
,int count
)
218 strncpy(cp2
,cp1
,AST_MAX_EXTENSION
); /* Right now, this routine is ONLY being called for
219 a possible var substitution on extension names,
225 int ast_add_extension2(struct ast_context
*con
,
226 int replace
, const char *extension
, int priority
, const char *label
, const char *callerid
,
227 const char *application
, void *data
, void (*datad
)(void *),
228 const char *registrar
)
231 con
->extension_count
++;
232 if (strcmp(extension
,last_exten
) != 0) {
234 strcpy(last_exten
, extension
);
243 application
= "(null)";
247 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",
248 con
->name
, replace
, extension
, priority
, label
, callerid
, application
, (data
?(char*)data
:"(null)"), registrar
);
250 if( dump_extensions
&& dumpfile
) {
257 fprintf(dumpfile
,"[globals]\n");
259 for(n
=globalvars
;n
;n
=n
->next
) {
260 fprintf(dumpfile
, "%s\n", n
->name
);
264 /* print out each extension , possibly the context header also */
265 if( con
!= last_context
) {
266 fprintf(dumpfile
,"\n\n[%s]\n", con
->name
);
268 for(n
=con
->ignorepats
;n
;n
=n
->next
) {
269 fprintf(dumpfile
, "ignorepat => %s\n", n
->name
);
271 for(n
=con
->includes
;n
;n
=n
->next
) {
272 fprintf(dumpfile
, "include => %s\n", n
->name
);
274 for(n
=con
->switches
;n
;n
=n
->next
) {
275 fprintf(dumpfile
, "switch => %s/%s\n", n
->name
, n
->name2
);
277 for(n
=con
->eswitches
;n
;n
=n
->next
) {
278 fprintf(dumpfile
, "eswitch => %s/%s\n", n
->name
, n
->name2
);
283 filter_newlines((char*)data
);
284 filter_leading_space_from_exprs((char*)data
);
285 /* in previous versions, commas were converted to '|' to separate
286 args in app calls, but now, commas are used. There used to be
287 code here to insert backslashes (escapes) before any commas
288 that may have been embedded in the app args. This code is no more. */
290 if( strcmp(label
,"(null)") != 0 )
291 fprintf(dumpfile
,"exten => %s,%d(%s),%s(%s)\n", extension
, priority
, label
, application
, (char*)data
);
293 fprintf(dumpfile
,"exten => %s,%d,%s(%s)\n", extension
, priority
, application
, (char*)data
);
297 if( strcmp(label
,"(null)") != 0 )
298 fprintf(dumpfile
,"exten => %s,%d(%s),%s\n", extension
, priority
, label
, application
);
300 fprintf(dumpfile
,"exten => %s,%d,%s\n", extension
, priority
, application
);
304 /* since add_extension2 is responsible for the malloc'd data stuff */
310 void pbx_builtin_setvar(void *chan
, void *data
)
312 struct namelist
*x
= create_name(data
);
314 printf("Executed pbx_builtin_setvar(chan, data=%s);\n", (char*)data
);
316 if( dump_extensions
) {
317 x
= create_name(data
);
318 ADD_LAST(globalvars
,x
);
323 struct ast_context
* ast_context_create(void **extcontexts
, const char *name
, const char *registrar
)
325 struct ast_context
*x
= calloc(1, sizeof(*x
));
328 x
->next
= context_list
;
331 printf("Executed ast_context_create(conts, name=%s, registrar=%s);\n", name
, registrar
);
333 strncpy(x
->name
, name
, sizeof(x
->name
) - 1);
334 strncpy(x
->registrar
, registrar
, sizeof(x
->registrar
) - 1);
338 struct ast_context
* ast_context_find_or_create(void **extcontexts
, void *tab
, const char *name
, const char *registrar
)
340 struct ast_context
*x
= calloc(1, sizeof(*x
));
343 x
->next
= context_list
;
346 printf("Executed ast_context_find_or_create(conts, name=%s, registrar=%s);\n", name
, registrar
);
348 strncpy(x
->name
, name
, sizeof(x
->name
) - 1);
349 strncpy(x
->registrar
, registrar
, sizeof(x
->registrar
) - 1);
353 void ast_context_add_ignorepat2(struct ast_context
*con
, const char *value
, const char *registrar
)
356 printf("Executed ast_context_add_ignorepat2(con, value=%s, registrar=%s);\n", value
, registrar
);
357 if( dump_extensions
) {
359 x
= create_name(value
);
360 ADD_LAST(con
->ignorepats
,x
);
364 void ast_context_add_include2(struct ast_context
*con
, const char *value
, const char *registrar
)
367 printf("Executed ast_context_add_include2(con, value=%s, registrar=%s);\n", value
, registrar
);
368 if( dump_extensions
) {
370 x
= create_name((char*)value
);
371 ADD_LAST(con
->includes
,x
);
375 void ast_context_add_switch2(struct ast_context
*con
, const char *value
, const char *data
, int eval
, const char *registrar
)
378 printf("Executed ast_context_add_switch2(con, value=%s, data=%s, eval=%d, registrar=%s);\n", value
, data
, eval
, registrar
);
379 if( dump_extensions
) {
381 x
= create_name((char*)value
);
382 strncpy(x
->name2
,data
,100);
385 ADD_LAST(con
->switches
,x
);
389 ADD_LAST(con
->eswitches
,x
);
394 void ast_merge_contexts_and_delete(void)
397 printf("Executed ast_merge_contexts_and_delete();\n");
400 void ast_context_verify_includes(void)
403 printf("Executed ast_context_verify_includes();\n");
406 struct ast_context
* ast_walk_contexts(void)
409 printf("Executed ast_walk_contexts();\n");
413 void ast_cli_unregister_multiple(void)
416 printf("Executed ast_cli_unregister_multiple();\n");
419 void ast_context_destroy(void)
422 printf("Executed ast_context_destroy();\n");
425 void filter_leading_space_from_exprs(char *str
)
427 /* Mainly for aesthetics */
428 char *t
, *v
, *u
= str
;
432 if( *u
== '$' && *(u
+1) == '[' ) {
434 while( *t
== '\n' || *t
== '\r' || *t
== '\t' || *t
== ' ' ) {
447 void filter_newlines(char *str
)
449 /* remove all newlines, returns */
452 if( *t
== '\n' || *t
== '\r' ) {
453 *t
= ' '; /* just replace newlines and returns with spaces; they act as
454 token separators, and just blindly removing them could be
462 extern struct module_symbols mod_data
;
463 int ael_external_load_module(void);
466 int main(int argc
, char **argv
)
470 struct ast_context
*lp
,*lp2
;
472 for(i
=1;i
<argc
;i
++) {
473 if( argv
[i
][0] == '-' && argv
[i
][1] == 'n' )
475 if( argv
[i
][0] == '-' && argv
[i
][1] == 'q' ) {
479 if( argv
[i
][0] == '-' && argv
[i
][1] == 'd' )
481 if( argv
[i
][0] == '-' && argv
[i
][1] == 'w' )
486 printf("\n(If you find progress and other non-error messages irritating, you can use -q to suppress them)\n");
488 printf("\n(You can use the -n option if you aren't interested in seeing all the instructions generated by the compiler)\n\n");
490 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");
491 if( !dump_extensions
)
492 printf("\n(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)\n");
496 strcpy(config_dir
, ".");
497 localized_use_local_dir();
500 strcpy(config_dir
, "/etc/asterisk");
501 localized_use_conf_dir();
503 strcpy(var_dir
, "/var/lib/asterisk");
505 if( dump_extensions
) {
506 dumpfile
= fopen("extensions.conf.aeldump","w");
508 printf("\n\nSorry, cannot open extensions.conf.aeldump for writing! Correct the situation and try again!\n\n");
516 ael_external_load_module();
518 ast_log(4, "ael2_parse", __LINE__
, "main", "%d contexts, %d extensions, %d priorities\n", conts
, extens
, priors
);
520 if( dump_extensions
&& dumpfile
) {
522 for( lp
= context_list
; lp
; lp
= lp
->next
) { /* print out any contexts that didn't have any
523 extensions in them */
524 if( lp
->extension_count
== 0 ) {
526 fprintf(dumpfile
,"\n\n[%s]\n", lp
->name
);
528 for(n
=lp
->ignorepats
;n
;n
=n
->next
) {
529 fprintf(dumpfile
, "ignorepat => %s\n", n
->name
);
531 for(n
=lp
->includes
;n
;n
=n
->next
) {
532 fprintf(dumpfile
, "include => %s\n", n
->name
);
534 for(n
=lp
->switches
;n
;n
=n
->next
) {
535 fprintf(dumpfile
, "switch => %s/%s\n", n
->name
, n
->name2
);
537 for(n
=lp
->eswitches
;n
;n
=n
->next
) {
538 fprintf(dumpfile
, "eswitch => %s/%s\n", n
->name
, n
->name2
);
544 if( dump_extensions
&& dumpfile
)
547 for( lp
= context_list
; lp
; lp
= lp2
) { /* free the ast_context structs */
551 destroy_namelist(lp
->includes
);
552 destroy_namelist(lp
->ignorepats
);
553 destroy_namelist(lp
->switches
);
554 destroy_namelist(lp
->eswitches
);
562 int ast_hashtab_compare_contexts(const void *ah_a
, const void *ah_b
);
564 int ast_hashtab_compare_contexts(const void *ah_a
, const void *ah_b
)
569 unsigned int ast_hashtab_hash_contexts(const void *obj
);
571 unsigned int ast_hashtab_hash_contexts(const void *obj
)
577 #if !defined(LOW_MEMORY)
578 void ast_mark_lock_acquired(void *lock_addr
)
582 void ast_remove_lock_info(void *lock_addr
, struct ast_bt
*bt
)
586 void ast_store_lock_info(enum ast_lock_type type
, const char *filename
,
587 int line_num
, const char *func
, const char *lock_name
, void *lock_addr
, struct ast_bt
*bt
)
591 int ast_bt_get_addresses(struct ast_bt
*bt
)
597 void ast_remove_lock_info(void *lock_addr
)
601 void ast_store_lock_info(enum ast_lock_type type
, const char *filename
,
602 int line_num
, const char *func
, const char *lock_name
, void *lock_addr
)
605 #endif /* HAVE_BKTR */
606 #endif /* !defined(LOW_MEMORY) */
607 #endif /* DEBUG_THREADS */