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