This source file includes following definitions.
- FT_DECLARE
- FT_DECLARE
- ftdm_config_open_file
- ftdm_config_close_file
- ftdm_config_next_pair
- FT_DECLARE
- FT_DECLARE
- FT_DECLARE
- FT_DECLARE
- FT_DECLARE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 #include "private/ftdm_core.h"
39
40 #ifndef FTDM_MOD_DIR
41 #define FTDM_MOD_DIR "."
42 #endif
43
44 #define FTDM_MAX_CONF_DIR 512
45
46 static char g_ftdm_config_dir[FTDM_MAX_CONF_DIR] = FTDM_CONFIG_DIR;
47 static char g_ftdm_mod_dir[FTDM_MAX_CONF_DIR] = FTDM_MOD_DIR;
48
49 FT_DECLARE(void) ftdm_global_set_mod_directory(const char *path)
50 {
51 snprintf(g_ftdm_mod_dir, sizeof(g_ftdm_mod_dir), "%s", path);
52 ftdm_log(FTDM_LOG_DEBUG, "New mod directory: %s\n", g_ftdm_mod_dir);
53 }
54
55 FT_DECLARE(void) ftdm_global_set_config_directory(const char *path)
56 {
57 snprintf(g_ftdm_config_dir, sizeof(g_ftdm_config_dir), "%s", path);
58 ftdm_log(FTDM_LOG_DEBUG, "New config directory: %s\n", g_ftdm_config_dir);
59 }
60
61 int ftdm_config_open_file(ftdm_config_t *cfg, const char *file_path)
62 {
63 FILE *f;
64 const char *path = NULL;
65 char path_buf[1024];
66
67 if (file_path[0] == '/') {
68 path = file_path;
69 } else {
70 snprintf(path_buf, sizeof(path_buf), "%s%s%s", g_ftdm_config_dir, FTDM_PATH_SEPARATOR, file_path);
71 path = path_buf;
72 }
73
74 if (!path) {
75 return 0;
76 }
77
78 memset(cfg, 0, sizeof(*cfg));
79 cfg->lockto = -1;
80 ftdm_log(FTDM_LOG_DEBUG, "Configuration file is %s.\n", path);
81 f = fopen(path, "r");
82
83 if (!f) {
84 if (file_path[0] != '/') {
85 int last = -1;
86 char *var, *val;
87
88 snprintf(path_buf, sizeof(path_buf), "%s%sfreetdm.conf", g_ftdm_config_dir, FTDM_PATH_SEPARATOR);
89 path = path_buf;
90
91 if ((f = fopen(path, "r")) == 0) {
92 return 0;
93 }
94
95 cfg->file = f;
96 ftdm_set_string(cfg->path, path);
97
98 while (ftdm_config_next_pair(cfg, &var, &val)) {
99 if ((cfg->sectno != last) && !strcmp(cfg->section, file_path)) {
100 cfg->lockto = cfg->sectno;
101 return 1;
102 }
103 }
104
105 ftdm_config_close_file(cfg);
106 memset(cfg, 0, sizeof(*cfg));
107 return 0;
108 }
109
110 return 0;
111 } else {
112 cfg->file = f;
113 ftdm_set_string(cfg->path, path);
114 return 1;
115 }
116 }
117
118 void ftdm_config_close_file(ftdm_config_t *cfg)
119 {
120
121 if (cfg->file) {
122 fclose(cfg->file);
123 }
124
125 memset(cfg, 0, sizeof(*cfg));
126 }
127
128
129
130 int ftdm_config_next_pair(ftdm_config_t *cfg, char **var, char **val)
131 {
132 int ret = 0;
133 char *p, *end;
134
135 *var = *val = NULL;
136
137 if (!cfg->path) {
138 return 0;
139 }
140
141 for (;;) {
142 cfg->lineno++;
143
144 if (!fgets(cfg->buf, sizeof(cfg->buf), cfg->file)) {
145 ret = 0;
146 break;
147 }
148 *var = cfg->buf;
149
150 if (**var == '[' && (end = strchr(*var, ']')) != 0) {
151 *end = '\0';
152 (*var)++;
153 if (**var == '+') {
154 (*var)++;
155 ftdm_copy_string(cfg->section, *var, sizeof(cfg->section));
156 cfg->sectno++;
157
158 if (cfg->lockto > -1 && cfg->sectno != cfg->lockto) {
159 break;
160 }
161 cfg->catno = 0;
162 cfg->lineno = 0;
163 *var = (char *) "";
164 *val = (char *) "";
165 return 1;
166 } else {
167 ftdm_copy_string(cfg->category, *var, sizeof(cfg->category));
168 cfg->catno++;
169 }
170 continue;
171 }
172
173
174
175 if (**var == '#' || **var == ';' || **var == '\n' || **var == '\r') {
176 continue;
177 }
178
179 if (!strncmp(*var, "__END__", 7)) {
180 break;
181 }
182
183
184 if ((end = strchr(*var, ';')) && *(end+1) == *end) {
185 *end = '\0';
186 end--;
187 } else if ((end = strchr(*var, '\n')) != 0) {
188 if (*(end - 1) == '\r') {
189 end--;
190 }
191 *end = '\0';
192 }
193
194 p = *var;
195 while ((*p == ' ' || *p == '\t') && p != end) {
196 *p = '\0';
197 p++;
198 }
199 *var = p;
200
201
202 if ((*val = strchr(*var, '=')) == 0) {
203 ret = -1;
204
205 continue;
206 } else {
207 p = *val - 1;
208 *(*val) = '\0';
209 (*val)++;
210 if (*(*val) == '>') {
211 *(*val) = '\0';
212 (*val)++;
213 }
214
215 while ((*p == ' ' || *p == '\t') && p != *var) {
216 *p = '\0';
217 p--;
218 }
219
220 p = *val;
221 while ((*p == ' ' || *p == '\t') && p != end) {
222 *p = '\0';
223 p++;
224 }
225 *val = p;
226 ret = 1;
227 break;
228 }
229 }
230
231
232 return ret;
233
234 }
235
236 FT_DECLARE (int) ftdm_config_get_cas_bits(char *strvalue, unsigned char *outbits)
237 {
238 char cas_bits[5];
239 unsigned char bit = 0x8;
240 int x = 0;
241 char *double_colon = strchr(strvalue, ':');
242 if (!double_colon) {
243 ftdm_log(FTDM_LOG_ERROR, "No CAS bits specified: %s, :xxxx definition expected, where x is 1 or 0\n", strvalue);
244 return -1;
245 }
246 double_colon++;
247 *outbits = 0;
248 cas_bits[4] = 0;
249 if (sscanf(double_colon, "%c%c%c%c", &cas_bits[0], &cas_bits[1], &cas_bits[2], &cas_bits[3]) != 4) {
250 ftdm_log(FTDM_LOG_ERROR, "Invalid CAS bits specified: '%s', :xxxx definition expected, where x is 1 or 0\n", double_colon);
251 return -1;
252 }
253 ftdm_log(FTDM_LOG_DEBUG, "CAS bits specification found: %s\n", cas_bits);
254 for (; cas_bits[x]; x++) {
255 if ('1' == cas_bits[x]) {
256 *outbits |= bit;
257 } else if ('0' != cas_bits[x]) {
258 ftdm_log(FTDM_LOG_ERROR, "Invalid CAS pattern specified: %s, just 0 or 1 allowed for each bit\n");
259 return -1;
260 }
261 bit >>= 1;
262 }
263 return 0;
264 }
265
266 #define PARAMETERS_CHUNK_SIZE 20
267 FT_DECLARE(ftdm_status_t) ftdm_conf_node_create(const char *name, ftdm_conf_node_t **node, ftdm_conf_node_t *parent)
268 {
269 ftdm_conf_node_t *newnode;
270 ftdm_conf_node_t *sibling = NULL;
271
272 ftdm_assert_return(name != NULL, FTDM_FAIL, "null node name");
273
274 newnode = ftdm_calloc(1, sizeof(**node));
275 if (!newnode) {
276 return FTDM_MEMERR;
277 }
278
279 strncpy(newnode->name, name, sizeof(newnode->name)-1);
280 newnode->name[sizeof(newnode->name)-1] = 0;
281
282 newnode->parameters = ftdm_calloc(PARAMETERS_CHUNK_SIZE, sizeof(*newnode->parameters));
283 if (!newnode->parameters) {
284 ftdm_safe_free(newnode);
285 return FTDM_MEMERR;
286 }
287 newnode->t_parameters = PARAMETERS_CHUNK_SIZE;
288
289 if (parent) {
290
291 newnode->parent = parent;
292
293
294 if (!parent->child) {
295
296 parent->child = newnode;
297 } else {
298 if (!parent->last) {
299
300 parent->last = newnode;
301 parent->child->next = newnode;
302 newnode->prev = parent->child;
303 } else {
304
305 sibling = parent->last;
306 sibling->next = newnode;
307 parent->last = newnode;
308 newnode->prev = sibling;
309 }
310 }
311 }
312
313 *node = newnode;
314
315 return FTDM_SUCCESS;
316 }
317
318 FT_DECLARE(ftdm_status_t) ftdm_conf_node_add_param(ftdm_conf_node_t *node, const char *param, const char *val)
319 {
320 void *newparameters;
321
322 ftdm_assert_return(param != NULL, FTDM_FAIL, "param is null");
323 ftdm_assert_return(val != NULL, FTDM_FAIL, "val is null");
324
325 if (node->n_parameters == node->t_parameters) {
326 newparameters = ftdm_realloc(node->parameters, (node->t_parameters + PARAMETERS_CHUNK_SIZE) * sizeof(*node->parameters));
327 if (!newparameters) {
328 return FTDM_MEMERR;
329 }
330 node->parameters = newparameters;
331 node->t_parameters = node->n_parameters + PARAMETERS_CHUNK_SIZE;
332 }
333 node->parameters[node->n_parameters].var = param;
334 node->parameters[node->n_parameters].val = val;
335 node->n_parameters++;
336 return FTDM_SUCCESS;
337 }
338
339 FT_DECLARE(ftdm_status_t) ftdm_conf_node_destroy(ftdm_conf_node_t *node)
340 {
341 ftdm_conf_node_t *curr = NULL;
342 ftdm_conf_node_t *child = node->child;
343 while (child) {
344 curr = child;
345 child = curr->next;
346 ftdm_conf_node_destroy(curr);
347 }
348 ftdm_free(node->parameters);
349 ftdm_free(node);
350 return FTDM_SUCCESS;
351 }
352
353 FT_DECLARE(char *) ftdm_build_dso_path(const char *name, char *path, ftdm_size_t len)
354 {
355 #ifdef WIN32
356 const char *ext = ".dll";
357
358 #elif defined (MACOSX) || defined (DARWIN)
359 const char *ext = ".dylib";
360
361 #else
362 const char *ext = ".so";
363
364 #endif
365 if (*name == *FTDM_PATH_SEPARATOR) {
366 snprintf(path, len, "%s%s", name, ext);
367 } else {
368 snprintf(path, len, "%s%s%s%s", g_ftdm_mod_dir, FTDM_PATH_SEPARATOR, name, ext);
369 }
370 return path;
371 }
372
373
374
375
376
377
378
379
380
381
382