12 #include "asterisk/ast_expr.h"
13 #include "asterisk/channel.h"
14 #include "asterisk/module.h"
15 #include "asterisk/app.h"
16 #include "asterisk/ael_structs.h"
19 <depend>pbx_ael</depend>
26 struct namelist
*next
;
34 struct namelist
*includes
;
35 struct namelist
*ignorepats
;
36 struct namelist
*switches
;
37 struct namelist
*eswitches
;
39 struct namelist
*includes_last
;
40 struct namelist
*ignorepats_last
;
41 struct namelist
*switches_last
;
42 struct namelist
*eswitches_last
;
44 struct ast_context
*next
;
47 #define ADD_LAST(headptr,memptr) if(!headptr){ headptr=(memptr); (headptr##_last)=(memptr);} else {(headptr##_last)->next = (memptr); (headptr##_last) = (memptr);}
49 void destroy_namelist(struct namelist
*x
);
50 void destroy_namelist(struct namelist
*x
)
52 struct namelist
*z
,*z2
;
61 struct namelist
*create_name(const char *name
);
62 struct namelist
*create_name(const char *name
)
64 struct namelist
*x
= calloc(1, sizeof(*x
));
67 strncpy(x
->name
, name
, sizeof(x
->name
) - 1);
71 struct ast_context
*context_list
;
72 struct ast_context
*last_context
;
73 struct namelist
*globalvars
;
74 struct namelist
*globalvars_last
;
76 int conts
=0, extens
=0, priors
=0;
77 char last_exten
[18000];
78 char ast_config_AST_CONFIG_DIR
[PATH_MAX
];
79 char ast_config_AST_VAR_DIR
[PATH_MAX
];
81 void ast_add_profile(void);
82 void ast_cli_register_multiple(void);
83 void ast_register_file_version(void);
84 void ast_unregister_file_version(void);
85 int ast_add_extension2(struct ast_context
*con
,
86 int replace
, const char *extension
, int priority
, const char *label
, const char *callerid
,
87 const char *application
, void *data
, void (*datad
)(void *),
88 const char *registrar
);
89 void pbx_builtin_setvar(void *chan
, void *data
);
90 struct ast_context
* ast_context_create(void **extcontexts
, const char *name
, const char *registrar
);
91 struct ast_context
* ast_context_find_or_create(void **extcontexts
, const char *name
, const char *registrar
);
92 void ast_context_add_ignorepat2(struct ast_context
*con
, const char *value
, const char *registrar
);
93 void ast_context_add_include2(struct ast_context
*con
, const char *value
, const char *registrar
);
94 void ast_context_add_switch2(struct ast_context
*con
, const char *value
, const char *data
, int eval
, const char *registrar
);
95 void ast_merge_contexts_and_delete(void);
96 void ast_context_verify_includes(void);
97 struct ast_context
* ast_walk_contexts(void);
98 void ast_cli_unregister_multiple(void);
99 void ast_context_destroy(void);
100 void ast_log(int level
, const char *file
, int line
, const char *function
, const char *fmt
, ...);
101 char *ast_process_quotes_and_slashes(char *start
, char find
, char replace_with
);
102 void ast_verbose(const char *fmt
, ...);
103 struct ast_app
*pbx_findapp(const char *app
);
104 void filter_leading_space_from_exprs(char *str
);
105 void filter_newlines(char *str
);
106 static int quiet
= 0;
107 static int no_comp
= 0;
108 static int use_curr_dir
= 0;
109 static int dump_extensions
= 0;
110 static int FIRST_TIME
= 0;
111 static FILE *dumpfile
;
113 struct ast_app
*pbx_findapp(const char *app
)
115 return (struct ast_app
*)1; /* so as not to trigger an error */
118 void ast_add_profile(void)
121 printf("Executed ast_add_profile();\n");
124 int ast_loader_register(int (*updater
)(void))
129 int ast_loader_unregister(int (*updater
)(void))
133 void ast_module_register(const struct ast_module_info
*x
)
137 void ast_module_unregister(const struct ast_module_info
*x
)
142 void ast_cli_register_multiple(void)
145 printf("Executed ast_cli_register_multiple();\n");
148 void ast_register_file_version(void)
151 printf("Executed ast_register_file_version();\n"); */
152 /* I'm erasing this, because I don't think anyone really ever needs to see it anyway */
155 void ast_unregister_file_version(void)
158 printf("Executed ast_unregister_file_version();\n"); */
159 /* I'm erasing this, because I don't think anyone really ever needs to see it anyway */
162 void pbx_substitute_variables_helper(struct ast_channel
*c
,const char *cp1
,char *cp2
,int count
);
163 void pbx_substitute_variables_helper(struct ast_channel
*c
,const char *cp1
,char *cp2
,int count
)
166 strncpy(cp2
,cp1
,AST_MAX_EXTENSION
); /* Right now, this routine is ONLY being called for
167 a possible var substitution on extension names,
173 int ast_add_extension2(struct ast_context
*con
,
174 int replace
, const char *extension
, int priority
, const char *label
, const char *callerid
,
175 const char *application
, void *data
, void (*datad
)(void *),
176 const char *registrar
)
179 con
->extension_count
++;
180 if (strcmp(extension
,last_exten
) != 0) {
182 strcpy(last_exten
, extension
);
191 application
= "(null)";
195 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",
196 con
->name
, replace
, extension
, priority
, label
, callerid
, application
, (data
?(char*)data
:"(null)"), registrar
);
198 if( dump_extensions
&& dumpfile
) {
200 char *data2
,*data3
=0;
207 fprintf(dumpfile
,"[globals]\n");
209 for(n
=globalvars
;n
;n
=n
->next
) {
210 fprintf(dumpfile
, "%s\n", n
->name
);
214 /* print out each extension , possibly the context header also */
215 if( con
!= last_context
) {
216 fprintf(dumpfile
,"\n\n[%s]\n", con
->name
);
218 for(n
=con
->ignorepats
;n
;n
=n
->next
) {
219 fprintf(dumpfile
, "ignorepat => %s\n", n
->name
);
221 for(n
=con
->includes
;n
;n
=n
->next
) {
222 fprintf(dumpfile
, "include => %s\n", n
->name
);
224 for(n
=con
->switches
;n
;n
=n
->next
) {
225 fprintf(dumpfile
, "switch => %s/%s\n", n
->name
, n
->name2
);
227 for(n
=con
->eswitches
;n
;n
=n
->next
) {
228 fprintf(dumpfile
, "eswitch => %s/%s\n", n
->name
, n
->name2
);
233 filter_newlines((char*)data
);
234 filter_leading_space_from_exprs((char*)data
);
236 /* compiling turns commas into vertical bars in the app data, and also removes the backslash from before escaped commas;
237 we have to restore the escaping backslash in front of any commas; the vertical bars are OK to leave as-is */
238 for (data2
= data
; *data2
; data2
++) {
240 commacount
++; /* we need to know how much bigger the string will grow-- one backslash for each comma */
246 data2
= (char*)malloc(strlen(data
)+commacount
+1);
252 *d4
++ = '\\'; /* put a backslash in front of each comma */
255 *d4
++ = *d3
++; /* or just copy the char */
257 *d4
++ = 0; /* cap off the new string */
262 if( strcmp(label
,"(null)") != 0 )
263 fprintf(dumpfile
,"exten => %s,%d(%s),%s(%s)\n", extension
, priority
, label
, application
, (char*)data
);
265 fprintf(dumpfile
,"exten => %s,%d,%s(%s)\n", extension
, priority
, application
, (char*)data
);
270 data
= data3
; /* restore data to pre-messedup state */
275 if( strcmp(label
,"(null)") != 0 )
276 fprintf(dumpfile
,"exten => %s,%d(%s),%s\n", extension
, priority
, label
, application
);
278 fprintf(dumpfile
,"exten => %s,%d,%s\n", extension
, priority
, application
);
282 /* since add_extension2 is responsible for the malloc'd data stuff */
288 void pbx_builtin_setvar(void *chan
, void *data
)
290 struct namelist
*x
= create_name(data
);
292 printf("Executed pbx_builtin_setvar(chan, data=%s);\n", (char*)data
);
294 if( dump_extensions
) {
295 x
= create_name(data
);
296 ADD_LAST(globalvars
,x
);
301 struct ast_context
* ast_context_create(void **extcontexts
, const char *name
, const char *registrar
)
303 struct ast_context
*x
= calloc(1, sizeof(*x
));
306 x
->next
= context_list
;
309 printf("Executed ast_context_create(conts, name=%s, registrar=%s);\n", name
, registrar
);
311 strncpy(x
->name
, name
, sizeof(x
->name
) - 1);
312 strncpy(x
->registrar
, registrar
, sizeof(x
->registrar
) - 1);
316 struct ast_context
* ast_context_find_or_create(void **extcontexts
, const char *name
, const char *registrar
)
318 struct ast_context
*x
= calloc(1, sizeof(*x
));
321 x
->next
= context_list
;
324 printf("Executed ast_context_find_or_create(conts, name=%s, registrar=%s);\n", name
, registrar
);
326 strncpy(x
->name
, name
, sizeof(x
->name
) - 1);
327 strncpy(x
->registrar
, registrar
, sizeof(x
->registrar
) - 1);
331 void ast_context_add_ignorepat2(struct ast_context
*con
, const char *value
, const char *registrar
)
334 printf("Executed ast_context_add_ignorepat2(con, value=%s, registrar=%s);\n", value
, registrar
);
335 if( dump_extensions
) {
337 x
= create_name(value
);
338 ADD_LAST(con
->ignorepats
,x
);
342 void ast_context_add_include2(struct ast_context
*con
, const char *value
, const char *registrar
)
345 printf("Executed ast_context_add_include2(con, value=%s, registrar=%s);\n", value
, registrar
);
346 if( dump_extensions
) {
348 x
= create_name((char*)value
);
349 ADD_LAST(con
->includes
,x
);
353 void ast_context_add_switch2(struct ast_context
*con
, const char *value
, const char *data
, int eval
, const char *registrar
)
356 printf("Executed ast_context_add_switch2(con, value=%s, data=%s, eval=%d, registrar=%s);\n", value
, data
, eval
, registrar
);
357 if( dump_extensions
) {
359 x
= create_name((char*)value
);
360 strncpy(x
->name2
,data
,100);
363 ADD_LAST(con
->switches
,x
);
367 ADD_LAST(con
->eswitches
,x
);
372 void ast_merge_contexts_and_delete(void)
375 printf("Executed ast_merge_contexts_and_delete();\n");
378 void ast_context_verify_includes(void)
381 printf("Executed ast_context_verify_includes();\n");
384 struct ast_context
* ast_walk_contexts(void)
387 printf("Executed ast_walk_contexts();\n");
391 void ast_cli_unregister_multiple(void)
394 printf("Executed ast_cli_unregister_multiple();\n");
397 void ast_context_destroy(void)
400 printf("Executed ast_context_destroy();\n");
403 void ast_log(int level
, const char *file
, int line
, const char *function
, const char *fmt
, ...)
407 if( !quiet
|| level
> 2 ) {
408 printf("LOG: lev:%d file:%s line:%d func: %s ",
409 level
, file
, line
, function
);
416 void ast_verbose(const char *fmt
, ...)
427 char *ast_process_quotes_and_slashes(char *start
, char find
, char replace_with
)
429 char *dataPut
= start
;
433 for (; *start
; start
++) {
435 *dataPut
++ = *start
; /* Always goes verbatim */
438 if (*start
== '\\') {
439 inEscape
= 1; /* Do not copy \ into the data */
440 } else if (*start
== '\'') {
441 inQuotes
= 1-inQuotes
; /* Do not copy ' into the data */
443 /* Replace , with |, unless in quotes */
444 *dataPut
++ = inQuotes
? *start
: ((*start
==find
) ? replace_with
: *start
);
448 if (start
!= dataPut
)
453 void filter_leading_space_from_exprs(char *str
)
455 /* Mainly for aesthetics */
456 char *t
, *v
, *u
= str
;
460 if( *u
== '$' && *(u
+1) == '[' ) {
462 while( *t
== '\n' || *t
== '\r' || *t
== '\t' || *t
== ' ' ) {
475 void filter_newlines(char *str
)
477 /* remove all newlines, returns */
480 if( *t
== '\n' || *t
== '\r' ) {
481 *t
= ' '; /* just replace newlines and returns with spaces; they act as
482 token separators, and just blindly removing them could be
490 extern struct module_symbols mod_data
;
491 extern int ael_external_load_module(void);
493 int main(int argc
, char **argv
)
497 struct ast_context
*lp
,*lp2
;
499 for(i
=1;i
<argc
;i
++) {
500 if( argv
[i
][0] == '-' && argv
[i
][1] == 'n' )
502 if( argv
[i
][0] == '-' && argv
[i
][1] == 'q' ) {
506 if( argv
[i
][0] == '-' && argv
[i
][1] == 'd' )
508 if( argv
[i
][0] == '-' && argv
[i
][1] == 'w' )
513 printf("\n(If you find progress and other non-error messages irritating, you can use -q to suppress them)\n");
515 printf("\n(You can use the -n option if you aren't interested in seeing all the instructions generated by the compiler)\n\n");
517 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");
518 if( !dump_extensions
)
519 printf("\n(You can use the -w option to dump extensions.conf format to extensions.conf.aeldump)\n");
523 strcpy(ast_config_AST_CONFIG_DIR
, ".");
526 strcpy(ast_config_AST_CONFIG_DIR
, "/etc/asterisk");
528 strcpy(ast_config_AST_VAR_DIR
, "/var/lib/asterisk");
530 if( dump_extensions
) {
531 dumpfile
= fopen("extensions.conf.aeldump","w");
533 printf("\n\nSorry, cannot open extensions.conf.aeldump for writing! Correct the situation and try again!\n\n");
541 ael_external_load_module();
543 ast_log(4, "ael2_parse", __LINE__
, "main", "%d contexts, %d extensions, %d priorities\n", conts
, extens
, priors
);
545 if( dump_extensions
&& dumpfile
) {
547 for( lp
= context_list
; lp
; lp
= lp
->next
) { /* print out any contexts that didn't have any
548 extensions in them */
549 if( lp
->extension_count
== 0 ) {
551 fprintf(dumpfile
,"\n\n[%s]\n", lp
->name
);
553 for(n
=lp
->ignorepats
;n
;n
=n
->next
) {
554 fprintf(dumpfile
, "ignorepat => %s\n", n
->name
);
556 for(n
=lp
->includes
;n
;n
=n
->next
) {
557 fprintf(dumpfile
, "include => %s\n", n
->name
);
559 for(n
=lp
->switches
;n
;n
=n
->next
) {
560 fprintf(dumpfile
, "switch => %s/%s\n", n
->name
, n
->name2
);
562 for(n
=lp
->eswitches
;n
;n
=n
->next
) {
563 fprintf(dumpfile
, "eswitch => %s/%s\n", n
->name
, n
->name2
);
569 if( dump_extensions
&& dumpfile
)
572 for( lp
= context_list
; lp
; lp
= lp2
) { /* free the ast_context structs */
576 destroy_namelist(lp
->includes
);
577 destroy_namelist(lp
->ignorepats
);
578 destroy_namelist(lp
->switches
);
579 destroy_namelist(lp
->eswitches
);