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