ff17b9663e0acd40ae8d27cc6d2bc3123b2b7395
[asterisk/asterisk.git] / utils / extconf.c
1 /*  
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2006, Digium, Inc.
5  *
6  * Steve Murphy <murf@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19
20 /*
21  *
22  * A condensation of the pbx_config stuff, to read into exensions.conf, and provide an interface to the data there,
23  * for operations outside of asterisk. A huge, awful hack.
24  *
25  */
26 #include "asterisk.h"
27
28 #undef DEBUG_THREADS
29
30 #include "asterisk/compat.h"
31 #include "asterisk/paths.h"     /* we use AST_CONFIG_DIR */
32
33 #include <errno.h>
34 #include <time.h>
35 #include <sys/stat.h>
36 #include <sys/types.h>
37 #include <sys/time.h>
38 #include <sys/resource.h>
39 #include <sys/wait.h>
40 #include <stdarg.h>
41 #include <string.h>
42 #include <locale.h>
43 #include <ctype.h>
44 #if !defined(SOLARIS) && !defined(__CYGWIN__)
45 #include <err.h>
46 #endif
47 #include <regex.h>
48 #include <limits.h>
49 #include <pthread.h>
50 #include <netdb.h>
51 #include <sys/param.h>
52 #include <signal.h>
53
54 static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__((format(printf, 5, 6)));
55 void ast_verbose(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
56
57 #define ASINCLUDE_GLOB 1
58 #ifdef AST_INCLUDE_GLOB
59
60 #if !defined(GLOB_ABORTED)
61 #define GLOB_ABORTED GLOB_ABEND
62 #endif
63
64 # include <glob.h>
65 #endif
66
67 #define AST_API_MODULE  1 /* gimme the inline defs! */
68 struct ast_channel 
69 {
70         char x; /* basically empty! */
71 };
72
73
74
75 #include "asterisk/inline_api.h"
76 #include "asterisk/endian.h"
77 #include "asterisk/ast_expr.h"
78
79 /* logger.h */
80
81 #define EVENTLOG "event_log"
82 #define QUEUELOG        "queue_log"
83
84 #define DEBUG_M(a) { \
85         a; \
86 }
87
88 #define VERBOSE_PREFIX_1 " "
89 #define VERBOSE_PREFIX_2 "  == "
90 #define VERBOSE_PREFIX_3 "    -- "
91 #define VERBOSE_PREFIX_4 "       > "
92
93 void ast_backtrace(void);
94
95 void ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt, ...)
96         __attribute__((format(printf, 5, 6)));
97
98 /* IN CONFLICT: void ast_verbose(const char *fmt, ...)
99    __attribute__((format(printf, 1, 2))); */
100
101 int ast_register_verbose(void (*verboser)(const char *string));
102 int ast_unregister_verbose(void (*verboser)(const char *string));
103
104 void ast_console_puts(const char *string);
105
106 #define _A_ __FILE__, __LINE__, __PRETTY_FUNCTION__
107
108 #ifdef LOG_DEBUG
109 #undef LOG_DEBUG
110 #endif
111 #define __LOG_DEBUG    0
112 #define LOG_DEBUG      __LOG_DEBUG, _A_
113
114 #ifdef LOG_EVENT
115 #undef LOG_EVENT
116 #endif
117 #define __LOG_EVENT    1
118 #define LOG_EVENT      __LOG_EVENT, _A_
119
120 #ifdef LOG_NOTICE
121 #undef LOG_NOTICE
122 #endif
123 #define __LOG_NOTICE   2
124 #define LOG_NOTICE     __LOG_NOTICE, _A_
125
126 #ifdef LOG_WARNING
127 #undef LOG_WARNING
128 #endif
129 #define __LOG_WARNING  3
130 #define LOG_WARNING    __LOG_WARNING, _A_
131
132 #ifdef LOG_ERROR
133 #undef LOG_ERROR
134 #endif
135 #define __LOG_ERROR    4
136 #define LOG_ERROR      __LOG_ERROR, _A_
137
138 #ifdef LOG_VERBOSE
139 #undef LOG_VERBOSE
140 #endif
141 #define __LOG_VERBOSE  5
142 #define LOG_VERBOSE    __LOG_VERBOSE, _A_
143
144 #ifdef LOG_DTMF
145 #undef LOG_DTMF
146 #endif
147 #define __LOG_DTMF  6
148 #define LOG_DTMF    __LOG_DTMF, _A_
149
150 /* lock.h */
151
152 #ifndef HAVE_MTX_PROFILE
153 #define __MTX_PROF(a)   return pthread_mutex_lock((a))
154 #else
155 int mtx_prof = -1;
156
157 #define __MTX_PROF(a)   do {                    \
158         int i;                                  \
159         /* profile only non-blocking events */  \
160         ast_mark(mtx_prof, 1);                  \
161         i = pthread_mutex_trylock((a));         \
162         ast_mark(mtx_prof, 0);                  \
163         if (!i)                                 \
164                 return i;                       \
165         else                                    \
166                 return pthread_mutex_lock((a)); \
167         } while (0)
168 #endif  /* HAVE_MTX_PROFILE */
169
170 #define AST_PTHREADT_NULL (pthread_t) -1
171 #define AST_PTHREADT_STOP (pthread_t) -2
172
173 #if defined(SOLARIS) || defined(BSD)
174 #define AST_MUTEX_INIT_W_CONSTRUCTORS
175 #endif /* SOLARIS || BSD */
176
177 /* Asterisk REQUIRES recursive (not error checking) mutexes
178    and will not run without them. */
179 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) && defined(PTHREAD_MUTEX_RECURSIVE_NP)
180 #define PTHREAD_MUTEX_INIT_VALUE        PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
181 #define AST_MUTEX_KIND                  PTHREAD_MUTEX_RECURSIVE_NP
182 #else
183 #define PTHREAD_MUTEX_INIT_VALUE        PTHREAD_MUTEX_INITIALIZER
184 #define AST_MUTEX_KIND                  PTHREAD_MUTEX_RECURSIVE
185 #endif /* PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
186
187 #ifdef DEBUG_THREADS
188
189 #define __ast_mutex_logger(...)  do { if (canlog) ast_log(LOG_ERROR, __VA_ARGS__); else fprintf(stderr, __VA_ARGS__); } while (0)
190
191 #ifdef THREAD_CRASH
192 #define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
193 #else
194 #define DO_THREAD_CRASH do { } while (0)
195 #endif
196
197 #define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, { NULL }, { 0 }, 0, { NULL }, { 0 } }
198
199 #define AST_MAX_REENTRANCY 10
200
201 struct ast_mutex_info {
202         pthread_mutex_t mutex;
203         /*! Track which thread holds this lock */
204         unsigned int track:1;
205         const char *file[AST_MAX_REENTRANCY];
206         int lineno[AST_MAX_REENTRANCY];
207         int reentrancy;
208         const char *func[AST_MAX_REENTRANCY];
209         pthread_t thread[AST_MAX_REENTRANCY];
210 };
211
212 typedef struct ast_mutex_info ast_mutex_t;
213
214 typedef pthread_cond_t ast_cond_t;
215
216 static pthread_mutex_t empty_mutex;
217
218 static void __attribute__((constructor)) init_empty_mutex(void)
219 {
220         memset(&empty_mutex, 0, sizeof(empty_mutex));
221 }
222
223 static inline int __ast_pthread_mutex_init_attr(const char *filename, int lineno, const char *func,
224                                                 const char *mutex_name, ast_mutex_t *t,
225                                                 pthread_mutexattr_t *attr) 
226 {
227 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
228         int canlog = strcmp(filename, "logger.c");
229
230         if ((t->mutex) != ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
231                 if ((t->mutex) != (empty_mutex)) {
232                         __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is already initialized.\n",
233                                            filename, lineno, func, mutex_name);
234                         __ast_mutex_logger("%s line %d (%s): Error: previously initialization of mutex '%s'.\n",
235                                            t->file[0], t->lineno[0], t->func[0], mutex_name);
236                         DO_THREAD_CRASH;
237                         return 0;
238                 }
239         }
240 #endif
241
242         t->file[0] = filename;
243         t->lineno[0] = lineno;
244         t->func[0] = func;
245         t->thread[0]  = 0;
246         t->reentrancy = 0;
247
248         return pthread_mutex_init(&t->mutex, attr);
249 }
250
251 static inline int __ast_pthread_mutex_init(const char *filename, int lineno, const char *func,
252                                            const char *mutex_name, ast_mutex_t *t)
253 {
254         static pthread_mutexattr_t  attr;
255
256         pthread_mutexattr_init(&attr);
257         pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
258
259         return __ast_pthread_mutex_init_attr(filename, lineno, func, mutex_name, t, &attr);
260 }
261 #define ast_mutex_init(pmutex) __ast_pthread_mutex_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
262
263 static inline int __ast_pthread_mutex_destroy(const char *filename, int lineno, const char *func,
264                                                 const char *mutex_name, ast_mutex_t *t)
265 {
266         int res;
267         int canlog = strcmp(filename, "logger.c");
268
269 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
270         if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
271                 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
272                                    filename, lineno, func, mutex_name);
273         }
274 #endif
275
276         res = pthread_mutex_trylock(&t->mutex);
277         switch (res) {
278         case 0:
279                 pthread_mutex_unlock(&t->mutex);
280                 break;
281         case EINVAL:
282                 __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy invalid mutex '%s'.\n",
283                                   filename, lineno, func, mutex_name);
284                 break;
285         case EBUSY:
286                 __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy locked mutex '%s'.\n",
287                                    filename, lineno, func, mutex_name);
288                 __ast_mutex_logger("%s line %d (%s): Error: '%s' was locked here.\n",
289                                    t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
290                 break;
291         }
292
293         if ((res = pthread_mutex_destroy(&t->mutex)))
294                 __ast_mutex_logger("%s line %d (%s): Error destroying mutex: %s\n",
295                                    filename, lineno, func, strerror(res));
296 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
297         else
298                 t->mutex = PTHREAD_MUTEX_INIT_VALUE;
299 #endif
300         t->file[0] = filename;
301         t->lineno[0] = lineno;
302         t->func[0] = func;
303
304         return res;
305 }
306
307 static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func,
308                                            const char* mutex_name, ast_mutex_t *t)
309 {
310         int res;
311         int canlog = strcmp(filename, "logger.c");
312
313 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
314         if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
315                 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
316                                  filename, lineno, func, mutex_name);
317                 ast_mutex_init(t);
318         }
319 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
320
321 #ifdef DETECT_DEADLOCKS
322         {
323                 time_t seconds = time(NULL);
324                 time_t current;
325                 do {
326 #ifdef  HAVE_MTX_PROFILE
327                         ast_mark(mtx_prof, 1);
328 #endif
329                         res = pthread_mutex_trylock(&t->mutex);
330 #ifdef  HAVE_MTX_PROFILE
331                         ast_mark(mtx_prof, 0);
332 #endif
333                         if (res == EBUSY) {
334                                 current = time(NULL);
335                                 if ((current - seconds) && (!((current - seconds) % 5))) {
336                                         __ast_mutex_logger("%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n",
337                                                            filename, lineno, func, (int)(current - seconds), mutex_name);
338                                         __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
339                                                            t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
340                                                            t->func[t->reentrancy-1], mutex_name);
341                                 }
342                                 usleep(200);
343                         }
344                 } while (res == EBUSY);
345         }
346 #else
347 #ifdef  HAVE_MTX_PROFILE
348         ast_mark(mtx_prof, 1);
349         res = pthread_mutex_trylock(&t->mutex);
350         ast_mark(mtx_prof, 0);
351         if (res)
352 #endif
353         res = pthread_mutex_lock(&t->mutex);
354 #endif /* DETECT_DEADLOCKS */
355
356         if (!res) {
357                 if (t->reentrancy < AST_MAX_REENTRANCY) {
358                         t->file[t->reentrancy] = filename;
359                         t->lineno[t->reentrancy] = lineno;
360                         t->func[t->reentrancy] = func;
361                         t->thread[t->reentrancy] = pthread_self();
362                         t->reentrancy++;
363                 } else {
364                         __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
365                                                            filename, lineno, func, mutex_name);
366                 }
367         } else {
368                 __ast_mutex_logger("%s line %d (%s): Error obtaining mutex: %s\n",
369                                    filename, lineno, func, strerror(errno));
370                 DO_THREAD_CRASH;
371         }
372
373         return res;
374 }
375
376 static inline int __ast_pthread_mutex_trylock(const char *filename, int lineno, const char *func,
377                                               const char* mutex_name, ast_mutex_t *t)
378 {
379         int res;
380         int canlog = strcmp(filename, "logger.c");
381
382 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
383         if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
384                 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
385                                    filename, lineno, func, mutex_name);
386                 ast_mutex_init(t);
387         }
388 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
389
390         if (!(res = pthread_mutex_trylock(&t->mutex))) {
391                 if (t->reentrancy < AST_MAX_REENTRANCY) {
392                         t->file[t->reentrancy] = filename;
393                         t->lineno[t->reentrancy] = lineno;
394                         t->func[t->reentrancy] = func;
395                         t->thread[t->reentrancy] = pthread_self();
396                         t->reentrancy++;
397                 } else {
398                         __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
399                                            filename, lineno, func, mutex_name);
400                 }
401         } else {
402                 __ast_mutex_logger("%s line %d (%s): Warning: '%s' was locked here.\n",
403                                    t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
404         }
405
406         return res;
407 }
408
409 static inline int __ast_pthread_mutex_unlock(const char *filename, int lineno, const char *func,
410                                              const char *mutex_name, ast_mutex_t *t)
411 {
412         int res;
413         int canlog = strcmp(filename, "logger.c");
414
415 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
416         if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
417                 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
418                                    filename, lineno, func, mutex_name);
419         }
420 #endif
421
422         if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
423                 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
424                                    filename, lineno, func, mutex_name);
425                 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
426                                    t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
427                 DO_THREAD_CRASH;
428         }
429
430         if (--t->reentrancy < 0) {
431                 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
432                                    filename, lineno, func, mutex_name);
433                 t->reentrancy = 0;
434         }
435
436         if (t->reentrancy < AST_MAX_REENTRANCY) {
437                 t->file[t->reentrancy] = NULL;
438                 t->lineno[t->reentrancy] = 0;
439                 t->func[t->reentrancy] = NULL;
440                 t->thread[t->reentrancy] = 0;
441         }
442
443         if ((res = pthread_mutex_unlock(&t->mutex))) {
444                 __ast_mutex_logger("%s line %d (%s): Error releasing mutex: %s\n", 
445                                    filename, lineno, func, strerror(res));
446                 DO_THREAD_CRASH;
447         }
448
449         return res;
450 }
451
452 static inline int __ast_cond_init(const char *filename, int lineno, const char *func,
453                                   const char *cond_name, ast_cond_t *cond, pthread_condattr_t *cond_attr)
454 {
455         return pthread_cond_init(cond, cond_attr);
456 }
457
458 static inline int __ast_cond_signal(const char *filename, int lineno, const char *func,
459                                     const char *cond_name, ast_cond_t *cond)
460 {
461         return pthread_cond_signal(cond);
462 }
463
464 static inline int __ast_cond_broadcast(const char *filename, int lineno, const char *func,
465                                        const char *cond_name, ast_cond_t *cond)
466 {
467         return pthread_cond_broadcast(cond);
468 }
469
470 static inline int __ast_cond_destroy(const char *filename, int lineno, const char *func,
471                                      const char *cond_name, ast_cond_t *cond)
472 {
473         return pthread_cond_destroy(cond);
474 }
475
476 static inline int __ast_cond_wait(const char *filename, int lineno, const char *func,
477                                   const char *cond_name, const char *mutex_name,
478                                   ast_cond_t *cond, ast_mutex_t *t)
479 {
480         int res;
481         int canlog = strcmp(filename, "logger.c");
482
483 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
484         if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
485                 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
486                                    filename, lineno, func, mutex_name);
487         }
488 #endif
489
490         if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
491                 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
492                                    filename, lineno, func, mutex_name);
493                 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
494                                    t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
495                 DO_THREAD_CRASH;
496         }
497
498         if (--t->reentrancy < 0) {
499                 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
500                                    filename, lineno, func, mutex_name);
501                 t->reentrancy = 0;
502         }
503
504         if (t->reentrancy < AST_MAX_REENTRANCY) {
505                 t->file[t->reentrancy] = NULL;
506                 t->lineno[t->reentrancy] = 0;
507                 t->func[t->reentrancy] = NULL;
508                 t->thread[t->reentrancy] = 0;
509         }
510
511         if ((res = pthread_cond_wait(cond, &t->mutex))) {
512                 __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n", 
513                                    filename, lineno, func, strerror(res));
514                 DO_THREAD_CRASH;
515         } else {
516                 if (t->reentrancy < AST_MAX_REENTRANCY) {
517                         t->file[t->reentrancy] = filename;
518                         t->lineno[t->reentrancy] = lineno;
519                         t->func[t->reentrancy] = func;
520                         t->thread[t->reentrancy] = pthread_self();
521                         t->reentrancy++;
522                 } else {
523                         __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
524                                                            filename, lineno, func, mutex_name);
525                 }
526         }
527
528         return res;
529 }
530
531 static inline int __ast_cond_timedwait(const char *filename, int lineno, const char *func,
532                                        const char *cond_name, const char *mutex_name, ast_cond_t *cond,
533                                        ast_mutex_t *t, const struct timespec *abstime)
534 {
535         int res;
536         int canlog = strcmp(filename, "logger.c");
537
538 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
539         if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
540                 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
541                                    filename, lineno, func, mutex_name);
542         }
543 #endif
544
545         if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
546                 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
547                                    filename, lineno, func, mutex_name);
548                 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
549                                    t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
550                 DO_THREAD_CRASH;
551         }
552
553         if (--t->reentrancy < 0) {
554                 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
555                                    filename, lineno, func, mutex_name);
556                 t->reentrancy = 0;
557         }
558
559         if (t->reentrancy < AST_MAX_REENTRANCY) {
560                 t->file[t->reentrancy] = NULL;
561                 t->lineno[t->reentrancy] = 0;
562                 t->func[t->reentrancy] = NULL;
563                 t->thread[t->reentrancy] = 0;
564         }
565
566         if ((res = pthread_cond_timedwait(cond, &t->mutex, abstime)) && (res != ETIMEDOUT)) {
567                 __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n", 
568                                    filename, lineno, func, strerror(res));
569                 DO_THREAD_CRASH;
570         } else {
571                 if (t->reentrancy < AST_MAX_REENTRANCY) {
572                         t->file[t->reentrancy] = filename;
573                         t->lineno[t->reentrancy] = lineno;
574                         t->func[t->reentrancy] = func;
575                         t->thread[t->reentrancy] = pthread_self();
576                         t->reentrancy++;
577                 } else {
578                         __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
579                                                            filename, lineno, func, mutex_name);
580                 }
581         }
582
583         return res;
584 }
585
586 #define ast_mutex_destroy(a) __ast_pthread_mutex_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
587 #define ast_mutex_lock(a) __ast_pthread_mutex_lock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
588 #define ast_mutex_unlock(a) __ast_pthread_mutex_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
589 #define ast_mutex_trylock(a) __ast_pthread_mutex_trylock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
590 #define ast_cond_init(cond, attr) __ast_cond_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond, attr)
591 #define ast_cond_destroy(cond) __ast_cond_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
592 #define ast_cond_signal(cond) __ast_cond_signal(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
593 #define ast_cond_broadcast(cond) __ast_cond_broadcast(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
594 #define ast_cond_wait(cond, mutex) __ast_cond_wait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex)
595 #define ast_cond_timedwait(cond, mutex, time) __ast_cond_timedwait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex, time)
596
597 #else /* !DEBUG_THREADS */
598
599
600 typedef pthread_mutex_t ast_mutex_t;
601
602 #define AST_MUTEX_INIT_VALUE    ((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
603
604 static inline int ast_mutex_init(ast_mutex_t *pmutex)
605 {
606         pthread_mutexattr_t attr;
607
608         pthread_mutexattr_init(&attr);
609         pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
610
611         return pthread_mutex_init(pmutex, &attr);
612 }
613
614 #define ast_pthread_mutex_init(pmutex,a) pthread_mutex_init(pmutex,a)
615
616 static inline int ast_mutex_unlock(ast_mutex_t *pmutex)
617 {
618         return pthread_mutex_unlock(pmutex);
619 }
620
621 static inline int ast_mutex_destroy(ast_mutex_t *pmutex)
622 {
623         return pthread_mutex_destroy(pmutex);
624 }
625
626 static inline int ast_mutex_lock(ast_mutex_t *pmutex)
627 {
628         __MTX_PROF(pmutex);
629 }
630
631 static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
632 {
633         return pthread_mutex_trylock(pmutex);
634 }
635
636 typedef pthread_cond_t ast_cond_t;
637
638 static inline int ast_cond_init(ast_cond_t *cond, pthread_condattr_t *cond_attr)
639 {
640         return pthread_cond_init(cond, cond_attr);
641 }
642
643 static inline int ast_cond_signal(ast_cond_t *cond)
644 {
645         return pthread_cond_signal(cond);
646 }
647
648 static inline int ast_cond_broadcast(ast_cond_t *cond)
649 {
650         return pthread_cond_broadcast(cond);
651 }
652
653 static inline int ast_cond_destroy(ast_cond_t *cond)
654 {
655         return pthread_cond_destroy(cond);
656 }
657
658 static inline int ast_cond_wait(ast_cond_t *cond, ast_mutex_t *t)
659 {
660         return pthread_cond_wait(cond, t);
661 }
662
663 static inline int ast_cond_timedwait(ast_cond_t *cond, ast_mutex_t *t, const struct timespec *abstime)
664 {
665         return pthread_cond_timedwait(cond, t, abstime);
666 }
667
668 #endif /* !DEBUG_THREADS */
669
670 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
671 /* If AST_MUTEX_INIT_W_CONSTRUCTORS is defined, use file scope
672  constructors/destructors to create/destroy mutexes.  */
673 #define __AST_MUTEX_DEFINE(scope, mutex) \
674         scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE; \
675 static void  __attribute__((constructor)) init_##mutex(void) \
676 { \
677         ast_mutex_init(&mutex); \
678 } \
679 static void  __attribute__((destructor)) fini_##mutex(void) \
680 { \
681         ast_mutex_destroy(&mutex); \
682 }
683 #else /* !AST_MUTEX_INIT_W_CONSTRUCTORS */
684 /* By default, use static initialization of mutexes. */ 
685 #define __AST_MUTEX_DEFINE(scope, mutex) \
686         scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE
687 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
688
689 #define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
690 #define pthread_mutex_lock use_ast_mutex_lock_instead_of_pthread_mutex_lock
691 #define pthread_mutex_unlock use_ast_mutex_unlock_instead_of_pthread_mutex_unlock
692 #define pthread_mutex_trylock use_ast_mutex_trylock_instead_of_pthread_mutex_trylock
693 #define pthread_mutex_init use_ast_mutex_init_instead_of_pthread_mutex_init
694 #define pthread_mutex_destroy use_ast_mutex_destroy_instead_of_pthread_mutex_destroy
695 #define pthread_cond_t use_ast_cond_t_instead_of_pthread_cond_t
696 #define pthread_cond_init use_ast_cond_init_instead_of_pthread_cond_init
697 #define pthread_cond_destroy use_ast_cond_destroy_instead_of_pthread_cond_destroy
698 #define pthread_cond_signal use_ast_cond_signal_instead_of_pthread_cond_signal
699 #define pthread_cond_broadcast use_ast_cond_broadcast_instead_of_pthread_cond_broadcast
700 #define pthread_cond_wait use_ast_cond_wait_instead_of_pthread_cond_wait
701 #define pthread_cond_timedwait use_ast_cond_timedwait_instead_of_pthread_cond_timedwait
702
703 #define AST_MUTEX_DEFINE_STATIC(mutex) __AST_MUTEX_DEFINE(static, mutex)
704
705 #define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
706
707 #define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
708
709 #ifndef __linux__
710 #define pthread_create __use_ast_pthread_create_instead__
711 #endif
712
713 typedef pthread_rwlock_t ast_rwlock_t;
714
715 static inline int ast_rwlock_init(ast_rwlock_t *prwlock)
716 {
717         pthread_rwlockattr_t attr;
718
719         pthread_rwlockattr_init(&attr);
720
721 #ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
722         pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP);
723 #endif
724
725         return pthread_rwlock_init(prwlock, &attr);
726 }
727
728 static inline int ast_rwlock_destroy(ast_rwlock_t *prwlock)
729 {
730         return pthread_rwlock_destroy(prwlock);
731 }
732
733 static inline int ast_rwlock_unlock(ast_rwlock_t *prwlock)
734 {
735         return pthread_rwlock_unlock(prwlock);
736 }
737
738 static inline int ast_rwlock_rdlock(ast_rwlock_t *prwlock)
739 {
740         return pthread_rwlock_rdlock(prwlock);
741 }
742
743 static inline int ast_rwlock_tryrdlock(ast_rwlock_t *prwlock)
744 {
745         return pthread_rwlock_tryrdlock(prwlock);
746 }
747
748 static inline int ast_rwlock_wrlock(ast_rwlock_t *prwlock)
749 {
750         return pthread_rwlock_wrlock(prwlock);
751 }
752
753 static inline int ast_rwlock_trywrlock(ast_rwlock_t *prwlock)
754 {
755         return pthread_rwlock_trywrlock(prwlock);
756 }
757
758 /* Statically declared read/write locks */
759
760 #ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER
761 #define __AST_RWLOCK_DEFINE(scope, rwlock) \
762         scope ast_rwlock_t rwlock; \
763 static void  __attribute__((constructor)) init_##rwlock(void) \
764 { \
765         ast_rwlock_init(&rwlock); \
766 } \
767 static void  __attribute__((destructor)) fini_##rwlock(void) \
768 { \
769         ast_rwlock_destroy(&rwlock); \
770 }
771 #else
772 #define AST_RWLOCK_INIT_VALUE PTHREAD_RWLOCK_INITIALIZER
773 #define __AST_RWLOCK_DEFINE(scope, rwlock) \
774         scope ast_rwlock_t rwlock = AST_RWLOCK_INIT_VALUE
775 #endif
776
777 #define AST_RWLOCK_DEFINE_STATIC(rwlock) __AST_RWLOCK_DEFINE(static, rwlock)
778
779 /*
780  * Initial support for atomic instructions.
781  * For platforms that have it, use the native cpu instruction to
782  * implement them. For other platforms, resort to a 'slow' version
783  * (defined in utils.c) that protects the atomic instruction with
784  * a single lock.
785  * The slow versions is always available, for testing purposes,
786  * as ast_atomic_fetchadd_int_slow()
787  */
788
789 #if defined(HAVE_OSX_ATOMICS)
790 #include "libkern/OSAtomic.h"
791 #endif
792
793 /*! \brief Atomically add v to *p and return * the previous value of *p.
794  * This can be used to handle reference counts, and the return value
795  * can be used to generate unique identifiers.
796  */
797
798 #if defined(HAVE_GCC_ATOMICS)
799 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
800 {
801         return __sync_fetch_and_add(p, v);
802 })
803 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
804 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
805 {
806         return OSAtomicAdd32(v, (int32_t *) p);
807 })
808 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
809 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
810 {
811         return OSAtomicAdd64(v, (int64_t *) p);
812 #elif defined (__i386__) || defined(__x86_64__)
813 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
814 {
815         __asm __volatile (
816         "       lock   xaddl   %0, %1 ;        "
817         : "+r" (v),                     /* 0 (result) */   
818           "=m" (*p)                     /* 1 */
819         : "m" (*p));                    /* 2 */
820         return (v);
821 })
822 #else
823 static int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
824 {
825         int ret;
826         ret = *p;
827         *p += v;
828         return ret;
829 }
830 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
831 {
832         return ast_atomic_fetchadd_int_slow(p, v);
833 })
834 #endif
835
836 /*! \brief decrement *p by 1 and return true if the variable has reached 0.
837  * Useful e.g. to check if a refcount has reached 0.
838  */
839 #if defined(HAVE_GCC_ATOMICS)
840 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
841 {
842         return __sync_sub_and_fetch(p, 1) == 0;
843 })
844 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
845 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
846 {
847         return OSAtomicAdd32( -1, (int32_t *) p) == 0;
848 })
849 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
850 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
851 {
852         return OSAtomicAdd64( -1, (int64_t *) p) == 0;
853 #else
854 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
855 {
856         int a = ast_atomic_fetchadd_int(p, -1);
857         return a == 1; /* true if the value is 0 now (so it was 1 previously) */
858 })
859 #endif
860
861 #ifndef DEBUG_CHANNEL_LOCKS
862 /*! \brief Lock a channel. If DEBUG_CHANNEL_LOCKS is defined 
863         in the Makefile, print relevant output for debugging */
864 #define ast_channel_lock(x)             ast_mutex_lock(&x->lock)
865 /*! \brief Unlock a channel. If DEBUG_CHANNEL_LOCKS is defined 
866         in the Makefile, print relevant output for debugging */
867 #define ast_channel_unlock(x)           ast_mutex_unlock(&x->lock)
868 /*! \brief Try locking a channel. If DEBUG_CHANNEL_LOCKS is defined 
869         in the Makefile, print relevant output for debugging */
870 #define ast_channel_trylock(x)          ast_mutex_trylock(&x->lock)
871 #else
872
873 /*! \brief Lock AST channel (and print debugging output)
874 \note You need to enable DEBUG_CHANNEL_LOCKS for this function */
875 int ast_channel_lock(struct ast_channel *chan);
876
877 /*! \brief Unlock AST channel (and print debugging output)
878 \note You need to enable DEBUG_CHANNEL_LOCKS for this function
879 */
880 int ast_channel_unlock(struct ast_channel *chan);
881
882 /*! \brief Lock AST channel (and print debugging output)
883 \note   You need to enable DEBUG_CHANNEL_LOCKS for this function */
884 int ast_channel_trylock(struct ast_channel *chan);
885 #endif
886
887
888 #include "asterisk/hashtab.h"
889 #include "asterisk/ael_structs.h"
890 #include "asterisk/pval.h"
891
892 /* from utils.h */
893
894 #define ast_free free
895 #define ast_free_ptr free
896
897 #define MALLOC_FAILURE_MSG \
898         ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
899
900 /*!
901  * \brief A wrapper for malloc()
902  *
903  * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
904  * message in the case that the allocation fails.
905  *
906  * The argument and return value are the same as malloc()
907  */
908 #define ast_malloc(len) \
909         _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
910
911 #define ast_calloc(num, len) \
912         _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
913
914 #define ast_calloc_cache(num, len) \
915         _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
916
917 #define ast_realloc(p, len) \
918         _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
919
920 #define ast_strdup(str) \
921         _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
922
923 #define ast_strndup(str, len) \
924         _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
925
926 #define ast_asprintf(ret, fmt, ...) \
927         _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
928
929 #define ast_vasprintf(ret, fmt, ap) \
930         _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
931
932
933 static unsigned int __unsigned_int_flags_dummy;
934
935 struct ast_flags {  /* stolen from utils.h */
936         unsigned int flags;
937 };
938 #define ast_test_flag(p,flag)           ({ \
939                                         typeof ((p)->flags) __p = (p)->flags; \
940                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
941                                         (void) (&__p == &__x); \
942                                         ((p)->flags & (flag)); \
943                                         })
944
945 #define ast_set2_flag(p,value,flag)     do { \
946                                         typeof ((p)->flags) __p = (p)->flags; \
947                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
948                                         (void) (&__p == &__x); \
949                                         if (value) \
950                                                 (p)->flags |= (flag); \
951                                         else \
952                                                 (p)->flags &= ~(flag); \
953                                         } while (0)
954
955
956
957 #define MALLOC_FAILURE_MSG \
958         ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
959 /*!
960  * \brief A wrapper for malloc()
961  *
962  * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
963  * message in the case that the allocation fails.
964  *
965  * The argument and return value are the same as malloc()
966  */
967 #define ast_malloc(len) \
968         _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
969
970 AST_INLINE_API(
971 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
972 {
973         void *p;
974
975         if (!(p = malloc(len)))
976                 MALLOC_FAILURE_MSG;
977
978         return p;
979 }
980 )
981
982 /*!
983  * \brief A wrapper for calloc()
984  *
985  * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
986  * message in the case that the allocation fails.
987  *
988  * The arguments and return value are the same as calloc()
989  */
990 #define ast_calloc(num, len) \
991         _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
992
993 AST_INLINE_API(
994 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
995 {
996         void *p;
997
998         if (!(p = calloc(num, len)))
999                 MALLOC_FAILURE_MSG;
1000
1001         return p;
1002 }
1003 )
1004
1005 /*!
1006  * \brief A wrapper for calloc() for use in cache pools
1007  *
1008  * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
1009  * message in the case that the allocation fails. When memory debugging is in use,
1010  * the memory allocated by this function will be marked as 'cache' so it can be
1011  * distinguished from normal memory allocations.
1012  *
1013  * The arguments and return value are the same as calloc()
1014  */
1015 #define ast_calloc_cache(num, len) \
1016         _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1017
1018 /*!
1019  * \brief A wrapper for realloc()
1020  *
1021  * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
1022  * message in the case that the allocation fails.
1023  *
1024  * The arguments and return value are the same as realloc()
1025  */
1026 #define ast_realloc(p, len) \
1027         _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1028
1029 AST_INLINE_API(
1030 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
1031 {
1032         void *newp;
1033
1034         if (!(newp = realloc(p, len)))
1035                 MALLOC_FAILURE_MSG;
1036
1037         return newp;
1038 }
1039 )
1040
1041 /*!
1042  * \brief A wrapper for strdup()
1043  *
1044  * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
1045  * message in the case that the allocation fails.
1046  *
1047  * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
1048  * argument is provided, ast_strdup will return NULL without generating any
1049  * kind of error log message.
1050  *
1051  * The argument and return value are the same as strdup()
1052  */
1053 #define ast_strdup(str) \
1054         _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1055
1056 AST_INLINE_API(
1057 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
1058 {
1059         char *newstr = NULL;
1060
1061         if (str) {
1062                 if (!(newstr = strdup(str)))
1063                         MALLOC_FAILURE_MSG;
1064         }
1065
1066         return newstr;
1067 }
1068 )
1069
1070 /*!
1071  * \brief A wrapper for strndup()
1072  *
1073  * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
1074  * message in the case that the allocation fails.
1075  *
1076  * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
1077  * string to duplicate. If a NULL argument is provided, ast_strdup will return  
1078  * NULL without generating any kind of error log message.
1079  *
1080  * The arguments and return value are the same as strndup()
1081  */
1082 #define ast_strndup(str, len) \
1083         _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1084
1085 AST_INLINE_API(
1086 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
1087 {
1088         char *newstr = NULL;
1089
1090         if (str) {
1091                 if (!(newstr = strndup(str, len)))
1092                         MALLOC_FAILURE_MSG;
1093         }
1094
1095         return newstr;
1096 }
1097 )
1098
1099 /*!
1100  * \brief A wrapper for asprintf()
1101  *
1102  * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
1103  * message in the case that the allocation fails.
1104  *
1105  * The arguments and return value are the same as asprintf()
1106  */
1107 #define ast_asprintf(ret, fmt, ...) \
1108         _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
1109
1110 AST_INLINE_API(
1111 __attribute__((format(printf, 5, 6)))
1112 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...),
1113 {
1114         int res;
1115         va_list ap;
1116
1117         va_start(ap, fmt);
1118         if ((res = vasprintf(ret, fmt, ap)) == -1)
1119                 MALLOC_FAILURE_MSG;
1120         va_end(ap);
1121
1122         return res;
1123 }
1124 )
1125
1126 /*!
1127  * \brief A wrapper for vasprintf()
1128  *
1129  * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
1130  * message in the case that the allocation fails.
1131  *
1132  * The arguments and return value are the same as vasprintf()
1133  */
1134 #define ast_vasprintf(ret, fmt, ap) \
1135         _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
1136
1137 AST_INLINE_API(
1138 __attribute__((format(printf, 5, 0)))
1139 int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
1140 {
1141         int res;
1142
1143         if ((res = vasprintf(ret, fmt, ap)) == -1)
1144                 MALLOC_FAILURE_MSG;
1145
1146         return res;
1147 }
1148 )
1149
1150 #if !defined(ast_strdupa) && defined(__GNUC__)
1151 /*!
1152   \brief duplicate a string in memory from the stack
1153   \param s The string to duplicate
1154
1155   This macro will duplicate the given string.  It returns a pointer to the stack
1156   allocatted memory for the new string.
1157 */
1158 #define ast_strdupa(s)                                                    \
1159         (__extension__                                                    \
1160         ({                                                                \
1161                 const char *__old = (s);                                  \
1162                 size_t __len = strlen(__old) + 1;                         \
1163                 char *__new = __builtin_alloca(__len);                    \
1164                 memcpy (__new, __old, __len);                             \
1165                 __new;                                                    \
1166         }))
1167 #endif
1168
1169
1170 /* from config.c */
1171
1172 #define MAX_NESTED_COMMENTS 128
1173 #define COMMENT_START ";--"
1174 #define COMMENT_END "--;"
1175 #define COMMENT_META ';'
1176 #define COMMENT_TAG '-'
1177
1178 static char *extconfig_conf = "extconfig.conf";
1179
1180 /*! Growable string buffer */
1181 static char *comment_buffer;   /*!< this will be a comment collector.*/
1182 static int   comment_buffer_size;  /*!< the amount of storage so far alloc'd for the comment_buffer */
1183
1184 static char *lline_buffer;    /*!< A buffer for stuff behind the ; */
1185 static int  lline_buffer_size;
1186
1187 #define CB_INCR 250
1188
1189 struct ast_comment {
1190         struct ast_comment *next;
1191         char cmt[0];
1192 };
1193
1194 static void CB_INIT(void)
1195 {
1196         if (!comment_buffer) {
1197                 comment_buffer = ast_malloc(CB_INCR);
1198                 if (!comment_buffer)
1199                         return;
1200                 comment_buffer[0] = 0;
1201                 comment_buffer_size = CB_INCR;
1202                 lline_buffer = ast_malloc(CB_INCR);
1203                 if (!lline_buffer)
1204                         return;
1205                 lline_buffer[0] = 0;
1206                 lline_buffer_size = CB_INCR;
1207         } else {
1208                 comment_buffer[0] = 0;
1209                 lline_buffer[0] = 0;
1210         }
1211 }
1212
1213 static void  CB_ADD(char *str)
1214 {
1215         int rem = comment_buffer_size - strlen(comment_buffer) - 1;
1216         int siz = strlen(str);
1217         if (rem < siz+1) {
1218                 comment_buffer = ast_realloc(comment_buffer, comment_buffer_size + CB_INCR + siz + 1);
1219                 if (!comment_buffer)
1220                         return;
1221                 comment_buffer_size += CB_INCR+siz+1;
1222         }
1223         strcat(comment_buffer,str);
1224 }
1225
1226 static void  CB_ADD_LEN(char *str, int len)
1227 {
1228         int cbl = strlen(comment_buffer) + 1;
1229         int rem = comment_buffer_size - cbl;
1230         if (rem < len+1) {
1231                 comment_buffer = ast_realloc(comment_buffer, comment_buffer_size + CB_INCR + len + 1);
1232                 if (!comment_buffer)
1233                         return;
1234                 comment_buffer_size += CB_INCR+len+1;
1235         }
1236         strncat(comment_buffer,str,len); /* safe */
1237         comment_buffer[cbl+len-1] = 0;
1238 }
1239
1240 static void  LLB_ADD(char *str)
1241 {
1242         int rem = lline_buffer_size - strlen(lline_buffer) - 1;
1243         int siz = strlen(str);
1244         if (rem < siz+1) {
1245                 lline_buffer = ast_realloc(lline_buffer, lline_buffer_size + CB_INCR + siz + 1);
1246                 if (!lline_buffer) 
1247                         return;
1248                 lline_buffer_size += CB_INCR + siz + 1;
1249         }
1250         strcat(lline_buffer,str);
1251 }
1252
1253 static void CB_RESET(void )  
1254
1255         comment_buffer[0] = 0; 
1256         lline_buffer[0] = 0;
1257 }
1258                 
1259 /*! \brief Keep track of how many threads are currently trying to wait*() on
1260  *  a child process */
1261 static unsigned int safe_system_level = 0;
1262 static struct sigaction safe_system_prev_handler;
1263
1264 /*! \brief NULL handler so we can collect the child exit status */
1265 static void _null_sig_handler(int sig)
1266 {
1267
1268 }
1269
1270 static struct sigaction null_sig_handler = {
1271         .sa_handler = _null_sig_handler,
1272 };
1273
1274 void ast_replace_sigchld(void);
1275
1276 void ast_replace_sigchld(void)
1277 {
1278         unsigned int level;
1279
1280         level = safe_system_level++;
1281
1282         /* only replace the handler if it has not already been done */
1283         if (level == 0) {
1284                 sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
1285         }
1286 }
1287
1288 void ast_unreplace_sigchld(void);
1289
1290 void ast_unreplace_sigchld(void)
1291 {
1292         unsigned int level;
1293
1294         level = --safe_system_level;
1295
1296         /* only restore the handler if we are the last one */
1297         if (level == 0) {
1298                 sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
1299         }
1300 }
1301
1302 int ast_safe_system(const char *s);
1303
1304 int ast_safe_system(const char *s)
1305 {
1306         pid_t pid;
1307 #ifdef HAVE_WORKING_FORK
1308         int x;
1309 #endif
1310         int res;
1311         struct rusage rusage;
1312         int status;
1313
1314 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
1315         ast_replace_sigchld();
1316
1317 #ifdef HAVE_WORKING_FORK
1318         pid = fork();
1319 #else
1320         pid = vfork();
1321 #endif  
1322
1323         if (pid == 0) {
1324 #ifdef HAVE_WORKING_FORK
1325                 /* Close file descriptors and launch system command */
1326                 for (x = STDERR_FILENO + 1; x < 4096; x++)
1327                         close(x);
1328 #endif
1329                 execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
1330                 _exit(1);
1331         } else if (pid > 0) {
1332                 for(;;) {
1333                         res = wait4(pid, &status, 0, &rusage);
1334                         if (res > -1) {
1335                                 res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
1336                                 break;
1337                         } else if (errno != EINTR) 
1338                                 break;
1339                 }
1340         } else {
1341                 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
1342                 res = -1;
1343         }
1344
1345         ast_unreplace_sigchld();
1346 #else
1347         res = -1;
1348 #endif
1349
1350         return res;
1351 }
1352
1353 static struct ast_comment *ALLOC_COMMENT(const char *buffer)
1354
1355         struct ast_comment *x = ast_calloc(1,sizeof(struct ast_comment)+strlen(buffer)+1);
1356         strcpy(x->cmt, buffer);
1357         return x;
1358 }
1359
1360 static struct ast_config_map {
1361         struct ast_config_map *next;
1362         char *name;
1363         char *driver;
1364         char *database;
1365         char *table;
1366         char stuff[0];
1367 } *config_maps = NULL;
1368
1369 static struct ast_config_engine *config_engine_list;
1370
1371 #define MAX_INCLUDE_LEVEL 10
1372
1373
1374 struct ast_category {
1375         char name[80];
1376         int ignored;                    /*!< do not let user of the config see this category */
1377         int include_level;      
1378     char *file;                /*!< the file name from whence this declaration was read */
1379     int lineno;
1380         struct ast_comment *precomments;
1381         struct ast_comment *sameline;
1382         struct ast_variable *root;
1383         struct ast_variable *last;
1384         struct ast_category *next;
1385 };
1386
1387 struct ast_config {
1388         struct ast_category *root;
1389         struct ast_category *last;
1390         struct ast_category *current;
1391         struct ast_category *last_browse;               /*!< used to cache the last category supplied via category_browse */
1392         int include_level;
1393         int max_include_level;
1394     struct ast_config_include *includes;  /*!< a list of inclusions, which should describe the entire tree */
1395 };
1396
1397 struct ast_config_include {
1398         char *include_location_file;     /*!< file name in which the include occurs */
1399         int  include_location_lineno;    /*!< lineno where include occurred */
1400         int  exec;                       /*!< set to non-zero if itsa #exec statement */
1401         char *exec_file;                 /*!< if it's an exec, you'll have both the /var/tmp to read, and the original script */
1402         char *included_file;             /*!< file name included */
1403         int inclusion_count;             /*!< if the file is included more than once, a running count thereof -- but, worry not,
1404                                                                            we explode the instances and will include those-- so all entries will be unique */
1405         int output;                      /*!< a flag to indicate if the inclusion has been output */
1406         struct ast_config_include *next; /*!< ptr to next inclusion in the list */
1407 };
1408
1409 typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, int withcomments, const char *suggested_include_file);
1410 typedef struct ast_variable *realtime_var_get(const char *database, const char *table, va_list ap);
1411 typedef struct ast_config *realtime_multi_get(const char *database, const char *table, va_list ap);
1412 typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
1413
1414 /*! \brief Configuration engine structure, used to define realtime drivers */
1415 struct ast_config_engine {
1416         char *name;
1417         config_load_func *load_func;
1418         realtime_var_get *realtime_func;
1419         realtime_multi_get *realtime_multi_func;
1420         realtime_update *update_func;
1421         struct ast_config_engine *next;
1422 };
1423
1424 static struct ast_config_engine *config_engine_list;
1425
1426 /* taken from strings.h */
1427
1428 static force_inline int ast_strlen_zero(const char *s)
1429 {
1430         return (!s || (*s == '\0'));
1431 }
1432
1433 #define S_OR(a, b)      (!ast_strlen_zero(a) ? (a) : (b))
1434
1435 AST_INLINE_API(
1436 void ast_copy_string(char *dst, const char *src, size_t size),
1437 {
1438         while (*src && size) {
1439                 *dst++ = *src++;
1440                 size--;
1441         }
1442         if (__builtin_expect(!size, 0))
1443                 dst--;
1444         *dst = '\0';
1445 }
1446 )
1447
1448 AST_INLINE_API(
1449 char *ast_skip_blanks(const char *str),
1450 {
1451         while (*str && *str < 33)
1452                 str++;
1453         return (char *)str;
1454 }
1455 )
1456
1457 /*!
1458   \brief Trims trailing whitespace characters from a string.
1459   \param ast_trim_blanks function being used
1460   \param str the input string
1461   \return a pointer to the modified string
1462  */
1463 AST_INLINE_API(
1464 char *ast_trim_blanks(char *str),
1465 {
1466         char *work = str;
1467
1468         if (work) {
1469                 work += strlen(work) - 1;
1470                 /* It's tempting to only want to erase after we exit this loop, 
1471                    but since ast_trim_blanks *could* receive a constant string
1472                    (which we presumably wouldn't have to touch), we shouldn't
1473                    actually set anything unless we must, and it's easier just
1474                    to set each position to \0 than to keep track of a variable
1475                    for it */
1476                 while ((work >= str) && *work < 33)
1477                         *(work--) = '\0';
1478         }
1479         return str;
1480 }
1481 )
1482
1483 /*!
1484   \brief Strip leading/trailing whitespace from a string.
1485   \param s The string to be stripped (will be modified).
1486   \return The stripped string.
1487
1488   This functions strips all leading and trailing whitespace
1489   characters from the input string, and returns a pointer to
1490   the resulting string. The string is modified in place.
1491 */
1492 AST_INLINE_API(
1493 char *ast_strip(char *s),
1494 {
1495         s = ast_skip_blanks(s);
1496         if (s)
1497                 ast_trim_blanks(s);
1498         return s;
1499
1500 )
1501
1502
1503 /* from config.h */
1504
1505 struct ast_variable {
1506         char *name;
1507         char *value;
1508         char *file;
1509         int lineno;
1510         int object;             /*!< 0 for variable, 1 for object */
1511         int blanklines;         /*!< Number of blanklines following entry */
1512         struct ast_comment *precomments;
1513         struct ast_comment *sameline;
1514         struct ast_variable *next;
1515         char stuff[0];
1516 };
1517
1518 static const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable);
1519 static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_include_file);
1520
1521 struct ast_config *localized_config_load_with_comments(const char *filename);
1522 static char *ast_category_browse(struct ast_config *config, const char *prev);
1523 static struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category);
1524 static void ast_variables_destroy(struct ast_variable *v);
1525 static void ast_config_destroy(struct ast_config *cfg);
1526 static struct ast_config_include *ast_include_new(struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size);
1527 static struct ast_config_include *ast_include_find(struct ast_config *conf, const char *included_file);
1528 void localized_ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file);
1529
1530 static struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename);
1531
1532 static struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename) 
1533 {
1534         struct ast_variable *variable;
1535         int name_len = strlen(name) + 1;        
1536
1537         if ((variable = ast_calloc(1, name_len + strlen(value) + 1 + strlen(filename) + 1 + sizeof(*variable)))) {
1538                 variable->name = variable->stuff;
1539                 variable->value = variable->stuff + name_len;           
1540                 variable->file = variable->value + strlen(value) + 1;           
1541                 strcpy(variable->name,name);
1542                 strcpy(variable->value,value);
1543                 strcpy(variable->file,filename);
1544         }
1545
1546         return variable;
1547 }
1548
1549 static struct ast_config_include *ast_include_new(struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size)
1550 {
1551         /* a file should be included ONCE. Otherwise, if one of the instances is changed,
1552        then all be changed. -- how do we know to include it? -- Handling modified 
1553        instances is possible, I'd have
1554        to create a new master for each instance. */
1555         struct ast_config_include *inc;
1556     
1557         inc = ast_include_find(conf, included_file);
1558         if (inc)
1559         {
1560                 inc->inclusion_count++;
1561                 snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count);
1562                 ast_log(LOG_WARNING,"'%s', line %d:  Same File included more than once! This data will be saved in %s if saved back to disk.\n", from_file, from_lineno, real_included_file_name);
1563         } else
1564                 *real_included_file_name = 0;
1565         
1566         inc = ast_calloc(1,sizeof(struct ast_config_include));
1567         inc->include_location_file = ast_strdup(from_file);
1568         inc->include_location_lineno = from_lineno;
1569         if (!ast_strlen_zero(real_included_file_name))
1570                 inc->included_file = ast_strdup(real_included_file_name);
1571         else
1572                 inc->included_file = ast_strdup(included_file);
1573         
1574         inc->exec = is_exec;
1575         if (is_exec)
1576                 inc->exec_file = ast_strdup(exec_file);
1577         
1578         /* attach this new struct to the conf struct */
1579         inc->next = conf->includes;
1580         conf->includes = inc;
1581     
1582         return inc;
1583 }
1584
1585 void localized_ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
1586 {
1587         struct ast_config_include *incl;
1588         struct ast_category *cat;
1589         struct ast_variable *v;
1590     
1591         int from_len = strlen(from_file);
1592         int to_len = strlen(to_file);
1593     
1594         if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */
1595                 return;
1596         
1597         /* the manager code allows you to read in one config file, then
1598        write it back out under a different name. But, the new arrangement
1599            ties output lines to the file name. So, before you try to write
1600        the config file to disk, better riffle thru the data and make sure
1601        the file names are changed.
1602         */
1603         /* file names are on categories, includes (of course), and on variables. So,
1604            traverse all this and swap names */
1605         
1606         for (incl = conf->includes; incl; incl=incl->next) {
1607                 if (strcmp(incl->include_location_file,from_file) == 0) {
1608                         if (from_len >= to_len)
1609                                 strcpy(incl->include_location_file, to_file);
1610                         else {
1611                                 free(incl->include_location_file);
1612                                 incl->include_location_file = strdup(to_file);
1613                         }
1614                 }
1615         }
1616         for (cat = conf->root; cat; cat = cat->next) {
1617                 if (strcmp(cat->file,from_file) == 0) {
1618                         if (from_len >= to_len)
1619                                 strcpy(cat->file, to_file);
1620                         else {
1621                                 free(cat->file);
1622                                 cat->file = strdup(to_file);
1623                         }
1624                 }
1625                 for (v = cat->root; v; v = v->next) {
1626                         if (strcmp(v->file,from_file) == 0) {
1627                                 if (from_len >= to_len)
1628                                         strcpy(v->file, to_file);
1629                                 else {
1630                                         free(v->file);
1631                                         v->file = strdup(to_file);
1632                                 }
1633                         }
1634                 }
1635         }
1636 }
1637
1638 static struct ast_config_include *ast_include_find(struct ast_config *conf, const char *included_file)
1639 {
1640         struct ast_config_include *x;
1641         for (x=conf->includes;x;x=x->next)
1642         {
1643                 if (strcmp(x->included_file,included_file) == 0)
1644                         return x;
1645         }
1646         return 0;
1647 }
1648
1649
1650 static void ast_variable_append(struct ast_category *category, struct ast_variable *variable);
1651
1652 static void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
1653 {
1654         if (!variable)
1655                 return;
1656         if (category->last)
1657                 category->last->next = variable;
1658         else
1659                 category->root = variable;
1660         category->last = variable;
1661         while (category->last->next)
1662                 category->last = category->last->next;
1663 }
1664
1665 static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored);
1666
1667 static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored)
1668 {
1669         struct ast_category *cat;
1670
1671         /* try exact match first, then case-insensitive match */
1672         for (cat = config->root; cat; cat = cat->next) {
1673                 if (cat->name == category_name && (ignored || !cat->ignored))
1674                         return cat;
1675         }
1676
1677         for (cat = config->root; cat; cat = cat->next) {
1678                 if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored))
1679                         return cat;
1680         }
1681
1682         return NULL;
1683 }
1684
1685 static struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name)
1686 {
1687         return category_get(config, category_name, 0);
1688 }
1689
1690 static struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category)
1691 {
1692         struct ast_category *cat = NULL;
1693
1694         if (category && config->last_browse && (config->last_browse->name == category))
1695                 cat = config->last_browse;
1696         else
1697                 cat = ast_category_get(config, category);
1698
1699         return (cat) ? cat->root : NULL;
1700 }
1701
1702 static const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
1703 {
1704         struct ast_variable *v;
1705
1706         if (category) {
1707                 for (v = ast_variable_browse(config, category); v; v = v->next) {
1708                         if (!strcasecmp(variable, v->name))
1709                                 return v->value;
1710                 }
1711         } else {
1712                 struct ast_category *cat;
1713
1714                 for (cat = config->root; cat; cat = cat->next)
1715                         for (v = cat->root; v; v = v->next)
1716                                 if (!strcasecmp(variable, v->name))
1717                                         return v->value;
1718         }
1719
1720         return NULL;
1721 }
1722
1723 static struct ast_variable *variable_clone(const struct ast_variable *old)
1724 {
1725         struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
1726
1727         if (new) {
1728                 new->lineno = old->lineno;
1729                 new->object = old->object;
1730                 new->blanklines = old->blanklines;
1731                 /* TODO: clone comments? */
1732         }
1733
1734         return new;
1735 }
1736  
1737 static void ast_variables_destroy(struct ast_variable *v)
1738 {
1739         struct ast_variable *vn;
1740
1741         while (v) {
1742                 vn = v;
1743                 v = v->next;
1744                 free(vn);
1745         }
1746 }
1747
1748 static void ast_includes_destroy(struct ast_config_include *incls)
1749 {
1750         struct ast_config_include *incl,*inclnext;
1751     
1752         for (incl=incls; incl; incl = inclnext) {
1753                 inclnext = incl->next;
1754                 if (incl->include_location_file)
1755                         free(incl->include_location_file);
1756                 if (incl->exec_file)
1757                         free(incl->exec_file);
1758                 if (incl->included_file)
1759                         free(incl->included_file);
1760                 free(incl);
1761         }
1762 }
1763
1764 static void ast_config_destroy(struct ast_config *cfg)
1765 {
1766         struct ast_category *cat, *catn;
1767
1768         if (!cfg)
1769                 return;
1770
1771         ast_includes_destroy(cfg->includes);
1772         
1773         cat = cfg->root;
1774         while (cat) {
1775                 ast_variables_destroy(cat->root);
1776                 catn = cat;
1777                 cat = cat->next;
1778                 free(catn);
1779         }
1780         free(cfg);
1781 }
1782
1783 enum ast_option_flags {
1784         /*! Allow \#exec in config files */
1785         AST_OPT_FLAG_EXEC_INCLUDES = (1 << 0),
1786         /*! Do not fork() */
1787         AST_OPT_FLAG_NO_FORK = (1 << 1),
1788         /*! Keep quiet */
1789         AST_OPT_FLAG_QUIET = (1 << 2),
1790         /*! Console mode */
1791         AST_OPT_FLAG_CONSOLE = (1 << 3),
1792         /*! Run in realtime Linux priority */
1793         AST_OPT_FLAG_HIGH_PRIORITY = (1 << 4),
1794         /*! Initialize keys for RSA authentication */
1795         AST_OPT_FLAG_INIT_KEYS = (1 << 5),
1796         /*! Remote console */
1797         AST_OPT_FLAG_REMOTE = (1 << 6),
1798         /*! Execute an asterisk CLI command upon startup */
1799         AST_OPT_FLAG_EXEC = (1 << 7),
1800         /*! Don't use termcap colors */
1801         AST_OPT_FLAG_NO_COLOR = (1 << 8),
1802         /*! Are we fully started yet? */
1803         AST_OPT_FLAG_FULLY_BOOTED = (1 << 9),
1804         /*! Trascode via signed linear */
1805         AST_OPT_FLAG_TRANSCODE_VIA_SLIN = (1 << 10),
1806         /*! Dump core on a seg fault */
1807         AST_OPT_FLAG_DUMP_CORE = (1 << 12),
1808         /*! Cache sound files */
1809         AST_OPT_FLAG_CACHE_RECORD_FILES = (1 << 13),
1810         /*! Display timestamp in CLI verbose output */
1811         AST_OPT_FLAG_TIMESTAMP = (1 << 14),
1812         /*! Override config */
1813         AST_OPT_FLAG_OVERRIDE_CONFIG = (1 << 15),
1814         /*! Reconnect */
1815         AST_OPT_FLAG_RECONNECT = (1 << 16),
1816         /*! Transmit Silence during Record() and DTMF Generation */
1817         AST_OPT_FLAG_TRANSMIT_SILENCE = (1 << 17),
1818         /*! Suppress some warnings */
1819         AST_OPT_FLAG_DONT_WARN = (1 << 18),
1820         /*! End CDRs before the 'h' extension */
1821         AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN = (1 << 19),
1822         /*! Use DAHDI Timing for generators if available */
1823         AST_OPT_FLAG_INTERNAL_TIMING = (1 << 20),
1824         /*! Always fork, even if verbose or debug settings are non-zero */
1825         AST_OPT_FLAG_ALWAYS_FORK = (1 << 21),
1826         /*! Disable log/verbose output to remote consoles */
1827         AST_OPT_FLAG_MUTE = (1 << 22),
1828         /*! There is a per-file debug setting */
1829         AST_OPT_FLAG_DEBUG_FILE = (1 << 23),
1830         /*! There is a per-file verbose setting */
1831         AST_OPT_FLAG_VERBOSE_FILE = (1 << 24),
1832         /*! Terminal colors should be adjusted for a light-colored background */
1833         AST_OPT_FLAG_LIGHT_BACKGROUND = (1 << 25),
1834         /*! Count Initiated seconds in CDR's */
1835         AST_OPT_FLAG_INITIATED_SECONDS = (1 << 26),
1836         /*! Force black background */
1837         AST_OPT_FLAG_FORCE_BLACK_BACKGROUND = (1 << 27),
1838 };
1839
1840 /* options.h declares ast_options extern; I need it static? */
1841 #define AST_CACHE_DIR_LEN       512
1842 #define AST_FILENAME_MAX        80
1843
1844 /*! These are the options that set by default when Asterisk starts */
1845 #define AST_DEFAULT_OPTIONS AST_OPT_FLAG_TRANSCODE_VIA_SLIN
1846
1847 struct ast_flags ast_options = { AST_DEFAULT_OPTIONS };
1848
1849 #define ast_opt_exec_includes           ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES)
1850 #define ast_opt_no_fork                 ast_test_flag(&ast_options, AST_OPT_FLAG_NO_FORK)
1851 #define ast_opt_quiet                   ast_test_flag(&ast_options, AST_OPT_FLAG_QUIET)
1852 #define ast_opt_console                 ast_test_flag(&ast_options, AST_OPT_FLAG_CONSOLE)
1853 #define ast_opt_high_priority           ast_test_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY)
1854 #define ast_opt_init_keys               ast_test_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS)
1855 #define ast_opt_remote                  ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)
1856 #define ast_opt_exec                    ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC)
1857 #define ast_opt_no_color                ast_test_flag(&ast_options, AST_OPT_FLAG_NO_COLOR)
1858 #define ast_fully_booted                ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)
1859 #define ast_opt_transcode_via_slin      ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN)
1860 #define ast_opt_priority_jumping        ast_test_flag(&ast_options, AST_OPT_FLAG_PRIORITY_JUMPING)
1861 #define ast_opt_dump_core               ast_test_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE)
1862 #define ast_opt_cache_record_files      ast_test_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES)
1863 #define ast_opt_timestamp               ast_test_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP)
1864 #define ast_opt_override_config         ast_test_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG)
1865 #define ast_opt_reconnect               ast_test_flag(&ast_options, AST_OPT_FLAG_RECONNECT)
1866 #define ast_opt_transmit_silence        ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE)
1867 #define ast_opt_dont_warn               ast_test_flag(&ast_options, AST_OPT_FLAG_DONT_WARN)
1868 #define ast_opt_end_cdr_before_h_exten  ast_test_flag(&ast_options, AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN)
1869 #define ast_opt_internal_timing         ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING)
1870 #define ast_opt_always_fork             ast_test_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK)
1871 #define ast_opt_mute                    ast_test_flag(&ast_options, AST_OPT_FLAG_MUTE)
1872
1873 extern int option_verbose;
1874 extern int option_debug;                /*!< Debugging */
1875 extern int option_maxcalls;             /*!< Maximum number of simultaneous channels */
1876 extern double option_maxload;
1877 extern char defaultlanguage[];
1878
1879 extern pid_t ast_mainpid;
1880
1881 extern char record_cache_dir[AST_CACHE_DIR_LEN];
1882 extern char debug_filename[AST_FILENAME_MAX];
1883
1884 extern int ast_language_is_prefix;
1885
1886
1887
1888 /* linkedlists.h */
1889
1890 #define AST_LIST_LOCK(head)                                             \
1891         ast_mutex_lock(&(head)->lock) 
1892
1893 /*!
1894   \brief Write locks a list.
1895   \param head This is a pointer to the list head structure
1896
1897   This macro attempts to place an exclusive write lock in the
1898   list head structure pointed to by head.
1899   Returns non-zero on success, 0 on failure
1900 */
1901 #define AST_RWLIST_WRLOCK(head)                                         \
1902         ast_rwlock_wrlock(&(head)->lock)
1903
1904 /*!
1905   \brief Read locks a list.
1906   \param head This is a pointer to the list head structure
1907
1908   This macro attempts to place a read lock in the
1909   list head structure pointed to by head.
1910   Returns non-zero on success, 0 on failure
1911 */
1912 #define AST_RWLIST_RDLOCK(head)                                         \
1913         ast_rwlock_rdlock(&(head)->lock)
1914         
1915 /*!
1916   \brief Locks a list, without blocking if the list is locked.
1917   \param head This is a pointer to the list head structure
1918
1919   This macro attempts to place an exclusive lock in the
1920   list head structure pointed to by head.
1921   Returns non-zero on success, 0 on failure
1922 */
1923 #define AST_LIST_TRYLOCK(head)                                          \
1924         ast_mutex_trylock(&(head)->lock) 
1925
1926 /*!
1927   \brief Write locks a list, without blocking if the list is locked.
1928   \param head This is a pointer to the list head structure
1929
1930   This macro attempts to place an exclusive write lock in the
1931   list head structure pointed to by head.
1932   Returns non-zero on success, 0 on failure
1933 */
1934 #define AST_RWLIST_TRYWRLOCK(head)                                      \
1935         ast_rwlock_trywrlock(&(head)->lock)
1936
1937 /*!
1938   \brief Read locks a list, without blocking if the list is locked.
1939   \param head This is a pointer to the list head structure
1940
1941   This macro attempts to place a read lock in the
1942   list head structure pointed to by head.
1943   Returns non-zero on success, 0 on failure
1944 */
1945 #define AST_RWLIST_TRYRDLOCK(head)                                      \
1946         ast_rwlock_tryrdlock(&(head)->lock)
1947         
1948 /*!
1949   \brief Attempts to unlock a list.
1950   \param head This is a pointer to the list head structure
1951
1952   This macro attempts to remove an exclusive lock from the
1953   list head structure pointed to by head. If the list
1954   was not locked by this thread, this macro has no effect.
1955 */
1956 #define AST_LIST_UNLOCK(head)                                           \
1957         ast_mutex_unlock(&(head)->lock)
1958
1959 /*!
1960   \brief Attempts to unlock a read/write based list.
1961   \param head This is a pointer to the list head structure
1962
1963   This macro attempts to remove a read or write lock from the
1964   list head structure pointed to by head. If the list
1965   was not locked by this thread, this macro has no effect.
1966 */
1967 #define AST_RWLIST_UNLOCK(head)                                         \
1968         ast_rwlock_unlock(&(head)->lock)
1969
1970 /*!
1971   \brief Defines a structure to be used to hold a list of specified type.
1972   \param name This will be the name of the defined structure.
1973   \param type This is the type of each list entry.
1974
1975   This macro creates a structure definition that can be used
1976   to hold a list of the entries of type \a type. It does not actually
1977   declare (allocate) a structure; to do that, either follow this
1978   macro with the desired name of the instance you wish to declare,
1979   or use the specified \a name to declare instances elsewhere.
1980
1981   Example usage:
1982   \code
1983   static AST_LIST_HEAD(entry_list, entry) entries;
1984   \endcode
1985
1986   This would define \c struct \c entry_list, and declare an instance of it named
1987   \a entries, all intended to hold a list of type \c struct \c entry.
1988 */
1989 #define AST_LIST_HEAD(name, type)                                       \
1990 struct name {                                                           \
1991         struct type *first;                                             \
1992         struct type *last;                                              \
1993         ast_mutex_t lock;                                               \
1994 }
1995
1996 /*!
1997   \brief Defines a structure to be used to hold a read/write list of specified type.
1998   \param name This will be the name of the defined structure.
1999   \param type This is the type of each list entry.
2000
2001   This macro creates a structure definition that can be used
2002   to hold a list of the entries of type \a type. It does not actually
2003   declare (allocate) a structure; to do that, either follow this
2004   macro with the desired name of the instance you wish to declare,
2005   or use the specified \a name to declare instances elsewhere.
2006
2007   Example usage:
2008   \code
2009   static AST_RWLIST_HEAD(entry_list, entry) entries;
2010   \endcode
2011
2012   This would define \c struct \c entry_list, and declare an instance of it named
2013   \a entries, all intended to hold a list of type \c struct \c entry.
2014 */
2015 #define AST_RWLIST_HEAD(name, type)                                     \
2016 struct name {                                                           \
2017         struct type *first;                                             \
2018         struct type *last;                                              \
2019         ast_rwlock_t lock;                                              \
2020 }
2021
2022 /*!
2023   \brief Defines a structure to be used to hold a list of specified type (with no lock).
2024   \param name This will be the name of the defined structure.
2025   \param type This is the type of each list entry.
2026
2027   This macro creates a structure definition that can be used
2028   to hold a list of the entries of type \a type. It does not actually
2029   declare (allocate) a structure; to do that, either follow this
2030   macro with the desired name of the instance you wish to declare,
2031   or use the specified \a name to declare instances elsewhere.
2032
2033   Example usage:
2034   \code
2035   static AST_LIST_HEAD_NOLOCK(entry_list, entry) entries;
2036   \endcode
2037
2038   This would define \c struct \c entry_list, and declare an instance of it named
2039   \a entries, all intended to hold a list of type \c struct \c entry.
2040 */
2041 #define AST_LIST_HEAD_NOLOCK(name, type)                                \
2042 struct name {                                                           \
2043         struct type *first;                                             \
2044         struct type *last;                                              \
2045 }
2046
2047 /*!
2048   \brief Defines initial values for a declaration of AST_LIST_HEAD
2049 */
2050 #define AST_LIST_HEAD_INIT_VALUE        {               \
2051         .first = NULL,                                  \
2052         .last = NULL,                                   \
2053         .lock = AST_MUTEX_INIT_VALUE,                   \
2054         }
2055
2056 /*!
2057   \brief Defines initial values for a declaration of AST_RWLIST_HEAD
2058 */
2059 #define AST_RWLIST_HEAD_INIT_VALUE      {               \
2060         .first = NULL,                                  \
2061         .last = NULL,                                   \
2062         .lock = AST_RWLOCK_INIT_VALUE,                  \
2063         }
2064
2065 /*!
2066   \brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK
2067 */
2068 #define AST_LIST_HEAD_NOLOCK_INIT_VALUE {       \
2069         .first = NULL,                                  \
2070         .last = NULL,                                   \
2071         }
2072
2073 /*!
2074   \brief Defines a structure to be used to hold a list of specified type, statically initialized.
2075   \param name This will be the name of the defined structure.
2076   \param type This is the type of each list entry.
2077
2078   This macro creates a structure definition that can be used
2079   to hold a list of the entries of type \a type, and allocates an instance
2080   of it, initialized to be empty.
2081
2082   Example usage:
2083   \code
2084   static AST_LIST_HEAD_STATIC(entry_list, entry);
2085   \endcode
2086
2087   This would define \c struct \c entry_list, intended to hold a list of
2088   type \c struct \c entry.
2089 */
2090 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
2091 #define AST_LIST_HEAD_STATIC(name, type)                                \
2092 struct name {                                                           \
2093         struct type *first;                                             \
2094         struct type *last;                                              \
2095         ast_mutex_t lock;                                               \
2096 } name;                                                                 \
2097 static void  __attribute__((constructor)) init_##name(void)             \
2098 {                                                                       \
2099         AST_LIST_HEAD_INIT(&name);                                      \
2100 }                                                                       \
2101 static void  __attribute__((destructor)) fini_##name(void)              \
2102 {                                                                       \
2103         AST_LIST_HEAD_DESTROY(&name);                                   \
2104 }                                                                       \
2105 struct __dummy_##name
2106 #else
2107 #define AST_LIST_HEAD_STATIC(name, type)                                \
2108 struct name {                                                           \
2109         struct type *first;                                             \
2110         struct type *last;                                              \
2111         ast_mutex_t lock;                                               \
2112 } name = AST_LIST_HEAD_INIT_VALUE
2113 #endif
2114
2115 /*!
2116   \brief Defines a structure to be used to hold a read/write list of specified type, statically initialized.
2117   \param name This will be the name of the defined structure.
2118   \param type This is the type of each list entry.
2119
2120   This macro creates a structure definition that can be used
2121   to hold a list of the entries of type \a type, and allocates an instance
2122   of it, initialized to be empty.
2123
2124   Example usage:
2125   \code
2126   static AST_RWLIST_HEAD_STATIC(entry_list, entry);
2127   \endcode
2128
2129   This would define \c struct \c entry_list, intended to hold a list of
2130   type \c struct \c entry.
2131 */
2132 #ifndef AST_RWLOCK_INIT_VALUE
2133 #define AST_RWLIST_HEAD_STATIC(name, type)                              \
2134 struct name {                                                           \
2135         struct type *first;                                             \
2136         struct type *last;                                              \
2137         ast_rwlock_t lock;                                              \
2138 } name;                                                                 \
2139 static void  __attribute__((constructor)) init_##name(void)            \
2140 {                                                                       \
2141         AST_RWLIST_HEAD_INIT(&name);                                    \
2142 }                                                                       \
2143 static void  __attribute__((destructor)) fini_##name(void)             \
2144 {                                                                       \
2145         AST_RWLIST_HEAD_DESTROY(&name);                                 \
2146 }                                                                       \
2147 struct __dummy_##name
2148 #else
2149 #define AST_RWLIST_HEAD_STATIC(name, type)                              \
2150 struct name {                                                           \
2151         struct type *first;                                             \
2152         struct type *last;                                              \
2153         ast_rwlock_t lock;                                              \
2154 } name = AST_RWLIST_HEAD_INIT_VALUE
2155 #endif
2156
2157 /*!
2158   \brief Defines a structure to be used to hold a list of specified type, statically initialized.
2159
2160   This is the same as AST_LIST_HEAD_STATIC, except without the lock included.
2161 */
2162 #define AST_LIST_HEAD_NOLOCK_STATIC(name, type)                         \
2163 struct name {                                                           \
2164         struct type *first;                                             \
2165         struct type *last;                                              \
2166 } name = AST_LIST_HEAD_NOLOCK_INIT_VALUE
2167
2168 /*!
2169   \brief Initializes a list head structure with a specified first entry.
2170   \param head This is a pointer to the list head structure
2171   \param entry pointer to the list entry that will become the head of the list
2172
2173   This macro initializes a list head structure by setting the head
2174   entry to the supplied value and recreating the embedded lock.
2175 */
2176 #define AST_LIST_HEAD_SET(head, entry) do {                             \
2177         (head)->first = (entry);                                        \
2178         (head)->last = (entry);                                         \
2179         ast_mutex_init(&(head)->lock);                                  \
2180 } while (0)
2181
2182 /*!
2183   \brief Initializes an rwlist head structure with a specified first entry.
2184   \param head This is a pointer to the list head structure
2185   \param entry pointer to the list entry that will become the head of the list
2186
2187   This macro initializes a list head structure by setting the head
2188   entry to the supplied value and recreating the embedded lock.
2189 */
2190 #define AST_RWLIST_HEAD_SET(head, entry) do {                           \
2191         (head)->first = (entry);                                        \
2192         (head)->last = (entry);                                         \
2193         ast_rwlock_init(&(head)->lock);                                 \
2194 } while (0)
2195
2196 /*!
2197   \brief Initializes a list head structure with a specified first entry.
2198   \param head This is a pointer to the list head structure
2199   \param entry pointer to the list entry that will become the head of the list
2200
2201   This macro initializes a list head structure by setting the head
2202   entry to the supplied value.
2203 */
2204 #define AST_LIST_HEAD_SET_NOLOCK(head, entry) do {                      \
2205         (head)->first = (entry);                                        \
2206         (head)->last = (entry);                                         \
2207 } while (0)
2208
2209 /*!
2210   \brief Declare a forward link structure inside a list entry.
2211   \param type This is the type of each list entry.
2212
2213   This macro declares a structure to be used to link list entries together.
2214   It must be used inside the definition of the structure named in
2215   \a type, as follows:
2216
2217   \code
2218   struct list_entry {
2219         ...
2220         AST_LIST_ENTRY(list_entry) list;
2221   }
2222   \endcode
2223
2224   The field name \a list here is arbitrary, and can be anything you wish.
2225 */
2226 #define AST_LIST_ENTRY(type)                                            \
2227 struct {                                                                \
2228         struct type *next;                                              \
2229 }
2230
2231 #define AST_RWLIST_ENTRY AST_LIST_ENTRY
2232  
2233 /*!
2234   \brief Returns the first entry contained in a list.
2235   \param head This is a pointer to the list head structure
2236  */
2237 #define AST_LIST_FIRST(head)    ((head)->first)
2238
2239 #define AST_RWLIST_FIRST AST_LIST_FIRST
2240
2241 /*!
2242   \brief Returns the last entry contained in a list.
2243   \param head This is a pointer to the list head structure
2244  */
2245 #define AST_LIST_LAST(head)     ((head)->last)
2246
2247 #define AST_RWLIST_LAST AST_LIST_LAST
2248
2249 /*!
2250   \brief Returns the next entry in the list after the given entry.
2251   \param elm This is a pointer to the current entry.
2252   \param field This is the name of the field (declared using AST_LIST_ENTRY())
2253   used to link entries of this list together.
2254 */
2255 #define AST_LIST_NEXT(elm, field)       ((elm)->field.next)
2256
2257 #define AST_RWLIST_NEXT AST_LIST_NEXT
2258
2259 /*!
2260   \brief Checks whether the specified list contains any entries.
2261   \param head This is a pointer to the list head structure
2262
2263   Returns non-zero if the list has entries, zero if not.
2264  */
2265 #define AST_LIST_EMPTY(head)    (AST_LIST_FIRST(head) == NULL)
2266
2267 #define AST_RWLIST_EMPTY AST_LIST_EMPTY
2268
2269 /*!
2270   \brief Loops over (traverses) the entries in a list.
2271   \param head This is a pointer to the list head structure
2272   \param var This is the name of the variable that will hold a pointer to the
2273   current list entry on each iteration. It must be declared before calling
2274   this macro.
2275   \param field This is the name of the field (declared using AST_LIST_ENTRY())
2276   used to link entries of this list together.
2277
2278   This macro is use to loop over (traverse) the entries in a list. It uses a
2279   \a for loop, and supplies the enclosed code with a pointer to each list
2280   entry as it loops. It is typically used as follows:
2281   \code
2282   static AST_LIST_HEAD(entry_list, list_entry) entries;
2283   ...
2284   struct list_entry {
2285         ...
2286         AST_LIST_ENTRY(list_entry) list;
2287   }
2288   ...
2289   struct list_entry *current;
2290   ...
2291   AST_LIST_TRAVERSE(&entries, current, list) {
2292      (do something with current here)
2293   }
2294   \endcode
2295   \warning If you modify the forward-link pointer contained in the \a current entry while
2296   inside the loop, the behavior will be unpredictable. At a minimum, the following
2297   macros will modify the forward-link pointer, and should not be used inside
2298   AST_LIST_TRAVERSE() against the entry pointed to by the \a current pointer without
2299   careful consideration of their consequences:
2300   \li AST_LIST_NEXT() (when used as an lvalue)
2301   \li AST_LIST_INSERT_AFTER()
2302   \li AST_LIST_INSERT_HEAD()
2303   \li AST_LIST_INSERT_TAIL()
2304 */
2305 #define AST_LIST_TRAVERSE(head,var,field)                               \
2306         for((var) = (head)->first; (var); (var) = (var)->field.next)
2307
2308 #define AST_RWLIST_TRAVERSE AST_LIST_TRAVERSE
2309
2310 /*!
2311   \brief Loops safely over (traverses) the entries in a list.
2312   \param head This is a pointer to the list head structure
2313   \param var This is the name of the variable that will hold a pointer to the
2314   current list entry on each iteration. It must be declared before calling
2315   this macro.
2316   \param field This is the name of the field (declared using AST_LIST_ENTRY())
2317   used to link entries of this list together.
2318
2319   This macro is used to safely loop over (traverse) the entries in a list. It
2320   uses a \a for loop, and supplies the enclosed code with a pointer to each list
2321   entry as it loops. It is typically used as follows:
2322
2323   \code
2324   static AST_LIST_HEAD(entry_list, list_entry) entries;
2325   ...
2326   struct list_entry {
2327         ...
2328         AST_LIST_ENTRY(list_entry) list;
2329   }
2330   ...
2331   struct list_entry *current;
2332   ...
2333   AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
2334      (do something with current here)
2335   }
2336   AST_LIST_TRAVERSE_SAFE_END;
2337   \endcode
2338
2339   It differs from AST_LIST_TRAVERSE() in that the code inside the loop can modify
2340   (or even free, after calling AST_LIST_REMOVE_CURRENT()) the entry pointed to by
2341   the \a current pointer without affecting the loop traversal.
2342 */
2343 #define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) {                                \
2344         typeof((head)->first) __list_next;                                              \
2345         typeof((head)->first) __list_prev = NULL;                                       \
2346         typeof((head)->first) __new_prev = NULL;                                        \
2347         for ((var) = (head)->first, __new_prev = (var),                                 \
2348               __list_next = (var) ? (var)->field.next : NULL;                           \
2349              (var);                                                                     \
2350              __list_prev = __new_prev, (var) = __list_next,                             \
2351              __new_prev = (var),                                                        \
2352              __list_next = (var) ? (var)->field.next : NULL                             \
2353             )
2354
2355 #define AST_RWLIST_TRAVERSE_SAFE_BEGIN AST_LIST_TRAVERSE_SAFE_BEGIN
2356
2357 /*!
2358   \brief Removes the \a current entry from a list during a traversal.
2359   \param head This is a pointer to the list head structure
2360   \param field This is the name of the field (declared using AST_LIST_ENTRY())
2361   used to link entries of this list together.
2362
2363   \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
2364   block; it is used to unlink the current entry from the list without affecting
2365   the list traversal (and without having to re-traverse the list to modify the
2366   previous entry, if any).
2367  */
2368 #define AST_LIST_REMOVE_CURRENT(head, field)                                            \
2369         __new_prev->field.next = NULL;                                                  \
2370         __new_prev = __list_prev;                                                       \
2371         if (__list_prev)                                                                \
2372                 __list_prev->field.next = __list_next;                                  \
2373         else                                                                            \
2374                 (head)->first = __list_next;                                            \
2375         if (!__list_next)                                                               \
2376                 (head)->last = __list_prev;
2377
2378 #define AST_RWLIST_REMOVE_CURRENT AST_LIST_REMOVE_CURRENT
2379
2380 /*!
2381   \brief Inserts a list entry before the current entry during a traversal.
2382   \param head This is a pointer to the list head structure
2383   \param elm This is a pointer to the entry to be inserted.
2384   \param field This is the name of the field (declared using AST_LIST_ENTRY())
2385   used to link entries of this list together.
2386
2387   \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
2388   block.
2389  */
2390 #define AST_LIST_INSERT_BEFORE_CURRENT(head, elm, field) do {           \
2391         if (__list_prev) {                                              \
2392                 (elm)->field.next = __list_prev->field.next;            \
2393                 __list_prev->field.next = elm;                          \
2394         } else {                                                        \
2395                 (elm)->field.next = (head)->first;                      \
2396                 (head)->first = (elm);                                  \
2397         }                                                               \
2398         __new_prev = (elm);                                             \
2399 } while (0)
2400
2401 #define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT
2402
2403 /*!
2404   \brief Closes a safe loop traversal block.
2405  */
2406 #define AST_LIST_TRAVERSE_SAFE_END  }
2407
2408 #define AST_RWLIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END
2409
2410 /*!
2411   \brief Initializes a list head structure.
2412   \param head This is a pointer to the list head structure
2413
2414   This macro initializes a list head structure by setting the head
2415   entry to \a NULL (empty list) and recreating the embedded lock.
2416 */
2417 #define AST_LIST_HEAD_INIT(head) {                                      \
2418         (head)->first = NULL;                                           \
2419         (head)->last = NULL;                                            \
2420         ast_mutex_init(&(head)->lock);                                  \
2421 }
2422
2423 /*!
2424   \brief Initializes an rwlist head structure.
2425   \param head This is a pointer to the list head structure
2426
2427   This macro initializes a list head structure by setting the head
2428   entry to \a NULL (empty list) and recreating the embedded lock.
2429 */
2430 #define AST_RWLIST_HEAD_INIT(head) {                                    \
2431         (head)->first = NULL;                                           \
2432         (head)->last = NULL;                                            \
2433         ast_rwlock_init(&(head)->lock);                                 \
2434 }
2435
2436 /*!
2437   \brief Destroys a list head structure.
2438   \param head This is a pointer to the list head structure
2439
2440   This macro destroys a list head structure by setting the head
2441   entry to \a NULL (empty list) and destroying the embedded lock.
2442   It does not free the structure from memory.
2443 */
2444 #define AST_LIST_HEAD_DESTROY(head) {                                   \
2445         (head)->first = NULL;                                           \
2446         (head)->last = NULL;                                            \
2447         ast_mutex_destroy(&(head)->lock);                               \
2448 }
2449
2450 /*!
2451   \brief Destroys an rwlist head structure.
2452   \param head This is a pointer to the list head structure
2453
2454   This macro destroys a list head structure by setting the head
2455   entry to \a NULL (empty list) and destroying the embedded lock.
2456   It does not free the structure from memory.
2457 */
2458 #define AST_RWLIST_HEAD_DESTROY(head) {                                 \
2459         (head)->first = NULL;                                           \
2460         (head)->last = NULL;                                            \
2461         ast_rwlock_destroy(&(head)->lock);                              \
2462 }
2463
2464 /*!
2465   \brief Initializes a list head structure.
2466   \param head This is a pointer to the list head structure
2467
2468   This macro initializes a list head structure by setting the head
2469   entry to \a NULL (empty list). There is no embedded lock handling
2470   with this macro.
2471 */
2472 #define AST_LIST_HEAD_INIT_NOLOCK(head) {                               \
2473         (head)->first = NULL;                                           \
2474         (head)->last = NULL;                                            \
2475 }
2476
2477 /*!
2478   \brief Inserts a list entry after a given entry.
2479   \param head This is a pointer to the list head structure
2480   \param listelm This is a pointer to the entry after which the new entry should
2481   be inserted.
2482   \param elm This is a pointer to the entry to be inserted.
2483   \param field This is the name of the field (declared using AST_LIST_ENTRY())
2484   used to link entries of this list together.
2485  */
2486 #define AST_LIST_INSERT_AFTER(head, listelm, elm, field) do {           \
2487         (elm)->field.next = (listelm)->field.next;                      \
2488         (listelm)->field.next = (elm);                                  \
2489         if ((head)->last == (listelm))                                  \
2490                 (head)->last = (elm);                                   \
2491 } while (0)
2492
2493 #define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER
2494
2495 /*!
2496   \brief Inserts a list entry at the head of a list.
2497   \param head This is a pointer to the list head structure
2498   \param elm This is a pointer to the entry to be inserted.
2499   \param field This is the name of the field (declared using AST_LIST_ENTRY())
2500   used to link entries of this list together.
2501  */
2502 #define AST_LIST_INSERT_HEAD(head, elm, field) do {                     \
2503                 (elm)->field.next = (head)->first;                      \
2504                 (head)->first = (elm);                                  \
2505                 if (!(head)->last)                                      \
2506                         (head)->last = (elm);                           \
2507 } while (0)
2508
2509 #define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD
2510
2511 /*!
2512   \brief Appends a list entry to the tail of a list.
2513   \param head This is a pointer to the list head structure
2514   \param elm This is a pointer to the entry to be appended.
2515   \param field This is the name of the field (declared using AST_LIST_ENTRY())
2516   used to link entries of this list together.
2517
2518   Note: The link field in the appended entry is \b not modified, so if it is
2519   actually the head of a list itself, the entire list will be appended
2520   temporarily (until the next AST_LIST_INSERT_TAIL is performed).
2521  */
2522 #define AST_LIST_INSERT_TAIL(head, elm, field) do {                     \
2523       if (!(head)->first) {                                             \
2524                 (head)->first = (elm);                                  \
2525                 (head)->last = (elm);                                   \
2526       } else {                                                          \
2527                 (head)->last->field.next = (elm);                       \
2528                 (head)->last = (elm);                                   \
2529       }                                                                 \
2530 } while (0)
2531
2532 #define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL
2533
2534 /*!
2535   \brief Appends a whole list to the tail of a list.
2536   \param head This is a pointer to the list head structure
2537   \param list This is a pointer to the list to be appended.
2538   \param field This is the name of the field (declared using AST_LIST_ENTRY())
2539   used to link entries of this list together.
2540  */
2541 #define AST_LIST_APPEND_LIST(head, list, field) do {                    \
2542       if (!(head)->first) {                                             \
2543                 (head)->first = (list)->first;                          \
2544                 (head)->last = (list)->last;                            \
2545       } else {                                                          \
2546                 (head)->last->field.next = (list)->first;               \
2547                 (head)->last = (list)->last;                            \
2548       }                                                                 \
2549 } while (0)
2550
2551 #define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST
2552
2553 /*!
2554   \brief Removes and returns the head entry from a list.
2555   \param head This is a pointer to the list head structure
2556   \param field This is the name of the field (declared using AST_LIST_ENTRY())
2557   used to link entries of this list together.
2558
2559   Removes the head entry from the list, and returns a pointer to it.
2560   This macro is safe to call on an empty list.
2561  */
2562 #define AST_LIST_REMOVE_HEAD(head, field) ({                            \
2563                 typeof((head)->first) cur = (head)->first;              \
2564                 if (cur) {                                              \
2565                         (head)->first = cur->field.next;                \
2566                         cur->field.next = NULL;                         \
2567                         if ((head)->last == cur)                        \
2568                                 (head)->last = NULL;                    \
2569                 }                                                       \
2570                 cur;                                                    \
2571         })
2572
2573 #define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD
2574
2575 /*!
2576   \brief Removes a specific entry from a list.
2577   \param head This is a pointer to the list head structure
2578   \param elm This is a pointer to the entry to be removed.
2579   \param field This is the name of the field (declared using AST_LIST_ENTRY())
2580   used to link entries of this list together.
2581   \warning The removed entry is \b not freed nor modified in any way.
2582  */
2583 #define AST_LIST_REMOVE(head, elm, field) do {                          \
2584         if ((head)->first == (elm)) {                                   \
2585                 (head)->first = (elm)->field.next;                      \
2586                 if ((head)->last == (elm))                      \
2587                         (head)->last = NULL;                    \
2588         } else {                                                                \
2589                 typeof(elm) curelm = (head)->first;                     \
2590                 while (curelm && (curelm->field.next != (elm)))                 \
2591                         curelm = curelm->field.next;                    \
2592                 if (curelm) { \
2593                         curelm->field.next = (elm)->field.next;                 \
2594                         if ((head)->last == (elm))                              \
2595                                 (head)->last = curelm;                          \
2596                 } \
2597         }                                                               \
2598         (elm)->field.next = NULL;                                       \
2599 } while (0)
2600
2601 #define AST_RWLIST_REMOVE AST_LIST_REMOVE
2602
2603 /* chanvars.h */
2604
2605 struct ast_var_t {
2606         AST_LIST_ENTRY(ast_var_t) entries;
2607         char *value;
2608         char name[0];
2609 };
2610
2611 AST_LIST_HEAD_NOLOCK(varshead, ast_var_t);
2612
2613 AST_RWLOCK_DEFINE_STATIC(globalslock);
2614 static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
2615
2616
2617 /* IN CONFLICT: struct ast_var_t *ast_var_assign(const char *name, const char *value); */
2618
2619 static struct ast_var_t *ast_var_assign(const char *name, const char *value);
2620
2621 static void ast_var_delete(struct ast_var_t *var);
2622
2623 /*from channel.h */
2624 #define AST_MAX_EXTENSION  80      /*!< Max length of an extension */
2625
2626
2627 /* from pbx.h */
2628 #define PRIORITY_HINT   -1      /*!< Special Priority for a hint */
2629
2630 enum ast_extension_states {
2631         AST_EXTENSION_REMOVED = -2,     /*!< Extension removed */
2632         AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */
2633         AST_EXTENSION_NOT_INUSE = 0,    /*!< No device INUSE or BUSY  */
2634         AST_EXTENSION_INUSE = 1 << 0,   /*!< One or more devices INUSE */
2635         AST_EXTENSION_BUSY = 1 << 1,    /*!< All devices BUSY */
2636         AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */
2637         AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */
2638         AST_EXTENSION_ONHOLD = 1 << 4,  /*!< All devices ONHOLD */
2639 };
2640
2641 struct ast_custom_function {
2642         const char *name;               /*!< Name */
2643         const char *synopsis;           /*!< Short description for "show functions" */
2644         const char *desc;               /*!< Help text that explains it all */
2645         const char *syntax;             /*!< Syntax description */
2646         int (*read)(struct ast_channel *, const char *, char *, char *, size_t);        /*!< Read function, if read is supported */
2647         int (*write)(struct ast_channel *, const char *, char *, const char *);         /*!< Write function, if write is supported */
2648         AST_RWLIST_ENTRY(ast_custom_function) acflist;
2649 };
2650
2651 typedef int (ast_switch_f)(struct ast_channel *chan, const char *context,
2652         const char *exten, int priority, const char *callerid, const char *data);
2653
2654 struct ast_switch {
2655         AST_LIST_ENTRY(ast_switch) list;
2656         const char *name;                       /*!< Name of the switch */
2657         const char *description;                /*!< Description of the switch */
2658         
2659         ast_switch_f *exists;
2660         ast_switch_f *canmatch;
2661         ast_switch_f *exec;
2662         ast_switch_f *matchmore;
2663 };
2664
2665
2666 static char *config_filename = "extensions.conf";
2667 static char *global_registrar = "conf2ael";
2668 static char userscontext[AST_MAX_EXTENSION] = "default";
2669 static int static_config = 0;
2670 static int write_protect_config = 1;
2671 static int autofallthrough_config = 0;
2672 static int clearglobalvars_config = 0;
2673 /*! Go no deeper than this through includes (not counting loops) */
2674 #define AST_PBX_MAX_STACK       128
2675 static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
2676
2677
2678 /* stolen from callerid.c */
2679
2680 /*! \brief Clean up phone string
2681  * remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets.
2682  * Basically, remove anything that could be invalid in a pattern.
2683  */
2684 static void ast_shrink_phone_number(char *n)
2685 {
2686         int x, y=0;
2687         int bracketed = 0;
2688
2689         for (x=0; n[x]; x++) {
2690                 switch(n[x]) {
2691                 case '[':
2692                         bracketed++;
2693                         n[y++] = n[x];
2694                         break;
2695                 case ']':
2696                         bracketed--;
2697                         n[y++] = n[x];
2698                         break;
2699                 case '-':
2700                         if (bracketed)
2701                                 n[y++] = n[x];
2702                         break;
2703                 case '.':
2704                         if (!n[x+1])
2705                                 n[y++] = n[x];
2706                         break;
2707                 default:
2708                         if (!strchr("()", n[x]))
2709                                 n[y++] = n[x];
2710                 }
2711         }
2712         n[y] = '\0';
2713 }
2714
2715
2716 /* stolen from chanvars.c */
2717
2718 static const char *ast_var_name(const struct ast_var_t *var)
2719 {
2720         const char *name;
2721
2722         if (var == NULL || (name = var->name) == NULL)
2723                 return NULL;
2724         /* Return the name without the initial underscores */
2725         if (name[0] == '_') {
2726                 name++;
2727                 if (name[0] == '_')
2728                         name++;
2729         }
2730         return name;
2731 }
2732
2733 /* experiment 1: see if it's easier just to use existing config code
2734  *               to read in the extensions.conf file. In this scenario, 
2735                  I have to rip/copy code from other modules, because they
2736                  are staticly declared as-is. A solution would be to move
2737                  the ripped code to another location and make them available
2738                  to other modules and standalones */
2739
2740 /* Our own version of ast_log, since the expr parser uses it. -- stolen from utils/check_expr.c */
2741
2742 static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
2743 {
2744         va_list vars;
2745         va_start(vars,fmt);
2746         
2747         printf("LOG: lev:%d file:%s  line:%d func: %s  ",
2748                    level, file, line, function);
2749         vprintf(fmt, vars);
2750         fflush(stdout);
2751         va_end(vars);
2752 }
2753
2754 void __attribute__((format(printf, 1, 2))) ast_verbose(const char *fmt, ...)
2755 {
2756         va_list vars;
2757         va_start(vars,fmt);
2758         
2759         printf("VERBOSE: ");
2760         vprintf(fmt, vars);
2761         fflush(stdout);
2762         va_end(vars);
2763 }
2764
2765 /* stolen from main/utils.c */
2766 static char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
2767 {
2768         char *dataPut = start;
2769         int inEscape = 0;
2770         int inQuotes = 0;
2771
2772         for (; *start; start++) {
2773                 if (inEscape) {
2774                         *dataPut++ = *start;       /* Always goes verbatim */
2775                         inEscape = 0;
2776                 } else {
2777                         if (*start == '\\') {
2778                                 inEscape = 1;      /* Do not copy \ into the data */
2779                         } else if (*start == '\'') {
2780                                 inQuotes = 1 - inQuotes;   /* Do not copy ' into the data */
2781                         } else {
2782                                 /* Replace , with |, unless in quotes */
2783                                 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
2784                         }
2785                 }
2786         }
2787         if (start != dataPut)
2788                 *dataPut = 0;
2789         return dataPut;
2790 }
2791
2792 static int ast_true(const char *s)
2793 {
2794         if (ast_strlen_zero(s))
2795                 return 0;
2796
2797         /* Determine if this is a true value */
2798         if (!strcasecmp(s, "yes") ||
2799             !strcasecmp(s, "true") ||
2800             !strcasecmp(s, "y") ||
2801             !strcasecmp(s, "t") ||
2802             !strcasecmp(s, "1") ||
2803             !strcasecmp(s, "on"))
2804                 return -1;
2805
2806         return 0;
2807 }
2808
2809 #define ONE_MILLION     1000000
2810 /*
2811  * put timeval in a valid range. usec is 0..999999
2812  * negative values are not allowed and truncated.
2813  */
2814 static struct timeval tvfix(struct timeval a)
2815 {
2816         if (a.tv_usec >= ONE_MILLION) {
2817                 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
2818                         (long)a.tv_sec, (long int) a.tv_usec);
2819                 a.tv_sec += a.tv_usec / ONE_MILLION;
2820                 a.tv_usec %= ONE_MILLION;
2821         } else if (a.tv_usec < 0) {
2822                 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
2823                         (long)a.tv_sec, (long int) a.tv_usec);
2824                 a.tv_usec = 0;
2825         }
2826         return a;
2827 }
2828
2829 struct timeval ast_tvadd(struct timeval a, struct timeval b);
2830 struct timeval ast_tvadd(struct timeval a, struct timeval b)
2831 {
2832         /* consistency checks to guarantee usec in 0..999999 */
2833         a = tvfix(a);
2834         b = tvfix(b);
2835         a.tv_sec += b.tv_sec;
2836         a.tv_usec += b.tv_usec;
2837         if (a.tv_usec >= ONE_MILLION) {
2838                 a.tv_sec++;
2839                 a.tv_usec -= ONE_MILLION;
2840         }
2841         return a;
2842 }
2843
2844 struct timeval ast_tvsub(struct timeval a, struct timeval b);
2845 struct timeval ast_tvsub(struct timeval a, struct timeval b)
2846 {
2847         /* consistency checks to guarantee usec in 0..999999 */
2848         a = tvfix(a);
2849         b = tvfix(b);
2850         a.tv_sec -= b.tv_sec;
2851         a.tv_usec -= b.tv_usec;
2852         if (a.tv_usec < 0) {
2853                 a.tv_sec-- ;
2854                 a.tv_usec += ONE_MILLION;
2855         }
2856         return a;
2857 }
2858 #undef ONE_MILLION
2859
2860 void ast_mark_lock_failed(void *lock_addr);
2861 void ast_mark_lock_failed(void *lock_addr)
2862 {
2863         /* Pretend to do something. */
2864 }
2865
2866 /* stolen from pbx.c */
2867 #define VAR_BUF_SIZE 4096
2868
2869 #define VAR_NORMAL              1
2870 #define VAR_SOFTTRAN    2
2871 #define VAR_HARDTRAN    3
2872
2873 #define BACKGROUND_SKIP         (1 << 0)
2874 #define BACKGROUND_NOANSWER     (1 << 1)
2875 #define BACKGROUND_MATCHEXTEN   (1 << 2)
2876 #define BACKGROUND_PLAYBACK     (1 << 3)
2877
2878 /*!
2879    \brief ast_exten: An extension
2880         The dialplan is saved as a linked list with each context
2881         having it's own linked list of extensions - one item per
2882         priority.
2883 */
2884 struct ast_exten {
2885         char *exten;                    /*!< Extension name */
2886         int matchcid;                   /*!< Match caller id ? */
2887         const char *cidmatch;           /*!< Caller id to match for this extension */
2888         int priority;                   /*!< Priority */
2889         const char *label;              /*!< Label */
2890         struct ast_context *parent;     /*!< The context this extension belongs to  */
2891         const char *app;                /*!< Application to execute */
2892         struct ast_app *cached_app;     /*!< Cached location of application */
2893         void *data;                     /*!< Data to use (arguments) */
2894         void (*datad)(void *);          /*!< Data destructor */
2895         struct ast_exten *peer;         /*!< Next higher priority with our extension */
2896         const char *registrar;          /*!< Registrar */
2897         struct ast_exten *next;         /*!< Extension with a greater ID */
2898         char stuff[0];
2899 };
2900 /* from pbx.h */
2901 typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data);
2902 struct ast_timing {
2903         int hastime;                            /*!< If time construct exists */
2904         unsigned int monthmask;                 /*!< Mask for month */
2905         unsigned int daymask;                   /*!< Mask for date */
2906         unsigned int dowmask;                   /*!< Mask for day of week (mon-sun) */
2907         unsigned int minmask[24];               /*!< Mask for minute */
2908         char *timezone;                 /*!< NULL, or zoneinfo style timezone */
2909 };
2910 /* end of pbx.h */
2911 /*! \brief ast_include: include= support in extensions.conf */
2912 struct ast_include {
2913         const char *name;
2914         const char *rname;                      /*!< Context to include */
2915         const char *registrar;                  /*!< Registrar */
2916         int hastime;                            /*!< If time construct exists */
2917         struct ast_timing timing;               /*!< time construct */
2918         struct ast_include *next;               /*!< Link them together */
2919         char stuff[0];
2920 };
2921
2922 /*! \brief ast_sw: Switch statement in extensions.conf */
2923 struct ast_sw {
2924         char *name;
2925         const char *registrar;                  /*!< Registrar */
2926         char *data;                             /*!< Data load */
2927         int eval;
2928         AST_LIST_ENTRY(ast_sw) list;
2929         char *tmpdata;
2930         char stuff[0];
2931 };
2932
2933 /*! \brief ast_ignorepat: Ignore patterns in dial plan */
2934 struct ast_ignorepat {
2935         const char *registrar;
2936         struct ast_ignorepat *next;
2937         char pattern[0];
2938 };
2939
2940 /*! \brief ast_context: An extension context */
2941 struct ast_context {
2942         ast_rwlock_t lock;                      /*!< A lock to prevent multiple threads from clobbering the context */
2943         struct ast_exten *root;                 /*!< The root of the list of extensions */
2944         struct ast_context *next;               /*!< Link them together */
2945         struct ast_include *includes;           /*!< Include other contexts */
2946         struct ast_ignorepat *ignorepats;       /*!< Patterns for which to continue playing dialtone */
2947         const char *registrar;                  /*!< Registrar */
2948         AST_LIST_HEAD_NOLOCK(, ast_sw) alts;    /*!< Alternative switches */
2949         ast_mutex_t macrolock;                  /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
2950         char name[0];                           /*!< Name of the context */
2951 };
2952
2953
2954 /*! \brief ast_app: A registered application */
2955 struct ast_app {
2956         int (*execute)(struct ast_channel *chan, void *data);
2957         const char *synopsis;                   /*!< Synopsis text for 'show applications' */
2958         const char *description;                /*!< Description (help text) for 'show application &lt;name&gt;' */
2959         AST_RWLIST_ENTRY(ast_app) list;         /*!< Next app in list */
2960         void *module;                   /*!< Module this app belongs to */
2961         char name[0];                           /*!< Name of the application */
2962 };
2963
2964
2965 /*! \brief ast_state_cb: An extension state notify register item */
2966 struct ast_state_cb {
2967         int id;
2968         void *data;
2969         ast_state_cb_type callback;
2970         struct ast_state_cb *next;
2971 };
2972
2973 /*! \brief Structure for dial plan hints
2974
2975   \note Hints are pointers from an extension in the dialplan to one or
2976   more devices (tech/name) 
2977         - See \ref AstExtState
2978 */
2979 struct ast_hint {
2980         struct ast_exten *exten;        /*!< Extension */
2981         int laststate;                  /*!< Last known state */
2982         struct ast_state_cb *callbacks; /*!< Callback list for this extension */
2983         AST_RWLIST_ENTRY(ast_hint) list;/*!< Pointer to next hint in list */
2984 };
2985
2986 struct store_hint {
2987         char *context;
2988         char *exten;
2989         struct ast_state_cb *callbacks;
2990         int laststate;
2991         AST_LIST_ENTRY(store_hint) list;
2992         char data[1];
2993 };
2994
2995 AST_LIST_HEAD(store_hints, store_hint);
2996
2997 static const struct cfextension_states {
2998         int extension_state;
2999         const char * const text;
3000 } extension_states[] = {
3001         { AST_EXTENSION_NOT_INUSE,                     "Idle" },
3002         { AST_EXTENSION_INUSE,                         "InUse" },
3003         { AST_EXTENSION_BUSY,                          "Busy" },
3004         { AST_EXTENSION_UNAVAILABLE,                   "Unavailable" },
3005         { AST_EXTENSION_RINGING,                       "Ringing" },
3006         { AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
3007         { AST_EXTENSION_ONHOLD,                        "Hold" },
3008         { AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD,  "InUse&Hold" }
3009 };
3010 #define STATUS_NO_CONTEXT       1
3011 #define STATUS_NO_EXTENSION     2
3012 #define STATUS_NO_PRIORITY      3
3013 #define STATUS_NO_LABEL         4
3014 #define STATUS_SUCCESS          5
3015
3016
3017 #if defined ( __i386__) && (defined(__FreeBSD__) || defined(linux))
3018 #if defined(__FreeBSD__)
3019 #include <machine/cpufunc.h>
3020 #elif defined(linux)
3021 static __inline uint64_t
3022 rdtsc(void)
3023
3024         uint64_t rv;
3025
3026         __asm __volatile(".byte 0x0f, 0x31" : "=A" (rv));
3027         return (rv);
3028 }
3029 #endif
3030 #else   /* supply a dummy function on other platforms */
3031 static __inline uint64_t
3032 rdtsc(void)
3033 {
3034         return 0;
3035 }
3036 #endif
3037
3038
3039 static struct ast_var_t *ast_var_assign(const char *name, const char *value)
3040 {       
3041         struct ast_var_t *var;
3042         int name_len = strlen(name) + 1;
3043         int value_len = strlen(value) + 1;
3044
3045         if (!(var = ast_calloc(sizeof(*var) + name_len + value_len, sizeof(char)))) {
3046                 return NULL;
3047         }
3048
3049         ast_copy_string(var->name, name, name_len);
3050         var->value = var->name + name_len;
3051         ast_copy_string(var->value, value, value_len);
3052         
3053         return var;
3054 }       
3055         
3056 static void ast_var_delete(struct ast_var_t *var)
3057 {
3058         free(var);
3059 }
3060
3061
3062 /* chopped this one off at the knees! */
3063 static int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
3064 {
3065
3066         /* ast_log(LOG_ERROR, "Function %s not registered\n", function); we are not interested in the details here */
3067
3068         return -1;
3069 }
3070
3071 static unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
3072 {
3073         int argc;
3074         char *scan;
3075         int paren = 0, quote = 0;
3076
3077         if (!buf || !array || !arraylen)
3078                 return 0;
3079
3080         memset(array, 0, arraylen * sizeof(*array));
3081
3082         scan = buf;
3083
3084         for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
3085                 array[argc] = scan;
3086                 for (; *scan; scan++) {
3087                         if (*scan == '(')
3088                                 paren++;
3089                         else if (*scan == ')') {
3090                                 if (paren)
3091                                         paren--;
3092                         } else if (*scan == '"' && delim != '"') {
3093                                 quote = quote ? 0 : 1;
3094                                 /* Remove quote character from argument */
3095                                 memmove(scan, scan + 1, strlen(scan));
3096                                 scan--;
3097                         } else if (*scan == '\\') {
3098                                 /* Literal character, don't parse */
3099                                 memmove(scan, scan + 1, strlen(scan));
3100                         } else if ((*scan == delim) && !paren && !quote) {
3101                                 *scan++ = '\0';
3102                                 break;
3103                         }
3104                 }
3105         }
3106
3107         if (*scan)
3108                 array[argc++] = scan;
3109
3110         return argc;
3111 }
3112
3113 static void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
3114 {
3115         struct ast_var_t *newvariable;
3116         struct varshead *headp;
3117         const char *nametail = name;
3118
3119         /* XXX may need locking on the channel ? */
3120         if (name[strlen(name)-1] == ')') {
3121                 char *function = ast_strdupa(name);
3122
3123                 ast_func_write(chan, function, value);
3124                 return;
3125         }
3126
3127         headp = &globals;
3128
3129         /* For comparison purposes, we have to strip leading underscores */
3130         if (*nametail == '_') {
3131                 nametail++;
3132                 if (*nametail == '_')
3133                         nametail++;
3134         }
3135
3136         AST_LIST_TRAVERSE (headp, newvariable, entries) {
3137                 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
3138                         /* there is already such a variable, delete it */
3139                         AST_LIST_REMOVE(headp, newvariable, entries);
3140                         ast_var_delete(newvariable);
3141                         break;
3142                 }
3143         }
3144
3145         if (value) {
3146                 if ((option_verbose > 1) && (headp == &globals))
3147                         ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
3148                 newvariable = ast_var_assign(name, value);
3149                 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
3150         }
3151
3152 }
3153
3154 static int pbx_builtin_setvar(struct ast_channel *chan, const void *data)
3155 {
3156         char *name, *value, *mydata;
3157         int argc;
3158         char *argv[24];         /* this will only support a maximum of 24 variables being set in a single operation */
3159         int global = 0;
3160         int x;
3161
3162         if (ast_strlen_zero(data)) {
3163                 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n");
3164                 return 0;
3165         }
3166
3167         mydata = ast_strdupa(data);
3168         argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
3169
3170         /* check for a trailing flags argument */
3171         if ((argc > 1) && !strchr(argv[argc-1], '=')) {
3172                 argc--;
3173                 if (strchr(argv[argc], 'g'))
3174                         global = 1;
3175         }
3176
3177         for (x = 0; x < argc; x++) {
3178                 name = argv[x];
3179                 if ((value = strchr(name, '='))) {
3180                         *value++ = '\0';
3181                         pbx_builtin_setvar_helper((global) ? NULL : chan, name, value);
3182                 } else
3183                         ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name);
3184         }
3185
3186         return(0);
3187 }
3188
3189 int localized_pbx_builtin_setvar(struct ast_channel *chan, const void *data);
3190
3191 int localized_pbx_builtin_setvar(struct ast_channel *chan, const void *data)
3192 {
3193         return pbx_builtin_setvar(chan, data);
3194 }
3195
3196
3197 /*! \brief Helper for get_range.
3198  * return the index of the matching entry, starting from 1.
3199  * If names is not supplied, try numeric values.
3200  */
3201 static int lookup_name(const char *s, char *const names[], int max)
3202 {
3203         int i;
3204
3205         if (names && *s > '9') {
3206                 for (i = 0; names[i]; i++) {
3207                         if (!strcasecmp(s, names[i])) {
3208                                 return i;
3209                         }
3210                 }
3211         }
3212
3213         /* Allow months and weekdays to be specified as numbers, as well */
3214         if (sscanf(s, "%2d", &i) == 1 && i >= 1 && i <= max) {
3215                 /* What the array offset would have been: "1" would be at offset 0 */
3216                 return i - 1;
3217         }
3218         return -1; /* error return */
3219 }
3220
3221 /*! \brief helper function to return a range up to max (7, 12, 31 respectively).
3222  * names, if supplied, is an array of names that should be mapped to numbers.
3223  */
3224 static unsigned get_range(char *src, int max, char *const names[], const char *msg)
3225 {
3226         int start, end; /* start and ending position */
3227         unsigned int mask = 0;
3228         char *part;
3229
3230         /* Check for whole range */
3231         if (ast_strlen_zero(src) || !strcmp(src, "*")) {
3232                 return (1 << max) - 1;
3233         }
3234
3235         while ((part = strsep(&src, "&"))) {
3236                 /* Get start and ending position */
3237                 char *endpart = strchr(part, '-');
3238                 if (endpart) {
3239                         *endpart++ = '\0';
3240                 }
3241                 /* Find the start */
3242                 if ((start = lookup_name(part, names, max)) < 0) {
3243                         ast_log(LOG_WARNING, "Invalid %s '%s', skipping element\n", msg, part);
3244                         continue;
3245                 }
3246                 if (endpart) { /* find end of range */
3247                         if ((end = lookup_name(endpart, names, max)) < 0) {
3248                                 ast_log(LOG_WARNING, "Invalid end %s '%s', skipping element\n", msg, endpart);
3249                                 continue;
3250                         }
3251                 } else {
3252                         end = start;
3253                 }
3254                 /* Fill the mask. Remember that ranges are cyclic */
3255                 mask |= (1 << end);   /* initialize with last element */
3256                 while (start != end) {
3257                         if (start >= max) {
3258                                 start = 0;
3259                         }
3260                         mask |= (1 << start);
3261                         start++;
3262                 }
3263         }
3264         return mask;
3265 }
3266
3267 /*! \brief store a bitmask of valid times, one bit each 2 minute */
3268 static void get_timerange(struct ast_timing *i, char *times)
3269 {
3270         char *endpart, *part;
3271         int x;
3272         int st_h, st_m;
3273         int endh, endm;
3274         int minute_start, minute_end;
3275
3276         /* start disabling all times, fill the fields with 0's, as they may contain garbage */
3277         memset(i->minmask, 0, sizeof(i->minmask));
3278
3279         /* 1-minute per bit */
3280         /* Star is all times */
3281         if (ast_strlen_zero(times) || !strcmp(times, "*")) {
3282                 /* 48, because each hour takes 2 integers; 30 bits each */
3283                 for (x = 0; x < 48; x++) {
3284                         i->minmask[x] = 0x3fffffff; /* 30 bits */
3285                 }
3286                 return;
3287         }
3288         /* Otherwise expect a range */
3289         while ((part = strsep(&times, "&"))) {
3290                 if (!(endpart = strchr(part, '-'))) {
3291                         if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
3292                                 ast_log(LOG_WARNING, "%s isn't a valid time.\n", part);
3293                                 continue;
3294                         }
3295                         i->minmask[st_h * 2 + (st_m >= 30 ? 1 : 0)] |= (1 << (st_m % 30));
3296                         continue;
3297                 }
3298                 *endpart++ = '\0';
3299                 /* why skip non digits? Mostly to skip spaces */
3300                 while (*endpart && !isdigit(*endpart)) {
3301                         endpart++;
3302                 }
3303                 if (!*endpart) {
3304                         ast_log(LOG_WARNING, "Invalid time range starting with '%s-'.\n", part);
3305                         continue;
3306                 }
3307                 if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
3308                         ast_log(LOG_WARNING, "'%s' isn't a valid start time.\n", part);
3309                         continue;
3310                 }
3311                 if (sscanf(endpart, "%2d:%2d", &endh, &endm) != 2 || endh < 0 || endh > 23 || endm < 0 || endm > 59) {
3312                         ast_log(LOG_WARNING, "'%s' isn't a valid end time.\n", endpart);
3313                         continue;
3314                 }
3315                 minute_start = st_h * 60 + st_m;
3316                 minute_end = endh * 60 + endm;
3317                 /* Go through the time and enable each appropriate bit */
3318                 for (x = minute_start; x != minute_end; x = (x + 1) % (24 * 60)) {
3319                         i->minmask[x / 30] |= (1 << (x % 30));
3320                 }
3321                 /* Do the last one */
3322                 i->minmask[x / 30] |= (1 << (x % 30));
3323         }
3324         /* All done */
3325         return;
3326 }
3327
3328 static void null_datad(void *foo)
3329 {
3330 }
3331
3332 /*! \brief Find realtime engine for realtime family */
3333 static struct ast_config_engine *find_engine(const char *family, char *database, int dbsiz, char *table, int tabsiz) 
3334 {
3335         struct ast_config_engine *eng, *ret = NULL;
3336         struct ast_config_map *map;
3337
3338
3339         for (map = config_maps; map; map = map->next) {
3340                 if (!strcasecmp(family, map->name)) {
3341                         if (database)
3342                                 ast_copy_string(database, map->database, dbsiz);
3343                         if (table)
3344                                 ast_copy_string(table, map->table ? map->table : family, tabsiz);
3345                         break;
3346                 }
3347         }
3348
3349         /* Check if the required driver (engine) exist */
3350         if (map) {
3351                 for (eng = config_engine_list; !ret && eng; eng = eng->next) {
3352                         if (!strcasecmp(eng->name, map->driver))
3353                                 ret = eng;
3354                 }
3355         }
3356         
3357         
3358         /* if we found a mapping, but the engine is not available, then issue a warning */
3359         if (map && !ret)
3360                 ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
3361         
3362         return ret;
3363 }
3364
3365 struct ast_category *ast_config_get_current_category(const struct ast_config *cfg);
3366
3367 struct ast_category *ast_config_get_current_category(const struct ast_config *cfg)
3368 {
3369         return cfg->current;
3370 }
3371
3372 static struct ast_category *ast_category_new(const char *name, const char *in_file, int lineno);
3373
3374 static struct ast_category *ast_category_new(const char *name, const char *in_file, int lineno)
3375 {
3376         struct ast_category *category;
3377
3378         if ((category = ast_calloc(1, sizeof(*category))))
3379                 ast_copy_string(category->name, name, sizeof(category->name));
3380         category->file = strdup(in_file);
3381         category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
3382         return category;
3383 }
3384
3385 struct ast_category *localized_category_get(const struct ast_config *config, const char *category_name);
3386
3387 struct ast_category *localized_category_get(const struct ast_config *config, const char *category_name)
3388 {
3389         return category_get(config, category_name, 0);
3390 }
3391
3392 static void move_variables(struct ast_category *old, struct ast_category *new)
3393 {
3394         struct ast_variable *var = old->root;
3395         old->root = NULL;
3396 #if 1
3397         /* we can just move the entire list in a single op */
3398         ast_variable_append(new, var);
3399 #else
3400         while (var) {
3401                 struct ast_variable *next = var->next;
3402                 var->next = NULL;
3403                 ast_variable_append(new, var);
3404                 var = next;
3405         }
3406 #endif
3407 }
3408
3409 static void inherit_category(struct ast_category *new, const struct ast_category *base)
3410 {
3411         struct ast_variable *var;
3412
3413         for (var = base->root; var; var = var->next)
3414                 ast_variable_append(new, variable_clone(var));
3415 }
3416
3417 static void ast_category_append(struct ast_config *config, struct ast_category *category);
3418
3419 static void ast_category_append(struct ast_config *config, struct ast_category *category)
3420 {
3421         if (config->last)
3422                 config->last->next = category;
3423         else
3424                 config->root = category;
3425         config->last = category;
3426         config->current = category;
3427 }
3428
3429 static void ast_category_destroy(struct ast_category *cat);
3430
3431 static void ast_category_destroy(struct ast_category *cat)
3432 {
3433         ast_variables_destroy(cat->root);
3434         if (cat->file)
3435                 free(cat->file);
3436         
3437         free(cat);
3438 }
3439
3440 static struct ast_config_engine text_file_engine = {
3441         .name = "text",
3442         .load_func = config_text_file_load,
3443 };
3444
3445
3446 static struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_incl_file);
3447
3448 static struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_incl_file)
3449 {
3450         char db[256];
3451         char table[256];
3452         struct ast_config_engine *loader = &text_file_engine;
3453         struct ast_config *result; 
3454
3455         if (cfg->include_level == cfg->max_include_level) {
3456                 ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
3457                 return NULL;
3458         }
3459
3460         cfg->include_level++;
3461         /*  silence is golden!
3462                 ast_log(LOG_WARNING, "internal loading file %s level=%d\n", filename, cfg->include_level);
3463         */
3464
3465         if (strcmp(filename, extconfig_conf) && strcmp(filename, "asterisk.conf") && config_engine_list) {
3466                 struct ast_config_engine *eng;
3467
3468                 eng = find_engine(filename, db, sizeof(db), table, sizeof(table));
3469
3470
3471                 if (eng && eng->load_func) {
3472                         loader = eng;
3473                 } else {
3474                         eng = find_engine("global", db, sizeof(db), table, sizeof(table));
3475                         if (eng && eng->load_func)
3476                                 loader = eng;
3477                 }
3478         }
3479
3480         result = loader->load_func(db, table, filename, cfg, withcomments, suggested_incl_file);
3481         /* silence is golden 
3482            ast_log(LOG_WARNING, "finished internal loading file %s level=%d\n", filename, cfg->include_level);
3483         */
3484
3485         if (result)
3486                 result->include_level--;
3487
3488         return result;
3489 }
3490
3491
3492 static int process_text_line(struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, int withcomments, const char *suggested_include_file)
3493 {
3494         char *c;
3495         char *cur = buf;
3496         struct ast_variable *v;
3497         char cmd[512], exec_file[512];
3498         int object, do_exec, do_include;
3499
3500         /* Actually parse the entry */
3501         if (cur[0] == '[') {
3502                 struct ast_category *newcat = NULL;
3503                 char *catname;
3504
3505                 /* A category header */
3506                 c = strchr(cur, ']');
3507                 if (!c) {
3508                         ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
3509                         return -1;
3510                 }
3511                 *c++ = '\0';
3512                 cur++;
3513                 if (*c++ != '(')
3514                         c = NULL;
3515                 catname = cur;
3516                 if (!(*cat = newcat = ast_category_new(catname, ast_strlen_zero(suggested_include_file)?configfile:suggested_include_file, lineno))) {
3517                         return -1;
3518                 }
3519                 (*cat)->lineno = lineno;
3520         
3521                 /* add comments */
3522                 if (withcomments && comment_buffer && comment_buffer[0] ) {
3523                         newcat->precomments = ALLOC_COMMENT(comment_buffer);
3524                 }
3525                 if (withcomments && lline_buffer && lline_buffer[0] ) {
3526                         newcat->sameline = ALLOC_COMMENT(lline_buffer);
3527                 }
3528                 if( withcomments )
3529                         CB_RESET();
3530                 
3531                 /* If there are options or categories to inherit from, process them now */
3532                 if (c) {
3533                         if (!(cur = strchr(c, ')'))) {
3534                                 ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
3535                                 return -1;
3536                         }
3537                         *cur = '\0';
3538                         while ((cur = strsep(&c, ","))) {
3539                                 if (!strcasecmp(cur, "!")) {
3540                                         (*cat)->ignored = 1;
3541                                 } else if (!strcasecmp(cur, "+")) {
3542                                         *cat = category_get(cfg, catname, 1);
3543                                         if (!*cat) {
3544                                                 ast_config_destroy(cfg);
3545                                                 if (newcat)
3546                                                         ast_category_destroy(newcat);
3547                                                 ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
3548                                                 return -1;
3549                                         }
3550                                         if (newcat) {
3551                                                 move_variables(newcat, *cat);
3552                                                 ast_category_destroy(newcat);
3553                                                 newcat = NULL;
3554                                         }
3555                                 } else {
3556                                         struct ast_category *base;
3557                                 
3558                                         base = category_get(cfg, cur, 1);
3559                                         if (!base) {
3560                                                 ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
3561                                                 return -1;
3562                                         }
3563                                         inherit_category(*cat, base);
3564                                 }
3565                         }
3566                 }
3567                 if (newcat)
3568                         ast_category_append(cfg, *cat);
3569         } else if (cur[0] == '#') {
3570                 /* A directive */
3571                 cur++;
3572                 c = cur;
3573                 while(*c && (*c > 32)) c++;
3574                 if (*c) {
3575                         *c = '\0';
3576                         /* Find real argument */
3577                         c = ast_skip_blanks(c + 1);
3578                         if (!*c)
3579                                 c = NULL;
3580                 } else 
3581                         c = NULL;
3582                 do_include = !strcasecmp(cur, "include");
3583                 if(!do_include)
3584                         do_exec = !strcasecmp(cur, "exec");
3585                 else
3586                         do_exec = 0;
3587                 if (do_exec && !ast_opt_exec_includes) {
3588                         ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
3589                         do_exec = 0;
3590                 }
3591                 if (do_include || do_exec) {
3592                         if (c) {
3593                                 char *cur2;
3594                                 char real_inclusion_name[256];
3595                                 struct ast_config_include *inclu;
3596                 
3597                                 /* Strip off leading and trailing "'s and <>'s */
3598                                 while((*c == '<') || (*c == '>') || (*c == '\"')) c++;
3599                                 /* Get rid of leading mess */
3600                                 cur = c;
3601                                 cur2 = cur;
3602                                 while (!ast_strlen_zero(cur)) {
3603                                         c = cur + strlen(cur) - 1;
3604                                         if ((*c == '>') || (*c == '<') || (*c == '\"'))
3605                                                 *c = '\0';
3606                                         else
3607                                                 break;
3608                                 }
3609                                 /* #exec </path/to/executable>
3610                                    We create a tmp file, then we #include it, then we delete it. */
3611                                 if (do_exec) { 
3612                                         snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d.%ld", (int)time(NULL), (long)pthread_self());
3613                                         snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file);
3614                                         ast_safe_system(cmd);
3615                                         cur = exec_file;
3616                                 } else
3617                                         exec_file[0] = '\0';
3618                                 /* A #include */
3619                                 /* ast_log(LOG_WARNING, "Reading in included file %s withcomments=%d\n", cur, withcomments); */
3620                                 
3621                                 /* record this inclusion */
3622                                 inclu = ast_include_new(cfg, configfile, cur, do_exec, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name));
3623                                 
3624                                 do_include = ast_config_internal_load(cur, cfg, withcomments, real_inclusion_name) ? 1 : 0;
3625                                 if(!ast_strlen_zero(exec_file))
3626                                         unlink(exec_file);
3627                                 if(!do_include)
3628                                         return 0;
3629                                 /* ast_log(LOG_WARNING, "Done reading in included file %s withcomments=%d\n", cur, withcomments); */
3630                                 
3631                         } else {
3632                                 ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n", 
3633                                                 do_exec ? "exec" : "include",
3634                                                 do_exec ? "/path/to/executable" : "filename",
3635                                                 lineno,
3636                                                 configfile);
3637                         }
3638                 }
3639                 else 
3640                         ast_log(LOG_WARNING, "Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile);
3641         } else {
3642                 /* Just a line (variable = value) */
3643                 if (!*cat) {
3644                         ast_log(LOG_WARNING,
3645                                 "parse error: No category context for line %d of %s\n", lineno, configfile);
3646                         return -1;
3647                 }
3648                 c = strchr(cur, '=');
3649                 if (c) {
3650                         *c = 0;
3651                         c++;
3652                         /* Ignore > in => */
3653                         if (*c== '>') {
3654                                 object = 1;
3655                                 c++;
3656                         } else
3657                                 object = 0;
3658                         if ((v = ast_variable_new(ast_strip(cur), ast_strip(c), configfile))) {
3659                                 v->lineno = lineno;
3660                                 v->object = object;
3661                                 /* Put and reset comments */
3662                                 v->blanklines = 0;
3663                                 ast_variable_append(*cat, v);
3664                                 /* add comments */
3665                                 if (withcomments && comment_buffer && comment_buffer[0] ) {
3666                                         v->precomments = ALLOC_COMMENT(comment_buffer);
3667                                 }
3668                                 if (withcomments && lline_buffer && lline_buffer[0] ) {
3669                                         v->sameline = ALLOC_COMMENT(lline_buffer);
3670                                 }
3671                                 if( withcomments )
3672                                         CB_RESET();
3673                                 
3674                         } else {
3675                                 return -1;
3676                         }
3677                 } else {
3678                         ast_log(LOG_WARNING, "EXTENSIONS.CONF: No '=' (equal sign) in line %d of %s\n", lineno, configfile);
3679                 }
3680         }
3681         return 0;
3682 }
3683
3684 static int use_local_dir = 1;
3685
3686 void localized_use_local_dir(void);
3687 void localized_use_conf_dir(void);
3688
3689 void localized_use_local_dir(void)
3690 {
3691         use_local_dir = 1;
3692 }
3693
3694 void localized_use_conf_dir(void)
3695 {
3696         use_local_dir = 0;
3697 }
3698
3699
3700 static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_include_file)
3701 {
3702         char fn[256];
3703         char buf[8192];
3704         char *new_buf, *comment_p, *process_buf;
3705         FILE *f;
3706         int lineno=0;
3707         int comment = 0, nest[MAX_NESTED_COMMENTS];
3708         struct ast_category *cat = NULL;
3709         int count = 0;
3710         struct stat statbuf;
3711         
3712         cat = ast_config_get_current_category(cfg);
3713
3714         if (filename[0] == '/') {
3715                 ast_copy_string(fn, filename, sizeof(fn));
3716         } else {
3717                 if (use_local_dir)
3718                         snprintf(fn, sizeof(fn), "./%s", filename);
3719                 else
3720                         snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
3721         }
3722
3723         if (withcomments && cfg && cfg->include_level < 2 ) {
3724                 CB_INIT();
3725         }
3726         
3727 #ifdef AST_INCLUDE_GLOB
3728         {
3729                 int glob_ret;
3730                 glob_t globbuf;
3731
3732                 globbuf.gl_offs = 0;    /* initialize it to silence gcc */
3733 #ifdef SOLARIS
3734                 glob_ret = glob(fn, GLOB_NOCHECK, NULL, &globbuf);
3735 #else
3736                 glob_ret = glob(fn, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf);
3737 #endif
3738                 if (glob_ret == GLOB_NOSPACE)
3739                         ast_log(LOG_WARNING,
3740                                 "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
3741                 else if (glob_ret  == GLOB_ABORTED)
3742                         ast_log(LOG_WARNING,
3743                                 "Glob Expansion of pattern '%s' failed: Read error\n", fn);
3744                 else  {
3745                         /* loop over expanded files */
3746                         int i;
3747                         for (i=0; i<globbuf.gl_pathc; i++) {
3748                                 ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn));
3749 #endif
3750         do {
3751                 if (stat(fn, &statbuf))
3752                         continue;
3753
3754                 if (!S_ISREG(statbuf.st_mode)) {
3755                         ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
3756                         continue;
3757                 }
3758                 if (option_verbose > 1) {
3759                         ast_verbose(VERBOSE_PREFIX_2 "Parsing '%s': ", fn);
3760                         fflush(stdout);
3761                 }
3762                 if (!(f = fopen(fn, "r"))) {
3763                         if (option_debug)
3764                                 ast_log(LOG_DEBUG, "No file to parse: %s\n", fn);
3765                         if (option_verbose > 1)
3766                                 ast_verbose( "Not found (%s)\n", strerror(errno));
3767                         continue;
3768                 }
3769                 count++;
3770                 if (option_debug)
3771                         ast_log(LOG_DEBUG, "Parsing %s\n", fn);
3772                 if (option_verbose > 1)
3773                         ast_verbose("Found\n");
3774                 while(!feof(f)) {
3775                         lineno++;
3776                         if (fgets(buf, sizeof(buf), f)) {
3777