== AsteriskSource/PbxConfig == * pbx/pbx_config.c * load_module * static char *config = "extensions.conf"; * cfg = ast_load(config); * static_config 설정 * general category 에 static variable 이 있으면, 그 값에 따라 설정 * cxt = ast_category_browse(cfg, NULL); * 첫번째 category struct pointer return * while(cxt) * category 명이 general 이면 * cxt = ast_category_browse(cfg, cxt); * 다음 category 명을 ctx 에 assign * continue * if ((con=ast_context_create(cxt))) * category 명이 general 이 아니면, 이 이름에 속하는 ast_struct con 을 생성한다. {{{ struct ast_context { char name[AST_MAX_EXTENSION]; pthread_mutex_t lock; struct ast_exten *root; struct ast_context *next; }; }}} * * * * ast_context struct 인 con 에 속하는 variavle 들을 읽어서 con 에 추가한다. * v = ast_variable_browse(cfg, cxt); * while(v) * tc = strdup(v->value); * ext, pri, appl, data * ast_add_extension2(con, 0, ext, atoi(pri), appl, strdup(data), free) * v = v->next; * free(tc); * cxt = ast_category_browse(cfg, cxt); * ctx 에 다음 category struct pointer 설정 * ast_destroy(cfg); * return 0; * pbx.c {{{ /* An extension context */ struct ast_context { /* Name of the context */ char name[AST_MAX_EXTENSION]; /* A lock to prevent multiple threads from clobbering the context */ pthread_mutex_t lock; /* The root of the list of extensions */ struct ast_exten *root; /* Link them together */ struct ast_context *next; }; }}} * struct ast_context *ast_context_create(char *name) * 이미 존재하는가 점검 * tmp = malloc(sizeof(struct ast_context)); * strncpy(tmp->name, name, sizeof(tmp->name)); * category 명을 tpm->name 에 assign 한다. * contexts 와 연결 * return tmp; * int ast_add_extension2(struct ast_context *con, int replace, char *extension, int priority, char *application, void *data, void (*datad)(void *)) {{{ /* An extension */ struct ast_exten { char exten[AST_MAX_EXTENSION]; int priority; /* An extension */ struct ast_context *parent; /* Application to execute */ char app[AST_MAX_EXTENSION]; /* Data to use */ void *data; /* Data destructor */ void (*datad)(void *); /* Next highest priority with our extension */ struct ast_exten *peer; /* Extension with a greater ID */ struct ast_exten *next; }; }}} * tmp = malloc(sizeof(struct ast_exten)); * tmp struct 에 필요한 값 설정 * e = con->root; * while(e) * res= strcasecmp(e->exten, extension); * if (res == 0) * 이미 같은 extension 이 등록되어 있는 경우 * while(e) * if (e->priority == tmp->priority) * else if (e->priority > tmp->priority) * } * ep = e; * e = e->peer; * ep->peer = tmp; * return 0; * else if (res > 0) * con에 이미 등록된 extension 보다 새로운 extension 이 lexically 크면 * Insert ourselves just before 'e' * tmp->next = e; * el->next = tmp; or con->root = tmp; * return 0; * el = e; * e = e->next; * el->next = tmp; or con->root = tmp; * return 0; == config.c == * struct ast_config *ast_load(char *configfile) * configfile 이 / 로 시작하면 fn 에 그대로 복사하고, 아니면 AST_CONFIG_DIR 을 앞에다 붙여서 fn 에 복사한다. * fn 파일을 open 한 후, 한 줄씩 읽어서 필요한 작업을 한다. * ast_config struct 인 tmp 를 만든다. {{{ struct ast_config { /* Maybe this structure isn't necessary but we'll keep it for now */ struct ast_category *root; }; }}} * [ 으로 시작하면 * ast_category struct 인 tempc 를 만든다. {{{ struct ast_category { char name[80]; struct ast_variable *root; struct ast_category *next; }; }}} * * tempc->name 에 [] 사이의 이름을 asiign 한다. * temp->root 에는 새로이 만들어진 tempc 를 assign 한다. * 앞에서 만들어진 tempc 를 새로 만들어진 tempc->next 에 assign 한다. * 즉 [ 로 시작하여 ] 로 끝나는 줄은 category list 로 연결한다. * [ 로 시작하지 않고 = 이 있으면, * ast_variable struct 인 v 를 만든다. {{{ struct ast_variable { char *name; char *value; struct ast_variable *next; }; }}} * * = 앞부분은 name 에 뒷부분은 value 에 assign 한다. * category 의 root 에 v 를 assign 한다. * variable list 로 연결시킨다. * temp 를 return 한다. * char *ast_category_browse(struct ast_config *config, char *prev) * prev 가 NULL 이면 config->root->name 을 return * prev 이름의 category 가 있으면, 다음 caterogy 의 name 을 return * struct ast_variable *ast_variable_browse(struct ast_config *config, char *category) * 해당 category 의 첫번째 ast_variable struct 를 return * char *ast_variable_retrieve(struct ast_config *config, char *category, char *value) * 해당되는 category 중 해당되는 variable 의 value 를 return