00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#include <stdio.h>
00015
#include <unistd.h>
00016
#include <stdlib.h>
00017
#include <string.h>
00018
#include <errno.h>
00019
#include <time.h>
00020
#include <asterisk/config.h>
00021
#include <asterisk/config_pvt.h>
00022
#include <asterisk/cli.h>
00023
#include <asterisk/lock.h>
00024
#include <asterisk/options.h>
00025
#include <asterisk/logger.h>
00026
#include <asterisk/utils.h>
00027
#include "asterisk.h"
00028
#include "astconf.h"
00029
00030
00031
static int ast_cust_config=0;
00032 struct ast_config *(*global_load_func)(
char *,
struct ast_config *,
struct ast_category **,
struct ast_variable **,
int
00033
#ifdef PRESERVE_COMMENTS
00034
,
struct ast_comment_struct *
00035
#endif
00036
);
00037
00038
AST_MUTEX_DEFINE_STATIC(ast_cust_config_lock);
00039
static struct ast_config_reg *ast_cust_config_list;
00040
static char *config_conf_file =
"extconfig.conf";
00041
00042
static char *strip(
char *buf)
00043 {
00044
char *start;
00045
00046
while (!ast_strlen_zero(buf) && (buf[strlen(buf)-1]<33))
00047 buf[strlen(buf)-1] =
'\0';
00048 start = buf;
00049
00050
while (*start && (*start < 33))
00051 *start++ =
'\0';
00052
return start;
00053 }
00054
00055
#ifdef PRESERVE_COMMENTS
00056
static void free_comments(
struct ast_comment *com)
00057 {
00058
struct ast_comment *l;
00059
while (com) {
00060 l = com;
00061 com = com->
next;
00062
free(l);
00063 }
00064 }
00065
#endif
00066
00067 void ast_destroy(
struct ast_config *ast)
00068 {
00069
struct ast_category *cat, *catn;
00070
struct ast_variable *v, *vn;
00071
00072
if (!ast)
00073
return;
00074
00075 cat = ast->
root;
00076
while(cat) {
00077 v = cat->
root;
00078
while(v) {
00079 vn = v;
00080
free(v->name);
00081
free(v->value);
00082
#ifdef PRESERVE_COMMENTS
00083
free_comments(v->precomments);
00084 free_comments(v->sameline);
00085
#endif
00086
v = v->next;
00087
free(vn);
00088 }
00089 catn = cat;
00090
#ifdef PRESERVE_COMMENTS
00091
free_comments(cat->precomments);
00092 free_comments(cat->sameline);
00093
#endif
00094
cat = cat->next;
00095
free(catn);
00096 }
00097
#ifdef PRESERVE_COMMENTS
00098
free_comments(ast->trailingcomments);
00099
#endif
00100
free(ast);
00101 }
00102
00103 int ast_true(
char *s)
00104 {
00105
if (!
s)
00106
return 0;
00107
00108
if (!strcasecmp(
s,
"yes") ||
00109 !strcasecmp(
s,
"true") ||
00110 !strcasecmp(
s,
"y") ||
00111 !strcasecmp(
s,
"t") ||
00112 !strcasecmp(
s,
"1"))
00113
return -1;
00114
return 0;
00115 }
00116
00117 int ast_false(
char *s)
00118 {
00119
if (!
s)
00120
return 0;
00121
00122
if (!strcasecmp(
s,
"no") ||
00123 !strcasecmp(
s,
"false") ||
00124 !strcasecmp(
s,
"n") ||
00125 !strcasecmp(
s,
"f") ||
00126 !strcasecmp(
s,
"0"))
00127
return -1;
00128
return 0;
00129 }
00130
00131 struct ast_variable *
ast_variable_browse(
struct ast_config *config,
char *category)
00132 {
00133
struct ast_category *cat;
00134 cat = config->
root;
00135
while(cat) {
00136
if (cat->name == category)
00137
return cat->
root;
00138 cat = cat->
next;
00139 }
00140 cat = config->
root;
00141
while(cat) {
00142
if (!strcasecmp(cat->name, category))
00143
return cat->
root;
00144 cat = cat->
next;
00145 }
00146
return NULL;
00147 }
00148
00149 char *
ast_variable_retrieve(
struct ast_config *config,
char *category,
char *value)
00150 {
00151
struct ast_variable *v;
00152
if (category) {
00153 v =
ast_variable_browse(config, category);
00154
while (v) {
00155
if (value == v->name)
00156
return v->value;
00157 v=v->next;
00158 }
00159 v =
ast_variable_browse(config, category);
00160
while (v) {
00161
if (!strcasecmp(value, v->name))
00162
return v->value;
00163 v=v->next;
00164 }
00165 }
else {
00166
struct ast_category *cat;
00167 cat = config->
root;
00168
while(cat) {
00169 v = cat->
root;
00170
while (v) {
00171
if (!strcasecmp(value, v->name))
00172
return v->
value;
00173 v=v->next;
00174 }
00175 cat = cat->next;
00176 }
00177 }
00178
return NULL;
00179 }
00180
00181
#ifdef PRESERVE_COMMENTS
00182
int ast_variable_delete(
struct ast_config *cfg,
char *category,
char *variable,
char *value)
00183 {
00184
struct ast_variable *v, *pv, *bv, *bpv;
00185
struct ast_category *cat;
00186 cat = cfg->
root;
00187
while(cat) {
00188
if (cat->name == category) {
00189
break;
00190 }
00191 cat = cat->
next;
00192 }
00193
if (!cat) {
00194 cat = cfg->
root;
00195
while(cat) {
00196
if (!strcasecmp(cat->name, category)) {
00197
break;
00198 }
00199 cat = cat->
next;
00200 }
00201 }
00202
if (!cat)
00203
return -1;
00204 v = cat->
root;
00205 pv = NULL;
00206
while (v) {
00207
if ((variable == v->name) && (!value || !strcmp(v->value, value)))
00208
break;
00209 pv = v;
00210 v=v->
next;
00211 }
00212
if (!v) {
00213
00214 bv = NULL;
00215 bpv = NULL;
00216 v = cat->root;
00217 pv = NULL;
00218
while (v) {
00219
if (!strcasecmp(variable, v->name) && (!value || !strcmp(v->value, value))) {
00220 bv = v;
00221 bpv = pv;
00222 }
00223 pv = v;
00224 v=v->
next;
00225 }
00226 v = bv;
00227 }
00228
00229
if (v) {
00230
00231
if (pv)
00232 pv->
next = v->
next;
00233
else
00234 cat->root = v->
next;
00235 v->
next = NULL;
00236
free(v->name);
00237
if (v->value)
00238
free(v->value);
00239 free_comments(v->sameline);
00240 free_comments(v->precomments);
00241
return 0;
00242 }
00243
return -1;
00244 }
00245
00246
int ast_category_delete(
struct ast_config *cfg,
char *category)
00247 {
00248
struct ast_variable *v, *pv;
00249
struct ast_category *cat, *cprev;
00250 cat = cfg->
root;
00251 cprev = NULL;
00252
while(cat) {
00253
if (cat->name == category) {
00254
break;
00255 }
00256 cprev = cat;
00257 cat = cat->
next;
00258 }
00259
if (!cat) {
00260 cat = cfg->
root;
00261 cprev = NULL;
00262
while(cat) {
00263
if (!strcasecmp(cat->name, category)) {
00264
break;
00265 }
00266 cprev = cat;
00267 cat = cat->
next;
00268 }
00269 }
00270
if (!cat)
00271
return -1;
00272
00273
if (cprev)
00274 cprev->
next = cat->
next;
00275
else
00276 cfg->
root = cat->
next;
00277 v = cat->
root;
00278
while (v) {
00279 pv = v;
00280 v=v->
next;
00281
if (pv->value)
00282
free(pv->value);
00283
if (pv->name)
00284
free(pv->name);
00285 free_comments(pv->sameline);
00286 free_comments(pv->precomments);
00287
free(pv);
00288 }
00289 free_comments(cat->sameline);
00290 free_comments(cat->precomments);
00291
free(cat);
00292
return 0;
00293 }
00294
00295
struct ast_variable *
ast_variable_append_modify(
struct ast_config *config,
char *category,
char *variable,
char *value,
int newcat,
int newvar,
int move)
00296 {
00297
struct ast_variable *v, *pv=NULL, *bv, *bpv;
00298
struct ast_category *cat, *pcat;
00299 cat = config->
root;
00300
if (!newcat) {
00301
while(cat) {
00302
if (cat->name == category) {
00303
break;
00304 }
00305 cat = cat->
next;
00306 }
00307
if (!cat) {
00308 cat = config->
root;
00309
while(cat) {
00310
if (!strcasecmp(cat->name, category)) {
00311
break;
00312 }
00313 cat = cat->
next;
00314 }
00315 }
00316 }
00317
if (!cat) {
00318 cat =
malloc(
sizeof(
struct ast_category));
00319
if (!cat)
00320
return NULL;
00321 memset(cat, 0,
sizeof(
struct ast_category));
00322 strncpy(cat->name, category,
sizeof(cat->name) - 1);
00323
if (config->
root) {
00324
00325 pcat = config->
root;
00326
while(pcat->next)
00327 pcat = pcat->
next;
00328 pcat->
next = cat;
00329 }
else {
00330
00331 config->
root = cat;
00332 }
00333
00334 }
00335
if (!newvar) {
00336 v = cat->
root;
00337 pv = NULL;
00338
while (v) {
00339
if (variable == v->name)
00340
break;
00341 pv = v;
00342 v=v->
next;
00343 }
00344
if (!v) {
00345
00346 bv = NULL;
00347 bpv = NULL;
00348 v = cat->root;
00349 pv = NULL;
00350
while (v) {
00351
if (!strcasecmp(variable, v->name)) {
00352 bv = v;
00353 bpv = pv;
00354 }
00355 pv = v;
00356 v=v->
next;
00357 }
00358 v = bv;
00359 }
00360 }
else v = NULL;
00361
if (v && move) {
00362
00363
if (pv)
00364 pv->
next = v->
next;
00365
else
00366 cat->root = v->
next;
00367 v->
next = NULL;
00368 }
00369
if (!v) {
00370 v =
malloc(
sizeof(
struct ast_variable));
00371
if (!v)
00372
return NULL;
00373 memset(v, 0,
sizeof(
struct ast_variable));
00374 v->name =
strdup(variable);
00375 move = 1;
00376 }
00377
if (v->value)
00378
free(v->value);
00379
if (value)
00380 v->value =
strdup(value);
00381
else
00382 v->value =
strdup(
"");
00383
if (move) {
00384
if (cat->root) {
00385 pv = cat->root;
00386
while (pv->next)
00387 pv = pv->next;
00388 pv->next = v;
00389 }
else {
00390 cat->root = v;
00391 }
00392 }
00393
return v;
00394 }
00395
#endif
00396
00397 int ast_category_exist(
struct ast_config *config,
char *category_name)
00398 {
00399
struct ast_category *category = NULL;
00400
00401 category = config->
root;
00402
00403
while(category) {
00404
if (!strcasecmp(category->name,category_name))
00405
return 1;
00406 category = category->
next;
00407 }
00408
00409
return 0;
00410 }
00411
00412
#ifdef PRESERVE_COMMENTS
00413
static struct ast_comment *build_comment(
char *cmt)
00414 {
00415
struct ast_comment *c;
00416
int len = strlen(cmt) + 1;
00417 c =
malloc(
sizeof(
struct ast_comment) + len);
00418
if (c) {
00419
00420 memset(c, 0,
sizeof(
struct ast_comment));
00421
00422 strcpy(c->cmt, cmt);
00423 }
00424
return c;
00425 }
00426
#endif
00427
00428
static struct ast_config *__ast_load(
char *configfile,
struct ast_config *tmp,
struct ast_category **_tmpc,
struct ast_variable **_last,
int includelevel
00429 #ifdef PRESERVE_COMMENTS
00430 ,
struct ast_comment_struct *acs
00431 #endif
00432 );
00433
00434
static int cfg_process(
struct ast_config *tmp,
struct ast_category **_tmpc,
struct ast_variable **_last,
char *buf,
int lineno,
char *configfile,
int includelevel
00435 #ifdef PRESERVE_COMMENTS
00436 ,
struct ast_comment_struct *acs
00437 #endif
00438 )
00439 {
00440
char *c;
00441
char *cur;
00442
char *arg=NULL;
00443
struct ast_config_reg *reg=NULL;
00444
struct ast_config *(*load_func)(
char *,
struct ast_config *,
struct ast_category **,
struct ast_variable **,
int
00445
#ifdef PRESERVE_COMMENTS
00446
,
struct ast_comment_struct *
00447
#endif
00448
);
00449
struct ast_variable *v;
00450
#ifdef PRESERVE_COMMENTS
00451
struct ast_comment *com = NULL;
00452
#endif
00453
int object;
00454
00455 c = strchr(buf,
';');
00456
if (c) {
00457 *c =
'\0';
00458
#ifdef PRESERVE_COMMENTS
00459
c++;
00460
if (*c !=
'!')
00461 com = build_comment(c);
00462
#endif
00463
}
00464 cur = strip(buf);
00465
if (!ast_strlen_zero(cur)) {
00466
00467
if (cur[0] ==
'[') {
00468
00469 c = strchr(cur,
']');
00470
if (c) {
00471 *c = 0;
00472 *_tmpc =
malloc(
sizeof(
struct ast_category));
00473
if (!*_tmpc) {
00474
ast_destroy(tmp);
00475
ast_log(LOG_WARNING,
00476
"Out of memory, line %d\n", lineno);
00477
return -1;
00478 }
00479 memset(*_tmpc, 0,
sizeof(
struct ast_category));
00480 strncpy((*_tmpc)->name, cur+1,
sizeof((*_tmpc)->name) - 1);
00481 (*_tmpc)->root = NULL;
00482
#ifdef PRESERVE_COMMENTS
00483
(*_tmpc)->precomments = acs->root;
00484 (*_tmpc)->sameline = com;
00485
#endif
00486
if (!tmp->
prev)
00487 tmp->
root = *_tmpc;
00488
else
00489 tmp->
prev->
next = *_tmpc;
00490
00491 tmp->
prev = *_tmpc;
00492
#ifdef PRESERVE_COMMENTS
00493
acs->
root = NULL;
00494 acs->prev = NULL;
00495
#endif
00496
*_last = NULL;
00497 }
else {
00498
ast_log(LOG_WARNING,
00499
"parse error: no closing ']', line %d of %s\n", lineno, configfile);
00500 }
00501 }
else if (cur[0] ==
'#') {
00502
00503 cur++;
00504 c = cur;
00505
while(*c && (*c > 32)) c++;
00506
if (*c) {
00507 *c =
'\0';
00508 c++;
00509
00510
while(*c && (*c < 33)) c++;
00511
if (!*c)
00512 c = NULL;
00513 }
else
00514 c = NULL;
00515
if (!strcasecmp(cur,
"include")) {
00516
00517
if (c) {
00518
while((*c ==
'<') || (*c ==
'>') || (*c ==
'\"')) c++;
00519
00520 cur = c;
00521
while (!ast_strlen_zero(cur)) {
00522 c = cur + strlen(cur) - 1;
00523
if ((*c ==
'>') || (*c ==
'<') || (*c ==
'\"'))
00524 *c =
'\0';
00525
else
00526
break;
00527 }
00528
00529
if((c = strchr(cur,
':'))) {
00530 *c =
'\0';
00531 c++;
00532 arg = c;
00533 }
00534
00535
if (includelevel <
MAX_INCLUDE_LEVEL) {
00536
if(arg && cur) {
00537 load_func = NULL;
00538
if(ast_cust_config_list)
00539 reg =
get_ast_cust_config(cur);
00540
if(reg && reg->func)
00541 load_func = reg->func;
00542
if(load_func) {
00543
ast_log(LOG_NOTICE,
"External Include '%s' via '%s' config engine\n",arg,cur);
00544 load_func(arg,tmp, _tmpc, _last, includelevel
00545 #ifdef PRESERVE_COMMENTS
00546 ,&acs
00547 #endif
00548 );
00549 }
00550
else
00551
ast_log(LOG_WARNING,
"Cant Find Registered Config Engine [%s] for [%s]\n",cur,arg);
00552 }
00553
else {
00554 __ast_load(cur, tmp, _tmpc, _last, includelevel + 1
00555 #ifdef PRESERVE_COMMENTS
00556 ,acs
00557 #endif
00558 );
00559 }
00560 }
else
00561
ast_log(LOG_WARNING,
"Maximum Include level (%d) exceeded\n", includelevel);
00562 }
else
00563
ast_log(LOG_WARNING,
"Directive '#include' needs an argument (filename) at line %d of %s\n", lineno, configfile);
00564
00565 }
00566
else
00567
ast_log(LOG_WARNING,
"Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile);
00568 }
else {
00569
00570
if (!*_tmpc) {
00571
ast_log(LOG_WARNING,
00572
"parse error: No category context for line %d of %s\n", lineno, configfile);
00573
ast_destroy(tmp);
00574
return -1;
00575 }
00576 c = strchr(cur,
'=');
00577
if (c) {
00578 *c = 0;
00579 c++;
00580
00581
if (*c==
'>') {
00582 object = 1;
00583 c++;
00584 }
else
00585 object = 0;
00586 v =
malloc(
sizeof(
struct ast_variable));
00587
if (v) {
00588 memset(v, 0,
sizeof(
struct ast_variable));
00589 v->next = NULL;
00590 v->name =
strdup(strip(cur));
00591 v->value =
strdup(strip(c));
00592 v->lineno = lineno;
00593 v->object = object;
00594
00595
#ifdef PRESERVE_COMMENTS
00596
v->precomments = acs->root;
00597 v->sameline = com;
00598 acs->prev = NULL;
00599 acs->root = NULL;
00600
#endif
00601
v->blanklines = 0;
00602
if (*_last)
00603 (*_last)->next = v;
00604
else
00605 (*_tmpc)->root = v;
00606 *_last = v;
00607 }
else {
00608
ast_destroy(tmp);
00609
ast_log(LOG_WARNING,
"Out of memory, line %d\n", lineno);
00610
return -1;
00611 }
00612 }
else {
00613
ast_log(LOG_WARNING,
"No '=' (equal sign) in line %d of %s\n", lineno, configfile);
00614 }
00615
00616 }
00617 }
else {
00618
00619
#ifdef PRESERVE_COMMENTS
00620
if (com) {
00621
if (acs->prev)
00622 acs->prev->next = com;
00623
else
00624 acs->root = com;
00625 acs->prev = com;
00626 }
else {
00627
if (*_last)
00628 (*_last)->blanklines++;
00629 }
00630
#endif
00631
}
00632
return 0;
00633 }
00634
00635
#ifdef PRESERVE_COMMENTS
00636
static void dump_comments(FILE *f,
struct ast_comment *comment)
00637 {
00638
while (comment) {
00639 fprintf(f,
";%s", comment->
cmt);
00640 comment = comment->
next;
00641 }
00642 }
00643
#endif
00644
00645 int ast_save(
char *configfile,
struct ast_config *cfg,
char *generator)
00646 {
00647 FILE *f;
00648
char fn[256];
00649
char date[256]=
"";
00650 time_t t;
00651
struct ast_variable *var;
00652
struct ast_category *cat;
00653
int blanklines = 0;
00654
if (configfile[0] ==
'/') {
00655 strncpy(fn, configfile,
sizeof(fn)-1);
00656 }
else {
00657 snprintf(fn,
sizeof(fn),
"%s/%s",
AST_CONFIG_DIR, configfile);
00658 }
00659 time(&t);
00660 strncpy(date, ctime(&t),
sizeof(date) - 1);
00661
if ((f = fopen(fn,
"w"))) {
00662
if ((
option_verbose > 1) && !
option_debug)
00663
ast_verbose(
VERBOSE_PREFIX_2 "Saving '%s': ", fn);
00664 fprintf(f,
";!\n");
00665 fprintf(f,
";! Automatically generated configuration file\n");
00666 fprintf(f,
";! Filename: %s (%s)\n", configfile, fn);
00667 fprintf(f,
";! Generator: %s\n", generator);
00668 fprintf(f,
";! Creation Date: %s", date);
00669 fprintf(f,
";!\n");
00670 cat = cfg->
root;
00671
while(cat) {
00672
#ifdef PRESERVE_COMMENTS
00673
00674 dump_comments(f, cat->precomments);
00675
#endif
00676
00677
#ifdef PRESERVE_COMMENTS
00678
if (cat->sameline)
00679 fprintf(f,
"[%s] ; %s\n", cat->name, cat->sameline->cmt);
00680
else
00681
#endif
00682
fprintf(f,
"[%s]\n", cat->name);
00683 var = cat->root;
00684
while(var) {
00685
#ifdef PRESERVE_COMMENTS
00686
dump_comments(f, var->precomments);
00687
#endif
00688
if (var->sameline)
00689 fprintf(f,
"%s %s %s ; %s\n", var->name, (var->object ?
"=>" :
"="), var->value, var->sameline->cmt);
00690
else
00691 fprintf(f,
"%s %s %s\n", var->name, (var->object ?
"=>" :
"="), var->value);
00692
if (var->blanklines) {
00693 blanklines = var->blanklines;
00694
while (blanklines) {
00695 fprintf(f,
"\n");
00696 blanklines--;
00697 }
00698 }
00699
00700 var = var->next;
00701 }
00702
#if 0
00703
00704 fprintf(f,
"\n");
00705
#endif
00706
cat = cat->next;
00707 }
00708
#ifdef PRESERVE_COMMENTS
00709
dump_comments(f, cfg->trailingcomments);
00710
#endif
00711
}
else {
00712
if (
option_debug)
00713 printf(
"Unable to open for writing: %s\n", fn);
00714
else if (
option_verbose > 1)
00715 printf(
"Unable to write (%s)", strerror(errno));
00716
return -1;
00717 }
00718 fclose(f);
00719
return 0;
00720 }
00721
00722
static struct ast_config *__ast_load(
char *configfile,
struct ast_config *tmp,
struct ast_category **_tmpc,
struct ast_variable **_last,
int includelevel
00723 #ifdef PRESERVE_COMMENTS
00724 ,
struct ast_comment_struct *acs
00725 #endif
00726 )
00727 {
00728
char fn[256];
00729
char buf[8192];
00730 FILE *f;
00731
int lineno=0;
00732
int master=0;
00733
struct ast_config_reg *reg=NULL;
00734
struct ast_config *(*load_func)(
char *,
struct ast_config *,
struct ast_category **,
struct ast_variable **,
int
00735
#ifdef PRESERVE_COMMENTS
00736
,
struct ast_comment_struct *
00737
#endif
00738
);
00739
00740 load_func=NULL;
00741
if (strcmp(configfile,config_conf_file) && strcmp(configfile,
"asterisk.conf") && ast_cust_config_list) {
00742
if (
global_load_func) {
00743 load_func =
global_load_func;
00744 }
else {
00745 reg =
get_ast_cust_config_keyword(configfile);
00746
if (reg && reg->func) {
00747 load_func = reg->func;
00748 }
else {
00749 reg =
get_ast_cust_config_keyword(
"global");
00750
if (reg && reg->func)
00751
global_load_func = load_func = reg->func;
00752 }
00753 }
00754
00755
if (load_func) {
00756
ast_log(LOG_NOTICE,
"Loading Config %s via %s engine\n",configfile,reg && reg->name ? reg->name :
"global");
00757 tmp = load_func(configfile,tmp, _tmpc, _last, includelevel
00758 #ifdef PRESERVE_COMMENTS
00759 ,&acs
00760 #endif
00761 );
00762
00763
if (tmp)
00764
return tmp;
00765 }
00766 }
00767
00768
if (configfile[0] ==
'/') {
00769 strncpy(fn, configfile,
sizeof(fn)-1);
00770 }
else {
00771 snprintf(fn,
sizeof(fn),
"%s/%s", (
char *)ast_config_AST_CONFIG_DIR, configfile);
00772 }
00773
if ((
option_verbose > 1) && !
option_debug) {
00774
ast_verbose( VERBOSE_PREFIX_2
"Parsing '%s': ", fn);
00775 fflush(stdout);
00776 }
00777
if ((f = fopen(fn,
"r"))) {
00778
if (
option_debug)
00779
ast_log(LOG_DEBUG,
"Parsing %s\n", fn);
00780
else if (
option_verbose > 1)
00781
ast_verbose(
"Found\n");
00782
if (!tmp) {
00783 tmp =
malloc(
sizeof(
struct ast_config));
00784
if (tmp)
00785 memset(tmp, 0,
sizeof(
struct ast_config));
00786
00787 master = 1;
00788 }
00789
if (!tmp) {
00790
ast_log(LOG_WARNING,
"Out of memory\n");
00791 fclose(f);
00792
return NULL;
00793 }
00794
while(!feof(f)) {
00795 lineno++;
00796
if (fgets(buf,
sizeof(buf), f)) {
00797
if (cfg_process(tmp, _tmpc, _last, buf, lineno, configfile, includelevel
00798 #ifdef PRESERVE_COMMENTS
00799 , acs
00800 #endif
00801 )) {
00802 fclose(f);
00803
return NULL;
00804 }
00805 }
00806 }
00807 fclose(f);
00808 }
else {
00809
if (
option_debug)
00810
ast_log(LOG_DEBUG,
"No file to parse: %s\n", fn);
00811
else if (
option_verbose > 1)
00812
ast_verbose(
"Not found (%s)\n", strerror(errno));
00813 }
00814
#ifdef PRESERVE_COMMENTS
00815
if (master) {
00816
00817 tmp->trailingcomments = acs->
root;
00818 acs->
root = NULL;
00819 acs->prev = NULL;
00820 }
00821
#endif
00822
return tmp;
00823 }
00824
00825 struct ast_config_reg *
get_ast_cust_config_keyword(
char *name)
00826 {
00827
struct ast_config_reg *reg,*ret=NULL;
00828
int x=0;
00829
ast_mutex_lock(&ast_cust_config_lock);
00830
for (reg=ast_cust_config_list;reg && !ret;reg=reg->
next) {
00831
for (x=0;x<reg->keycount && !ret ;x++) {
00832
if (!strcmp(reg->keywords[x],name))
00833 ret=reg;
00834 }
00835 }
00836
ast_mutex_unlock(&ast_cust_config_lock);
00837
return ret;
00838 }
00839
00840 struct ast_config_reg *
get_ast_cust_config(
char *name)
00841 {
00842
struct ast_config_reg *ptr=NULL;
00843
ast_mutex_lock(&ast_cust_config_lock);
00844
for (ptr=ast_cust_config_list;ptr;ptr=ptr->
next) {
00845
if (!strcmp(name,ptr->name))
00846
break;
00847 }
00848
ast_mutex_unlock(&ast_cust_config_lock);
00849
return ptr;
00850 }
00851
00852 void ast_config_destroy_all(
void)
00853 {
00854
struct ast_config_reg *
key;
00855
ast_mutex_lock(&ast_cust_config_lock);
00856
for (
key=ast_cust_config_list;
key;
key=
key->next) {
00857
ast_config_deregister(
key);
00858 }
00859 ast_cust_config_list = NULL;
00860
ast_mutex_unlock(&ast_cust_config_lock);
00861 }
00862
00863 struct ast_config_reg *
get_config_registrations(
void)
00864 {
00865
return ast_cust_config_list;
00866 }
00867
00868 int ast_config_register(
struct ast_config_reg *
new)
00869 {
00870
struct ast_config_reg *ptr;
00871
ast_mutex_lock(&ast_cust_config_lock);
00872
new->keycount = 0;
00873
if (!ast_cust_config_list) {
00874 ast_cust_config_list =
new;
00875 }
else {
00876
for(ptr=ast_cust_config_list;ptr->
next;ptr=ptr->
next);
00877 ptr->
next =
new;
00878 }
00879
ast_mutex_unlock(&ast_cust_config_lock);
00880
ast_log(
LOG_NOTICE,
"Registered Config Engine %s\n",new->
name);
00881
return 1;
00882 }
00883
00884 int ast_config_deregister(
struct ast_config_reg *del)
00885 {
00886
struct ast_config_reg *ptr=NULL,*last=NULL;
00887
ast_mutex_lock(&ast_cust_config_lock);
00888
for (ptr=ast_cust_config_list;ptr;ptr=ptr->
next) {
00889
if (ptr == del) {
00890
if (last && ptr->next) {
00891 last->next = ptr->next;
00892 }
else if (last && ! ptr->next) {
00893 last->next = NULL;
00894 }
else if (!last && ptr->next) {
00895 ast_cust_config_list = ptr->
next;
00896 }
else if (!last && !ptr->next) {
00897 ast_cust_config_list = NULL;
00898 }
00899 }
00900 last = ptr;
00901 }
00902
ast_mutex_unlock(&ast_cust_config_lock);
00903
return 0;
00904 }
00905
00906 int ast_cust_config_active(
void) {
00907
return (ast_cust_config >0) ? 1 : 0;
00908 }
00909
00910 struct ast_config *
ast_load(
char *configfile)
00911 {
00912
struct ast_category *tmpc=NULL;
00913
struct ast_variable *last = NULL;
00914
00915
00916
#ifdef PRESERVE_COMMENTS
00917
struct ast_comment_struct acs = { NULL, NULL };
00918
#endif
00919
00920
00921
return __ast_load(configfile, NULL, &tmpc, &last, 0
00922 #ifdef PRESERVE_COMMENTS
00923 ,&acs
00924 #endif
00925 );
00926 }
00927
00928 char *
ast_category_browse(
struct ast_config *config,
char *prev)
00929 {
00930
struct ast_category *cat;
00931
if (!prev) {
00932
if (config->
root)
00933
return config->
root->
name;
00934
else
00935
return NULL;
00936 }
00937 cat = config->
root;
00938
while(cat) {
00939
if (cat->name == prev) {
00940
if (cat->next)
00941
return cat->
next->
name;
00942
else
00943
return NULL;
00944 }
00945 cat = cat->next;
00946 }
00947 cat = config->
root;
00948
while(cat) {
00949
if (!strcasecmp(cat->name, prev)) {
00950
if (cat->next)
00951
return cat->
next->
name;
00952
else
00953
return NULL;
00954 }
00955 cat = cat->next;
00956 }
00957
return NULL;
00958 }
00959
00960
00961 struct ast_config *
ast_new_config(
void)
00962 {
00963
struct ast_config *config;
00964 config =
malloc(
sizeof(
struct ast_config));
00965 memset(config,0,
sizeof(
struct ast_config));
00966
return config;
00967 }
00968
00969
00970
00971 struct ast_category *
ast_new_category(
char *name)
00972 {
00973
struct ast_category *category;
00974 category =
malloc(
sizeof(
struct ast_category));
00975
if (category) {
00976 memset(category,0,
sizeof(
struct ast_category));
00977 strncpy(category->name,name,
sizeof(category->name) - 1);
00978 }
00979
return category;
00980 }
00981
00982
00983 struct ast_variable *
ast_new_variable(
char *name,
char *value)
00984 {
00985
struct ast_variable *variable;
00986 variable =
malloc(
sizeof(
struct ast_variable));
00987
if (variable) {
00988 memset(variable,0,
sizeof(
struct ast_variable));
00989 variable->object=0;
00990 variable->name =
malloc(strlen(name)+1);
00991
if (variable->name) {
00992 strcpy(variable->name,name);
00993 variable->value =
malloc(strlen(value)+1);
00994
if (variable->value) {
00995 strcpy(variable->value,value);
00996 }
else {
00997
free(variable->name);
00998 variable->name = NULL;
00999 }
01000 }
01001 }
01002
if (!variable->value) {
01003
free(variable);
01004 variable = NULL;
01005 }
01006
01007
return variable;
01008 }
01009
01010 int ast_cust_config_register(
struct ast_config_reg *
new)
01011 {
01012
ast_config_register(
new);
01013
read_ast_cust_config();
01014
return 1;
01015 }
01016 int ast_cust_config_deregister(
struct ast_config_reg *
new)
01017 {
01018
ast_config_deregister(
new);
01019
read_ast_cust_config();
01020
return 1;
01021 }
01022
01023
static void clear_cust_keywords(
void)
01024 {
01025
struct ast_config_reg *
key;
01026
int x;
01027
ast_mutex_lock(&ast_cust_config_lock);
01028
for (
key=
get_config_registrations();
key;
key=
key->next) {
01029
for (x=0;x<
key->keycount;x++) {
01030
key->keywords[x][0] =
'\0';
01031 }
01032
key->keycount=0;
01033 }
01034
ast_mutex_unlock(&ast_cust_config_lock);
01035 }
01036
01037
static int config_command(
int fd,
int argc,
char **argv)
01038 {
01039
struct ast_config_reg *
key;
01040
int x;
01041
01042
ast_cli(fd,
"\n\n");
01043
ast_mutex_lock(&ast_cust_config_lock);
01044
for (
key=
get_config_registrations();
key;
key=
key->next) {
01045
ast_cli(fd,
"\nConfig Engine: %s\n",
key->name);
01046
for (x=0;x<
key->keycount;x++)
01047
ast_cli(fd,
"===>%s\n",
key->keywords[x]);
01048 }
01049
ast_mutex_unlock(&ast_cust_config_lock);
01050
ast_cli(fd,
"\n\n");
01051
01052
return 0;
01053 }
01054
01055
static struct ast_cli_entry config_command_struct = {
01056 {
"show",
"config",
"handles", NULL }, config_command,
01057
"Show Config Handles", NULL };
01058
01059 int register_config_cli()
01060 {
01061
return ast_cli_register(&config_command_struct);
01062 }
01063
01064 int read_ast_cust_config(
void)
01065 {
01066
char *cfg = config_conf_file;
01067
struct ast_config *config;
01068
struct ast_variable *v;
01069
struct ast_config_reg *ptr;
01070
struct ast_config_reg *test = NULL;
01071
01072 clear_cust_keywords();
01073 config =
ast_load(cfg);
01074
if (config) {
01075
for (v =
ast_variable_browse(config,
"settings");v;v=v->next) {
01076
01077 ptr =
get_ast_cust_config(v->value);
01078
if (ptr) {
01079
if (ptr->keycount >=
CONFIG_KEYWORD_ARRAYLEN) {
01080
ast_log(
LOG_WARNING,
"Max Number of Bindings exceeded for %s->%s %d/%d\n",v->name,v->value,ptr->keycount,
CONFIG_KEYWORD_ARRAYLEN);
01081 }
else {
01082
if (strcmp(v->name,config_conf_file) && strcmp(v->name,
"asterisk.conf")) {
01083
if (!(test =
get_ast_cust_config_keyword(v->name))) {
01084
ast_log(
LOG_NOTICE,
"Binding: %s to %s\n",v->name,v->value);
01085 strncpy(ptr->keywords[ptr->keycount],v->name,
sizeof(ptr->keywords[ptr->keycount]) - 1);
01086 ptr->keywords[ptr->keycount][
sizeof(ptr->keywords[ptr->keycount])-1] =
'\0';
01087 ptr->keycount++;
01088 }
01089 }
else {
01090
ast_log(
LOG_WARNING,
"Cannot bind %s, Permission Denied\n",v->name);
01091 }
01092 }
01093 }
01094 }
01095
01096
ast_destroy(config);
01097 }
01098
01099
return 0;
01100 }