Merge "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         /*! Always fork, even if verbose or debug settings are non-zero */
1355         AST_OPT_FLAG_ALWAYS_FORK = (1 << 21),
1356         /*! Disable log/verbose output to remote consoles */
1357         AST_OPT_FLAG_MUTE = (1 << 22),
1358         /*! There is a per-file debug setting */
1359         AST_OPT_FLAG_DEBUG_FILE = (1 << 23),
1360         /*! Terminal colors should be adjusted for a light-colored background */
1361         AST_OPT_FLAG_LIGHT_BACKGROUND = (1 << 25),
1362         /*! Force black background */
1363         AST_OPT_FLAG_FORCE_BLACK_BACKGROUND = (1 << 27),
1364 };
1365
1366 /* options.h declares ast_options extern; I need it static? */
1367 #define AST_CACHE_DIR_LEN       512
1368 #define AST_FILENAME_MAX        80
1369
1370 /*! These are the options that set by default when Asterisk starts */
1371 #define AST_DEFAULT_OPTIONS AST_OPT_FLAG_TRANSCODE_VIA_SLIN
1372
1373 struct ast_flags ast_options = { AST_DEFAULT_OPTIONS };
1374
1375 #define ast_opt_exec_includes           ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES)
1376 #define ast_opt_no_fork                 ast_test_flag(&ast_options, AST_OPT_FLAG_NO_FORK)
1377 #define ast_opt_quiet                   ast_test_flag(&ast_options, AST_OPT_FLAG_QUIET)
1378 #define ast_opt_console                 ast_test_flag(&ast_options, AST_OPT_FLAG_CONSOLE)
1379 #define ast_opt_high_priority           ast_test_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY)
1380 #define ast_opt_init_keys               ast_test_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS)
1381 #define ast_opt_remote                  ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)
1382 #define ast_opt_exec                    ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC)
1383 #define ast_opt_no_color                ast_test_flag(&ast_options, AST_OPT_FLAG_NO_COLOR)
1384 #define ast_fully_booted                ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)
1385 #define ast_opt_transcode_via_slin      ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN)
1386 #define ast_opt_priority_jumping        ast_test_flag(&ast_options, AST_OPT_FLAG_PRIORITY_JUMPING)
1387 #define ast_opt_dump_core               ast_test_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE)
1388 #define ast_opt_cache_record_files      ast_test_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES)
1389 #define ast_opt_timestamp               ast_test_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP)
1390 #define ast_opt_override_config         ast_test_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG)
1391 #define ast_opt_reconnect               ast_test_flag(&ast_options, AST_OPT_FLAG_RECONNECT)
1392 #define ast_opt_transmit_silence        ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE)
1393 #define ast_opt_dont_warn               ast_test_flag(&ast_options, AST_OPT_FLAG_DONT_WARN)
1394 #define ast_opt_always_fork             ast_test_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK)
1395 #define ast_opt_mute                    ast_test_flag(&ast_options, AST_OPT_FLAG_MUTE)
1396
1397 extern int option_verbose;
1398 extern int option_debug;                /*!< Debugging */
1399 extern int ast_option_maxcalls;         /*!< Maximum number of simultaneous channels */
1400 extern double ast_option_maxload;
1401 extern char ast_defaultlanguage[];
1402
1403 extern pid_t ast_mainpid;
1404
1405 extern char record_cache_dir[AST_CACHE_DIR_LEN];
1406 extern char debug_filename[AST_FILENAME_MAX];
1407
1408 extern int ast_language_is_prefix;
1409
1410
1411
1412 /* linkedlists.h */
1413
1414 /*!
1415   \brief Write locks a list.
1416   \param head This is a pointer to the list head structure
1417
1418   This macro attempts to place an exclusive write lock in the
1419   list head structure pointed to by head.
1420   Returns non-zero on success, 0 on failure
1421 */
1422 #define AST_RWLIST_WRLOCK(head)                                         \
1423         ast_rwlock_wrlock(&(head)->lock)
1424
1425 /*!
1426   \brief Read locks a list.
1427   \param head This is a pointer to the list head structure
1428
1429   This macro attempts to place a read lock in the
1430   list head structure pointed to by head.
1431   Returns non-zero on success, 0 on failure
1432 */
1433 #define AST_RWLIST_RDLOCK(head)                                         \
1434         ast_rwlock_rdlock(&(head)->lock)
1435
1436 /*!
1437   \brief Attempts to unlock a read/write based list.
1438   \param head This is a pointer to the list head structure
1439
1440   This macro attempts to remove a read or write lock from the
1441   list head structure pointed to by head. If the list
1442   was not locked by this thread, this macro has no effect.
1443 */
1444 #define AST_RWLIST_UNLOCK(head)                                         \
1445         ast_rwlock_unlock(&(head)->lock)
1446
1447 /*!
1448   \brief Defines a structure to be used to hold a list of specified type.
1449   \param name This will be the name of the defined structure.
1450   \param type This is the type of each list entry.
1451
1452   This macro creates a structure definition that can be used
1453   to hold a list of the entries of type \a type. It does not actually
1454   declare (allocate) a structure; to do that, either follow this
1455   macro with the desired name of the instance you wish to declare,
1456   or use the specified \a name to declare instances elsewhere.
1457
1458   Example usage:
1459   \code
1460   static AST_LIST_HEAD(entry_list, entry) entries;
1461   \endcode
1462
1463   This would define \c struct \c entry_list, and declare an instance of it named
1464   \a entries, all intended to hold a list of type \c struct \c entry.
1465 */
1466 #define AST_LIST_HEAD(name, type)                                       \
1467 struct name {                                                           \
1468         struct type *first;                                             \
1469         struct type *last;                                              \
1470         ast_mutex_t lock;                                               \
1471 }
1472
1473 /*!
1474   \brief Defines a structure to be used to hold a read/write list of specified type.
1475   \param name This will be the name of the defined structure.
1476   \param type This is the type of each list entry.
1477
1478   This macro creates a structure definition that can be used
1479   to hold a list of the entries of type \a type. It does not actually
1480   declare (allocate) a structure; to do that, either follow this
1481   macro with the desired name of the instance you wish to declare,
1482   or use the specified \a name to declare instances elsewhere.
1483
1484   Example usage:
1485   \code
1486   static AST_RWLIST_HEAD(entry_list, entry) entries;
1487   \endcode
1488
1489   This would define \c struct \c entry_list, and declare an instance of it named
1490   \a entries, all intended to hold a list of type \c struct \c entry.
1491 */
1492 #define AST_RWLIST_HEAD(name, type)                                     \
1493 struct name {                                                           \
1494         struct type *first;                                             \
1495         struct type *last;                                              \
1496         ast_rwlock_t lock;                                              \
1497 }
1498
1499 /*!
1500   \brief Defines a structure to be used to hold a list of specified type (with no lock).
1501   \param name This will be the name of the defined structure.
1502   \param type This is the type of each list entry.
1503
1504   This macro creates a structure definition that can be used
1505   to hold a list of the entries of type \a type. It does not actually
1506   declare (allocate) a structure; to do that, either follow this
1507   macro with the desired name of the instance you wish to declare,
1508   or use the specified \a name to declare instances elsewhere.
1509
1510   Example usage:
1511   \code
1512   static AST_LIST_HEAD_NOLOCK(entry_list, entry) entries;
1513   \endcode
1514
1515   This would define \c struct \c entry_list, and declare an instance of it named
1516   \a entries, all intended to hold a list of type \c struct \c entry.
1517 */
1518 #define AST_LIST_HEAD_NOLOCK(name, type)                                \
1519 struct name {                                                           \
1520         struct type *first;                                             \
1521         struct type *last;                                              \
1522 }
1523
1524 /*!
1525   \brief Defines initial values for a declaration of AST_LIST_HEAD
1526 */
1527 #define AST_LIST_HEAD_INIT_VALUE        {               \
1528         .first = NULL,                                  \
1529         .last = NULL,                                   \
1530         .lock = AST_MUTEX_INIT_VALUE,                   \
1531         }
1532
1533 /*!
1534   \brief Defines initial values for a declaration of AST_RWLIST_HEAD
1535 */
1536 #define AST_RWLIST_HEAD_INIT_VALUE      {               \
1537         .first = NULL,                                  \
1538         .last = NULL,                                   \
1539         .lock = AST_RWLOCK_INIT_VALUE,                  \
1540         }
1541
1542 /*!
1543   \brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK
1544 */
1545 #define AST_LIST_HEAD_NOLOCK_INIT_VALUE {       \
1546         .first = NULL,                                  \
1547         .last = NULL,                                   \
1548         }
1549
1550 /*!
1551   \brief Defines a structure to be used to hold a list of specified type, statically initialized.
1552   \param name This will be the name of the defined structure.
1553   \param type This is the type of each list entry.
1554
1555   This macro creates a structure definition that can be used
1556   to hold a list of the entries of type \a type, and allocates an instance
1557   of it, initialized to be empty.
1558
1559   Example usage:
1560   \code
1561   static AST_LIST_HEAD_STATIC(entry_list, entry);
1562   \endcode
1563
1564   This would define \c struct \c entry_list, intended to hold a list of
1565   type \c struct \c entry.
1566 */
1567 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
1568 #define AST_LIST_HEAD_STATIC(name, type)                                \
1569 struct name {                                                           \
1570         struct type *first;                                             \
1571         struct type *last;                                              \
1572         ast_mutex_t lock;                                               \
1573 } name;                                                                 \
1574 static void  __attribute__((constructor)) init_##name(void)             \
1575 {                                                                       \
1576         AST_LIST_HEAD_INIT(&name);                                      \
1577 }                                                                       \
1578 static void  __attribute__((destructor)) fini_##name(void)              \
1579 {                                                                       \
1580         AST_LIST_HEAD_DESTROY(&name);                                   \
1581 }                                                                       \
1582 struct __dummy_##name
1583 #else
1584 #define AST_LIST_HEAD_STATIC(name, type)                                \
1585 struct name {                                                           \
1586         struct type *first;                                             \
1587         struct type *last;                                              \
1588         ast_mutex_t lock;                                               \
1589 } name = AST_LIST_HEAD_INIT_VALUE
1590 #endif
1591
1592 /*!
1593   \brief Defines a structure to be used to hold a read/write list of specified type, statically initialized.
1594   \param name This will be the name of the defined structure.
1595   \param type This is the type of each list entry.
1596
1597   This macro creates a structure definition that can be used
1598   to hold a list of the entries of type \a type, and allocates an instance
1599   of it, initialized to be empty.
1600
1601   Example usage:
1602   \code
1603   static AST_RWLIST_HEAD_STATIC(entry_list, entry);
1604   \endcode
1605
1606   This would define \c struct \c entry_list, intended to hold a list of
1607   type \c struct \c entry.
1608 */
1609 #ifndef AST_RWLOCK_INIT_VALUE
1610 #define AST_RWLIST_HEAD_STATIC(name, type)                              \
1611 struct name {                                                           \
1612         struct type *first;                                             \
1613         struct type *last;                                              \
1614         ast_rwlock_t lock;                                              \
1615 } name;                                                                 \
1616 static void  __attribute__((constructor)) init_##name(void)            \
1617 {                                                                       \
1618         AST_RWLIST_HEAD_INIT(&name);                                    \
1619 }                                                                       \
1620 static void  __attribute__((destructor)) fini_##name(void)             \
1621 {                                                                       \
1622         AST_RWLIST_HEAD_DESTROY(&name);                                 \
1623 }                                                                       \
1624 struct __dummy_##name
1625 #else
1626 #define AST_RWLIST_HEAD_STATIC(name, type)                              \
1627 struct name {                                                           \
1628         struct type *first;                                             \
1629         struct type *last;                                              \
1630         ast_rwlock_t lock;                                              \
1631 } name = AST_RWLIST_HEAD_INIT_VALUE
1632 #endif
1633
1634 /*!
1635   \brief Defines a structure to be used to hold a list of specified type, statically initialized.
1636
1637   This is the same as AST_LIST_HEAD_STATIC, except without the lock included.
1638 */
1639 #define AST_LIST_HEAD_NOLOCK_STATIC(name, type)                         \
1640 struct name {                                                           \
1641         struct type *first;                                             \
1642         struct type *last;                                              \
1643 } name = AST_LIST_HEAD_NOLOCK_INIT_VALUE
1644
1645 /*!
1646   \brief Initializes a list head structure with a specified first entry.
1647   \param head This is a pointer to the list head structure
1648   \param entry pointer to the list entry that will become the head of the list
1649
1650   This macro initializes a list head structure by setting the head
1651   entry to the supplied value and recreating the embedded lock.
1652 */
1653 #define AST_LIST_HEAD_SET(head, entry) do {                             \
1654         (head)->first = (entry);                                        \
1655         (head)->last = (entry);                                         \
1656         ast_mutex_init(&(head)->lock);                                  \
1657 } while (0)
1658
1659 /*!
1660   \brief Initializes an rwlist head structure with a specified first entry.
1661   \param head This is a pointer to the list head structure
1662   \param entry pointer to the list entry that will become the head of the list
1663
1664   This macro initializes a list head structure by setting the head
1665   entry to the supplied value and recreating the embedded lock.
1666 */
1667 #define AST_RWLIST_HEAD_SET(head, entry) do {                           \
1668         (head)->first = (entry);                                        \
1669         (head)->last = (entry);                                         \
1670         ast_rwlock_init(&(head)->lock);                                 \
1671 } while (0)
1672
1673 /*!
1674   \brief Initializes a list head structure with a specified first entry.
1675   \param head This is a pointer to the list head structure
1676   \param entry pointer to the list entry that will become the head of the list
1677
1678   This macro initializes a list head structure by setting the head
1679   entry to the supplied value.
1680 */
1681 #define AST_LIST_HEAD_SET_NOLOCK(head, entry) do {                      \
1682         (head)->first = (entry);                                        \
1683         (head)->last = (entry);                                         \
1684 } while (0)
1685
1686 /*!
1687   \brief Declare a forward link structure inside a list entry.
1688   \param type This is the type of each list entry.
1689
1690   This macro declares a structure to be used to link list entries together.
1691   It must be used inside the definition of the structure named in
1692   \a type, as follows:
1693
1694   \code
1695   struct list_entry {
1696         ...
1697         AST_LIST_ENTRY(list_entry) list;
1698   }
1699   \endcode
1700
1701   The field name \a list here is arbitrary, and can be anything you wish.
1702 */
1703 #define AST_LIST_ENTRY(type)                                            \
1704 struct {                                                                \
1705         struct type *next;                                              \
1706 }
1707
1708 #define AST_RWLIST_ENTRY AST_LIST_ENTRY
1709
1710 /*!
1711   \brief Returns the first entry contained in a list.
1712   \param head This is a pointer to the list head structure
1713  */
1714 #define AST_LIST_FIRST(head)    ((head)->first)
1715
1716 #define AST_RWLIST_FIRST AST_LIST_FIRST
1717
1718 /*!
1719   \brief Returns the last entry contained in a list.
1720   \param head This is a pointer to the list head structure
1721  */
1722 #define AST_LIST_LAST(head)     ((head)->last)
1723
1724 #define AST_RWLIST_LAST AST_LIST_LAST
1725
1726 /*!
1727   \brief Returns the next entry in the list after the given entry.
1728   \param elm This is a pointer to the current entry.
1729   \param field This is the name of the field (declared using AST_LIST_ENTRY())
1730   used to link entries of this list together.
1731 */
1732 #define AST_LIST_NEXT(elm, field)       ((elm)->field.next)
1733
1734 #define AST_RWLIST_NEXT AST_LIST_NEXT
1735
1736 /*!
1737   \brief Checks whether the specified list contains any entries.
1738   \param head This is a pointer to the list head structure
1739
1740   Returns non-zero if the list has entries, zero if not.
1741  */
1742 #define AST_LIST_EMPTY(head)    (AST_LIST_FIRST(head) == NULL)
1743
1744 #define AST_RWLIST_EMPTY AST_LIST_EMPTY
1745
1746 /*!
1747   \brief Loops over (traverses) the entries in a list.
1748   \param head This is a pointer to the list head structure
1749   \param var This is the name of the variable that will hold a pointer to the
1750   current list entry on each iteration. It must be declared before calling
1751   this macro.
1752   \param field This is the name of the field (declared using AST_LIST_ENTRY())
1753   used to link entries of this list together.
1754
1755   This macro is use to loop over (traverse) the entries in a list. It uses a
1756   \a for loop, and supplies the enclosed code with a pointer to each list
1757   entry as it loops. It is typically used as follows:
1758   \code
1759   static AST_LIST_HEAD(entry_list, list_entry) entries;
1760   ...
1761   struct list_entry {
1762         ...
1763         AST_LIST_ENTRY(list_entry) list;
1764   }
1765   ...
1766   struct list_entry *current;
1767   ...
1768   AST_LIST_TRAVERSE(&entries, current, list) {
1769      (do something with current here)
1770   }
1771   \endcode
1772   \warning If you modify the forward-link pointer contained in the \a current entry while
1773   inside the loop, the behavior will be unpredictable. At a minimum, the following
1774   macros will modify the forward-link pointer, and should not be used inside
1775   AST_LIST_TRAVERSE() against the entry pointed to by the \a current pointer without
1776   careful consideration of their consequences:
1777   \li AST_LIST_NEXT() (when used as an lvalue)
1778   \li AST_LIST_INSERT_AFTER()
1779   \li AST_LIST_INSERT_HEAD()
1780   \li AST_LIST_INSERT_TAIL()
1781 */
1782 #define AST_LIST_TRAVERSE(head,var,field)                               \
1783         for((var) = (head)->first; (var); (var) = (var)->field.next)
1784
1785 #define AST_RWLIST_TRAVERSE AST_LIST_TRAVERSE
1786
1787 /*!
1788   \brief Loops safely over (traverses) the entries in a list.
1789   \param head This is a pointer to the list head structure
1790   \param var This is the name of the variable that will hold a pointer to the
1791   current list entry on each iteration. It must be declared before calling
1792   this macro.
1793   \param field This is the name of the field (declared using AST_LIST_ENTRY())
1794   used to link entries of this list together.
1795
1796   This macro is used to safely loop over (traverse) the entries in a list. It
1797   uses a \a for loop, and supplies the enclosed code with a pointer to each list
1798   entry as it loops. It is typically used as follows:
1799
1800   \code
1801   static AST_LIST_HEAD(entry_list, list_entry) entries;
1802   ...
1803   struct list_entry {
1804         ...
1805         AST_LIST_ENTRY(list_entry) list;
1806   }
1807   ...
1808   struct list_entry *current;
1809   ...
1810   AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
1811      (do something with current here)
1812   }
1813   AST_LIST_TRAVERSE_SAFE_END;
1814   \endcode
1815
1816   It differs from AST_LIST_TRAVERSE() in that the code inside the loop can modify
1817   (or even free, after calling AST_LIST_REMOVE_CURRENT()) the entry pointed to by
1818   the \a current pointer without affecting the loop traversal.
1819 */
1820 #define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) {                                \
1821         typeof((head)->first) __list_next;                                              \
1822         typeof((head)->first) __list_prev = NULL;                                       \
1823         typeof((head)->first) __new_prev = NULL;                                        \
1824         for ((var) = (head)->first, __new_prev = (var),                                 \
1825               __list_next = (var) ? (var)->field.next : NULL;                           \
1826              (var);                                                                     \
1827              __list_prev = __new_prev, (var) = __list_next,                             \
1828              __new_prev = (var),                                                        \
1829              __list_next = (var) ? (var)->field.next : NULL                             \
1830             )
1831
1832 #define AST_RWLIST_TRAVERSE_SAFE_BEGIN AST_LIST_TRAVERSE_SAFE_BEGIN
1833
1834 /*!
1835   \brief Removes the \a current entry from a list during a traversal.
1836   \param head This is a pointer to the list head structure
1837   \param field This is the name of the field (declared using AST_LIST_ENTRY())
1838   used to link entries of this list together.
1839
1840   \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
1841   block; it is used to unlink the current entry from the list without affecting
1842   the list traversal (and without having to re-traverse the list to modify the
1843   previous entry, if any).
1844  */
1845 #define AST_LIST_REMOVE_CURRENT(head, field)                                            \
1846         __new_prev->field.next = NULL;                                                  \
1847         __new_prev = __list_prev;                                                       \
1848         if (__list_prev)                                                                \
1849                 __list_prev->field.next = __list_next;                                  \
1850         else                                                                            \
1851                 (head)->first = __list_next;                                            \
1852         if (!__list_next)                                                               \
1853                 (head)->last = __list_prev;
1854
1855 #define AST_RWLIST_REMOVE_CURRENT AST_LIST_REMOVE_CURRENT
1856
1857 /*!
1858   \brief Inserts a list entry before the current entry during a traversal.
1859   \param head This is a pointer to the list head structure
1860   \param elm This is a pointer to the entry to be inserted.
1861   \param field This is the name of the field (declared using AST_LIST_ENTRY())
1862   used to link entries of this list together.
1863
1864   \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
1865   block.
1866  */
1867 #define AST_LIST_INSERT_BEFORE_CURRENT(head, elm, field) do {           \
1868         if (__list_prev) {                                              \
1869                 (elm)->field.next = __list_prev->field.next;            \
1870                 __list_prev->field.next = elm;                          \
1871         } else {                                                        \
1872                 (elm)->field.next = (head)->first;                      \
1873                 (head)->first = (elm);                                  \
1874         }                                                               \
1875         __new_prev = (elm);                                             \
1876 } while (0)
1877
1878 #define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT
1879
1880 /*!
1881   \brief Closes a safe loop traversal block.
1882  */
1883 #define AST_LIST_TRAVERSE_SAFE_END  }
1884
1885 #define AST_RWLIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END
1886
1887 /*!
1888   \brief Initializes a list head structure.
1889   \param head This is a pointer to the list head structure
1890
1891   This macro initializes a list head structure by setting the head
1892   entry to \a NULL (empty list) and recreating the embedded lock.
1893 */
1894 #define AST_LIST_HEAD_INIT(head) {                                      \
1895         (head)->first = NULL;                                           \
1896         (head)->last = NULL;                                            \
1897         ast_mutex_init(&(head)->lock);                                  \
1898 }
1899
1900 /*!
1901   \brief Initializes an rwlist head structure.
1902   \param head This is a pointer to the list head structure
1903
1904   This macro initializes a list head structure by setting the head
1905   entry to \a NULL (empty list) and recreating the embedded lock.
1906 */
1907 #define AST_RWLIST_HEAD_INIT(head) {                                    \
1908         (head)->first = NULL;                                           \
1909         (head)->last = NULL;                                            \
1910         ast_rwlock_init(&(head)->lock);                                 \
1911 }
1912
1913 /*!
1914   \brief Destroys an rwlist head structure.
1915   \param head This is a pointer to the list head structure
1916
1917   This macro destroys a list head structure by setting the head
1918   entry to \a NULL (empty list) and destroying the embedded lock.
1919   It does not free the structure from memory.
1920 */
1921 #define AST_RWLIST_HEAD_DESTROY(head) {                                 \
1922         (head)->first = NULL;                                           \
1923         (head)->last = NULL;                                            \
1924         ast_rwlock_destroy(&(head)->lock);                              \
1925 }
1926
1927 /*!
1928   \brief Initializes a list head structure.
1929   \param head This is a pointer to the list head structure
1930
1931   This macro initializes a list head structure by setting the head
1932   entry to \a NULL (empty list). There is no embedded lock handling
1933   with this macro.
1934 */
1935 #define AST_LIST_HEAD_INIT_NOLOCK(head) {                               \
1936         (head)->first = NULL;                                           \
1937         (head)->last = NULL;                                            \
1938 }
1939
1940 /*!
1941   \brief Inserts a list entry after a given entry.
1942   \param head This is a pointer to the list head structure
1943   \param listelm This is a pointer to the entry after which the new entry should
1944   be inserted.
1945   \param elm This is a pointer to the entry to be inserted.
1946   \param field This is the name of the field (declared using AST_LIST_ENTRY())
1947   used to link entries of this list together.
1948  */
1949 #define AST_LIST_INSERT_AFTER(head, listelm, elm, field) do {           \
1950         (elm)->field.next = (listelm)->field.next;                      \
1951         (listelm)->field.next = (elm);                                  \
1952         if ((head)->last == (listelm))                                  \
1953                 (head)->last = (elm);                                   \
1954 } while (0)
1955
1956 #define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER
1957
1958 /*!
1959   \brief Inserts a list entry at the head of a list.
1960   \param head This is a pointer to the list head structure
1961   \param elm This is a pointer to the entry to be inserted.
1962   \param field This is the name of the field (declared using AST_LIST_ENTRY())
1963   used to link entries of this list together.
1964  */
1965 #define AST_LIST_INSERT_HEAD(head, elm, field) do {                     \
1966                 (elm)->field.next = (head)->first;                      \
1967                 (head)->first = (elm);                                  \
1968                 if (!(head)->last)                                      \
1969                         (head)->last = (elm);                           \
1970 } while (0)
1971
1972 #define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD
1973
1974 /*!
1975   \brief Appends a list entry to the tail of a list.
1976   \param head This is a pointer to the list head structure
1977   \param elm This is a pointer to the entry to be appended.
1978   \param field This is the name of the field (declared using AST_LIST_ENTRY())
1979   used to link entries of this list together.
1980
1981   Note: The link field in the appended entry is \b not modified, so if it is
1982   actually the head of a list itself, the entire list will be appended
1983   temporarily (until the next AST_LIST_INSERT_TAIL is performed).
1984  */
1985 #define AST_LIST_INSERT_TAIL(head, elm, field) do {                     \
1986       if (!(head)->first) {                                             \
1987                 (head)->first = (elm);                                  \
1988                 (head)->last = (elm);                                   \
1989       } else {                                                          \
1990                 (head)->last->field.next = (elm);                       \
1991                 (head)->last = (elm);                                   \
1992       }                                                                 \
1993 } while (0)
1994
1995 #define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL
1996
1997 /*!
1998   \brief Appends a whole list to the tail of a list.
1999   \param head This is a pointer to the list head structure
2000   \param list This is a pointer to the list to be appended.
2001   \param field This is the name of the field (declared using AST_LIST_ENTRY())
2002   used to link entries of this list together.
2003  */
2004 #define AST_LIST_APPEND_LIST(head, list, field) do {                    \
2005       if (!(head)->first) {                                             \
2006                 (head)->first = (list)->first;                          \
2007                 (head)->last = (list)->last;                            \
2008       } else {                                                          \
2009                 (head)->last->field.next = (list)->first;               \
2010                 (head)->last = (list)->last;                            \
2011       }                                                                 \
2012 } while (0)
2013
2014 #define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST
2015
2016 /*!
2017   \brief Removes and returns the head entry from a list.
2018   \param head This is a pointer to the list head structure
2019   \param field This is the name of the field (declared using AST_LIST_ENTRY())
2020   used to link entries of this list together.
2021
2022   Removes the head entry from the list, and returns a pointer to it.
2023   This macro is safe to call on an empty list.
2024  */
2025 #define AST_LIST_REMOVE_HEAD(head, field) ({                            \
2026                 typeof((head)->first) cur = (head)->first;              \
2027                 if (cur) {                                              \
2028                         (head)->first = cur->field.next;                \
2029                         cur->field.next = NULL;                         \
2030                         if ((head)->last == cur)                        \
2031                                 (head)->last = NULL;                    \
2032                 }                                                       \
2033                 cur;                                                    \
2034         })
2035
2036 #define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD
2037
2038 /*!
2039   \brief Removes a specific entry from a list.
2040   \param head This is a pointer to the list head structure
2041   \param elm This is a pointer to the entry to be removed.
2042   \param field This is the name of the field (declared using AST_LIST_ENTRY())
2043   used to link entries of this list together.
2044   \warning The removed entry is \b not freed nor modified in any way.
2045  */
2046 #define AST_LIST_REMOVE(head, elm, field) do {                          \
2047         if ((head)->first == (elm)) {                                   \
2048                 (head)->first = (elm)->field.next;                      \
2049                 if ((head)->last == (elm))                      \
2050                         (head)->last = NULL;                    \
2051         } else {                                                                \
2052                 typeof(elm) curelm = (head)->first;                     \
2053                 while (curelm && (curelm->field.next != (elm)))                 \
2054                         curelm = curelm->field.next;                    \
2055                 if (curelm) { \
2056                         curelm->field.next = (elm)->field.next;                 \
2057                         if ((head)->last == (elm))                              \
2058                                 (head)->last = curelm;                          \
2059                 } \
2060         }                                                               \
2061         (elm)->field.next = NULL;                                       \
2062 } while (0)
2063
2064 #define AST_RWLIST_REMOVE AST_LIST_REMOVE
2065
2066 /* chanvars.h */
2067
2068 struct ast_var_t {
2069         AST_LIST_ENTRY(ast_var_t) entries;
2070         char *value;
2071         char name[0];
2072 };
2073
2074 AST_LIST_HEAD_NOLOCK(varshead, ast_var_t);
2075
2076 AST_RWLOCK_DEFINE_STATIC(globalslock);
2077 static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
2078
2079
2080 /* IN CONFLICT: struct ast_var_t *ast_var_assign(const char *name, const char *value); */
2081
2082 static struct ast_var_t *ast_var_assign(const char *name, const char *value);
2083
2084 static void ast_var_delete(struct ast_var_t *var);
2085
2086 /*from channel.h */
2087 #define AST_MAX_EXTENSION  80      /*!< Max length of an extension */
2088
2089
2090 /* from pbx.h */
2091 #define PRIORITY_HINT   -1      /*!< Special Priority for a hint */
2092
2093 enum ast_extension_states {
2094         AST_EXTENSION_REMOVED = -2,     /*!< Extension removed */
2095         AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */
2096         AST_EXTENSION_NOT_INUSE = 0,    /*!< No device INUSE or BUSY  */
2097         AST_EXTENSION_INUSE = 1 << 0,   /*!< One or more devices INUSE */
2098         AST_EXTENSION_BUSY = 1 << 1,    /*!< All devices BUSY */
2099         AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */
2100         AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */
2101         AST_EXTENSION_ONHOLD = 1 << 4,  /*!< All devices ONHOLD */
2102 };
2103
2104 struct ast_custom_function {
2105         const char *name;               /*!< Name */
2106         const char *synopsis;           /*!< Short description for "show functions" */
2107         const char *desc;               /*!< Help text that explains it all */
2108         const char *syntax;             /*!< Syntax description */
2109         int (*read)(struct ast_channel *, const char *, char *, char *, size_t);        /*!< Read function, if read is supported */
2110         int (*write)(struct ast_channel *, const char *, char *, const char *);         /*!< Write function, if write is supported */
2111         AST_RWLIST_ENTRY(ast_custom_function) acflist;
2112 };
2113
2114 typedef int (ast_switch_f)(struct ast_channel *chan, const char *context,
2115         const char *exten, int priority, const char *callerid, const char *data);
2116
2117 struct ast_switch {
2118         AST_LIST_ENTRY(ast_switch) list;
2119         const char *name;                       /*!< Name of the switch */
2120         const char *description;                /*!< Description of the switch */
2121
2122         ast_switch_f *exists;
2123         ast_switch_f *canmatch;
2124         ast_switch_f *exec;
2125         ast_switch_f *matchmore;
2126 };
2127
2128
2129 static char *config_filename = "extensions.conf";
2130 static char *global_registrar = "conf2ael";
2131 static char userscontext[AST_MAX_EXTENSION] = "default";
2132 static int static_config = 0;
2133 static int write_protect_config = 1;
2134 static int autofallthrough_config = 0;
2135 static int clearglobalvars_config = 0;
2136 static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
2137
2138
2139 /* stolen from callerid.c */
2140
2141 /*! \brief Clean up phone string
2142  * remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets.
2143  * Basically, remove anything that could be invalid in a pattern.
2144  */
2145 static void ast_shrink_phone_number(char *n)
2146 {
2147         int x, y=0;
2148         int bracketed = 0;
2149
2150         for (x=0; n[x]; x++) {
2151                 switch(n[x]) {
2152                 case '[':
2153                         bracketed++;
2154                         n[y++] = n[x];
2155                         break;
2156                 case ']':
2157                         bracketed--;
2158                         n[y++] = n[x];
2159                         break;
2160                 case '-':
2161                         if (bracketed)
2162                                 n[y++] = n[x];
2163                         break;
2164                 case '.':
2165                         if (!n[x+1])
2166                                 n[y++] = n[x];
2167                         break;
2168                 default:
2169                         if (!strchr("()", n[x]))
2170                                 n[y++] = n[x];
2171                 }
2172         }
2173         n[y] = '\0';
2174 }
2175
2176
2177 /* stolen from chanvars.c */
2178
2179 static const char *ast_var_name(const struct ast_var_t *var)
2180 {
2181         const char *name;
2182
2183         if (var == NULL || (name = var->name) == NULL)
2184                 return NULL;
2185         /* Return the name without the initial underscores */
2186         if (name[0] == '_') {
2187                 name++;
2188                 if (name[0] == '_')
2189                         name++;
2190         }
2191         return name;
2192 }
2193
2194 /* experiment 1: see if it's easier just to use existing config code
2195  *               to read in the extensions.conf file. In this scenario,
2196                  I have to rip/copy code from other modules, because they
2197                  are staticly declared as-is. A solution would be to move
2198                  the ripped code to another location and make them available
2199                  to other modules and standalones */
2200
2201 /* Our own version of ast_log, since the expr parser uses it. -- stolen from utils/check_expr.c */
2202
2203 static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
2204 {
2205         va_list vars;
2206         va_start(vars,fmt);
2207
2208         printf("LOG: lev:%d file:%s  line:%d func: %s  ",
2209                    level, file, line, function);
2210         vprintf(fmt, vars);
2211         fflush(stdout);
2212         va_end(vars);
2213 }
2214
2215 void __attribute__((format(printf, 1, 2))) ast_verbose(const char *fmt, ...)
2216 {
2217         va_list vars;
2218         va_start(vars,fmt);
2219
2220         printf("VERBOSE: ");
2221         vprintf(fmt, vars);
2222         fflush(stdout);
2223         va_end(vars);
2224 }
2225
2226 /* stolen from main/utils.c */
2227 static char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
2228 {
2229         char *dataPut = start;
2230         int inEscape = 0;
2231         int inQuotes = 0;
2232
2233         for (; *start; start++) {
2234                 if (inEscape) {
2235                         *dataPut++ = *start;       /* Always goes verbatim */
2236                         inEscape = 0;
2237                 } else {
2238                         if (*start == '\\') {
2239                                 inEscape = 1;      /* Do not copy \ into the data */
2240                         } else if (*start == '\'') {
2241                                 inQuotes = 1 - inQuotes;   /* Do not copy ' into the data */
2242                         } else {
2243                                 /* Replace , with |, unless in quotes */
2244                                 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
2245                         }
2246                 }
2247         }
2248         if (start != dataPut)
2249                 *dataPut = 0;
2250         return dataPut;
2251 }
2252
2253 static int ast_true(const char *s)
2254 {
2255         if (ast_strlen_zero(s))
2256                 return 0;
2257
2258         /* Determine if this is a true value */
2259         if (!strcasecmp(s, "yes") ||
2260             !strcasecmp(s, "true") ||
2261             !strcasecmp(s, "y") ||
2262             !strcasecmp(s, "t") ||
2263             !strcasecmp(s, "1") ||
2264             !strcasecmp(s, "on"))
2265                 return -1;
2266
2267         return 0;
2268 }
2269
2270 #define ONE_MILLION     1000000
2271 /*
2272  * put timeval in a valid range. usec is 0..999999
2273  * negative values are not allowed and truncated.
2274  */
2275 static struct timeval tvfix(struct timeval a)
2276 {
2277         if (a.tv_usec >= ONE_MILLION) {
2278                 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
2279                         (long)a.tv_sec, (long int) a.tv_usec);
2280                 a.tv_sec += a.tv_usec / ONE_MILLION;
2281                 a.tv_usec %= ONE_MILLION;
2282         } else if (a.tv_usec < 0) {
2283                 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
2284                         (long)a.tv_sec, (long int) a.tv_usec);
2285                 a.tv_usec = 0;
2286         }
2287         return a;
2288 }
2289
2290 struct timeval ast_tvadd(struct timeval a, struct timeval b);
2291 struct timeval ast_tvadd(struct timeval a, struct timeval b)
2292 {
2293         /* consistency checks to guarantee usec in 0..999999 */
2294         a = tvfix(a);
2295         b = tvfix(b);
2296         a.tv_sec += b.tv_sec;
2297         a.tv_usec += b.tv_usec;
2298         if (a.tv_usec >= ONE_MILLION) {
2299                 a.tv_sec++;
2300                 a.tv_usec -= ONE_MILLION;
2301         }
2302         return a;
2303 }
2304
2305 struct timeval ast_tvsub(struct timeval a, struct timeval b);
2306 struct timeval ast_tvsub(struct timeval a, struct timeval b)
2307 {
2308         /* consistency checks to guarantee usec in 0..999999 */
2309         a = tvfix(a);
2310         b = tvfix(b);
2311         a.tv_sec -= b.tv_sec;
2312         a.tv_usec -= b.tv_usec;
2313         if (a.tv_usec < 0) {
2314                 a.tv_sec-- ;
2315                 a.tv_usec += ONE_MILLION;
2316         }
2317         return a;
2318 }
2319 #undef ONE_MILLION
2320
2321 void ast_mark_lock_failed(void *lock_addr);
2322 void ast_mark_lock_failed(void *lock_addr)
2323 {
2324         /* Pretend to do something. */
2325 }
2326
2327 /* stolen from pbx.c */
2328 #define VAR_BUF_SIZE 4096
2329
2330 #define VAR_NORMAL              1
2331 #define VAR_SOFTTRAN    2
2332 #define VAR_HARDTRAN    3
2333
2334 #define BACKGROUND_SKIP         (1 << 0)
2335 #define BACKGROUND_NOANSWER     (1 << 1)
2336 #define BACKGROUND_MATCHEXTEN   (1 << 2)
2337 #define BACKGROUND_PLAYBACK     (1 << 3)
2338
2339 /*!
2340    \brief ast_exten: An extension
2341         The dialplan is saved as a linked list with each context
2342         having it's own linked list of extensions - one item per
2343         priority.
2344 */
2345 struct ast_exten {
2346         char *exten;                    /*!< Extension name */
2347         int matchcid;                   /*!< Match caller id ? */
2348         const char *cidmatch;           /*!< Caller id to match for this extension */
2349         int priority;                   /*!< Priority */
2350         const char *label;              /*!< Label */
2351         struct ast_context *parent;     /*!< The context this extension belongs to  */
2352         const char *app;                /*!< Application to execute */
2353         struct ast_app *cached_app;     /*!< Cached location of application */
2354         void *data;                     /*!< Data to use (arguments) */
2355         void (*datad)(void *);          /*!< Data destructor */
2356         struct ast_exten *peer;         /*!< Next higher priority with our extension */
2357         const char *registrar;          /*!< Registrar */
2358         struct ast_exten *next;         /*!< Extension with a greater ID */
2359         char stuff[0];
2360 };
2361 /* from pbx.h */
2362 typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data);
2363 struct ast_timing {
2364         int hastime;                            /*!< If time construct exists */
2365         unsigned int monthmask;                 /*!< Mask for month */
2366         unsigned int daymask;                   /*!< Mask for date */
2367         unsigned int dowmask;                   /*!< Mask for day of week (mon-sun) */
2368         unsigned int minmask[48];               /*!< Mask for minute */
2369         char *timezone;                 /*!< NULL, or zoneinfo style timezone */
2370 };
2371 /* end of pbx.h */
2372 /*! \brief ast_include: include= support in extensions.conf */
2373 struct ast_include {
2374         const char *name;
2375         const char *rname;                      /*!< Context to include */
2376         const char *registrar;                  /*!< Registrar */
2377         int hastime;                            /*!< If time construct exists */
2378         struct ast_timing timing;               /*!< time construct */
2379         struct ast_include *next;               /*!< Link them together */
2380         char stuff[0];
2381 };
2382
2383 /*! \brief ast_sw: Switch statement in extensions.conf */
2384 struct ast_sw {
2385         char *name;
2386         const char *registrar;                  /*!< Registrar */
2387         char *data;                             /*!< Data load */
2388         int eval;
2389         AST_LIST_ENTRY(ast_sw) list;
2390         char *tmpdata;
2391         char stuff[0];
2392 };
2393
2394 /*! \brief ast_ignorepat: Ignore patterns in dial plan */
2395 struct ast_ignorepat {
2396         const char *registrar;
2397         struct ast_ignorepat *next;
2398         char pattern[0];
2399 };
2400
2401 /*! \brief ast_context: An extension context */
2402 struct ast_context {
2403         ast_rwlock_t lock;                      /*!< A lock to prevent multiple threads from clobbering the context */
2404         struct ast_exten *root;                 /*!< The root of the list of extensions */
2405         struct ast_context *next;               /*!< Link them together */
2406         struct ast_include *includes;           /*!< Include other contexts */
2407         struct ast_ignorepat *ignorepats;       /*!< Patterns for which to continue playing dialtone */
2408         const char *registrar;                  /*!< Registrar */
2409         AST_LIST_HEAD_NOLOCK(, ast_sw) alts;    /*!< Alternative switches */
2410         ast_mutex_t macrolock;                  /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
2411         char name[0];                           /*!< Name of the context */
2412 };
2413
2414
2415 /*! \brief ast_app: A registered application */
2416 struct ast_app {
2417         int (*execute)(struct ast_channel *chan, void *data);
2418         const char *synopsis;                   /*!< Synopsis text for 'show applications' */
2419         const char *description;                /*!< Description (help text) for 'show application &lt;name&gt;' */
2420         AST_RWLIST_ENTRY(ast_app) list;         /*!< Next app in list */
2421         void *module;                   /*!< Module this app belongs to */
2422         char name[0];                           /*!< Name of the application */
2423 };
2424
2425
2426 /*! \brief ast_state_cb: An extension state notify register item */
2427 struct ast_state_cb {
2428         int id;
2429         void *data;
2430         ast_state_cb_type callback;
2431         struct ast_state_cb *next;
2432 };
2433
2434 /*! \brief Structure for dial plan hints
2435
2436   \note Hints are pointers from an extension in the dialplan to one or
2437   more devices (tech/name)
2438         - See \ref AstExtState
2439 */
2440 struct ast_hint {
2441         struct ast_exten *exten;        /*!< Extension */
2442         int laststate;                  /*!< Last known state */
2443         struct ast_state_cb *callbacks; /*!< Callback list for this extension */
2444         AST_RWLIST_ENTRY(ast_hint) list;/*!< Pointer to next hint in list */
2445 };
2446
2447 struct store_hint {
2448         char *context;
2449         char *exten;
2450         struct ast_state_cb *callbacks;
2451         int laststate;
2452         AST_LIST_ENTRY(store_hint) list;
2453         char data[1];
2454 };
2455
2456 AST_LIST_HEAD(store_hints, store_hint);
2457
2458 #define STATUS_NO_CONTEXT       1
2459 #define STATUS_NO_EXTENSION     2
2460 #define STATUS_NO_PRIORITY      3
2461 #define STATUS_NO_LABEL         4
2462 #define STATUS_SUCCESS          5
2463
2464 static struct ast_var_t *ast_var_assign(const char *name, const char *value)
2465 {
2466         struct ast_var_t *var;
2467         int name_len = strlen(name) + 1;
2468         int value_len = strlen(value) + 1;
2469
2470         if (!(var = ast_calloc(sizeof(*var) + name_len + value_len, sizeof(char)))) {
2471                 return NULL;
2472         }
2473
2474         ast_copy_string(var->name, name, name_len);
2475         var->value = var->name + name_len;
2476         ast_copy_string(var->value, value, value_len);
2477
2478         return var;
2479 }
2480
2481 static void ast_var_delete(struct ast_var_t *var)
2482 {
2483         free(var);
2484 }
2485
2486
2487 /* chopped this one off at the knees! */
2488 static int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
2489 {
2490
2491         /* ast_log(LOG_ERROR, "Function %s not registered\n", function); we are not interested in the details here */
2492
2493         return -1;
2494 }
2495
2496 static unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
2497 {
2498         int argc;
2499         char *scan;
2500         int paren = 0, quote = 0;
2501
2502         if (!buf || !array || !arraylen)
2503                 return 0;
2504
2505         memset(array, 0, arraylen * sizeof(*array));
2506
2507         scan = buf;
2508
2509         for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
2510                 array[argc] = scan;
2511                 for (; *scan; scan++) {
2512                         if (*scan == '(')
2513                                 paren++;
2514                         else if (*scan == ')') {
2515                                 if (paren)
2516                                         paren--;
2517                         } else if (*scan == '"' && delim != '"') {
2518                                 quote = quote ? 0 : 1;
2519                                 /* Remove quote character from argument */
2520                                 memmove(scan, scan + 1, strlen(scan));
2521                                 scan--;
2522                         } else if (*scan == '\\') {
2523                                 /* Literal character, don't parse */
2524                                 memmove(scan, scan + 1, strlen(scan));
2525                         } else if ((*scan == delim) && !paren && !quote) {
2526                                 *scan++ = '\0';
2527                                 break;
2528                         }
2529                 }
2530         }
2531
2532         if (*scan)
2533                 array[argc++] = scan;
2534
2535         return argc;
2536 }
2537
2538 static void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
2539 {
2540         struct ast_var_t *newvariable;
2541         struct varshead *headp;
2542         const char *nametail = name;
2543
2544         /* XXX may need locking on the channel ? */
2545         if (name[strlen(name)-1] == ')') {
2546                 char *function = ast_strdupa(name);
2547
2548                 ast_func_write(chan, function, value);
2549                 return;
2550         }
2551
2552         headp = &globals;
2553
2554         /* For comparison purposes, we have to strip leading underscores */
2555         if (*nametail == '_') {
2556                 nametail++;
2557                 if (*nametail == '_')
2558                         nametail++;
2559         }
2560
2561         AST_LIST_TRAVERSE (headp, newvariable, entries) {
2562                 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
2563                         /* there is already such a variable, delete it */
2564                         AST_LIST_REMOVE(headp, newvariable, entries);
2565                         ast_var_delete(newvariable);
2566                         break;
2567                 }
2568         }
2569
2570         if (value && (newvariable = ast_var_assign(name, value))) {
2571                 if ((option_verbose > 1) && (headp == &globals))
2572                         ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
2573                 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
2574         }
2575
2576 }
2577
2578 static int pbx_builtin_setvar(struct ast_channel *chan, const void *data)
2579 {
2580         char *name, *value, *mydata;
2581         int argc;
2582         char *argv[24];         /* this will only support a maximum of 24 variables being set in a single operation */
2583         int global = 0;
2584         int x;
2585
2586         if (ast_strlen_zero(data)) {
2587                 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n");
2588                 return 0;
2589         }
2590
2591         mydata = ast_strdupa(data);
2592         argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
2593
2594         /* check for a trailing flags argument */
2595         if ((argc > 1) && !strchr(argv[argc-1], '=')) {
2596                 argc--;
2597                 if (strchr(argv[argc], 'g'))
2598                         global = 1;
2599         }
2600
2601         for (x = 0; x < argc; x++) {
2602                 name = argv[x];
2603                 if ((value = strchr(name, '='))) {
2604                         *value++ = '\0';
2605                         pbx_builtin_setvar_helper((global) ? NULL : chan, name, value);
2606                 } else
2607                         ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name);
2608         }
2609
2610         return(0);
2611 }
2612
2613 int localized_pbx_builtin_setvar(struct ast_channel *chan, const void *data);
2614
2615 int localized_pbx_builtin_setvar(struct ast_channel *chan, const void *data)
2616 {
2617         return pbx_builtin_setvar(chan, data);
2618 }
2619
2620
2621 /*! \brief Helper for get_range.
2622  * return the index of the matching entry, starting from 1.
2623  * If names is not supplied, try numeric values.
2624  */
2625 static int lookup_name(const char *s, char *const names[], int max)
2626 {
2627         int i;
2628
2629         if (names && *s > '9') {
2630                 for (i = 0; names[i]; i++) {
2631                         if (!strcasecmp(s, names[i])) {
2632                                 return i;
2633                         }
2634                 }
2635         }
2636
2637         /* Allow months and weekdays to be specified as numbers, as well */
2638         if (sscanf(s, "%2d", &i) == 1 && i >= 1 && i <= max) {
2639                 /* What the array offset would have been: "1" would be at offset 0 */
2640                 return i - 1;
2641         }
2642         return -1; /* error return */
2643 }
2644
2645 /*! \brief helper function to return a range up to max (7, 12, 31 respectively).
2646  * names, if supplied, is an array of names that should be mapped to numbers.
2647  */
2648 static unsigned get_range(char *src, int max, char *const names[], const char *msg)
2649 {
2650         int start, end; /* start and ending position */
2651         unsigned int mask = 0;
2652         char *part;
2653
2654         /* Check for whole range */
2655         if (ast_strlen_zero(src) || !strcmp(src, "*")) {
2656                 return (1 << max) - 1;
2657         }
2658
2659         while ((part = strsep(&src, "&"))) {
2660                 /* Get start and ending position */
2661                 char *endpart = strchr(part, '-');
2662                 if (endpart) {
2663                         *endpart++ = '\0';
2664                 }
2665                 /* Find the start */
2666                 if ((start = lookup_name(part, names, max)) < 0) {
2667                         ast_log(LOG_WARNING, "Invalid %s '%s', skipping element\n", msg, part);
2668                         continue;
2669                 }
2670                 if (endpart) { /* find end of range */
2671                         if ((end = lookup_name(endpart, names, max)) < 0) {
2672                                 ast_log(LOG_WARNING, "Invalid end %s '%s', skipping element\n", msg, endpart);
2673                                 continue;
2674                         }
2675                 } else {
2676                         end = start;
2677                 }
2678                 /* Fill the mask. Remember that ranges are cyclic */
2679                 mask |= (1 << end);   /* initialize with last element */
2680                 while (start != end) {
2681                         if (start >= max) {
2682                                 start = 0;
2683                         }
2684                         mask |= (1 << start);
2685                         start++;
2686                 }
2687         }
2688         return mask;
2689 }
2690
2691 /*! \brief store a bitmask of valid times, one bit each 2 minute */
2692 static void get_timerange(struct ast_timing *i, char *times)
2693 {
2694         char *endpart, *part;
2695         int x;
2696         int st_h, st_m;
2697         int endh, endm;
2698         int minute_start, minute_end;
2699
2700         /* start disabling all times, fill the fields with 0's, as they may contain garbage */
2701         memset(i->minmask, 0, sizeof(i->minmask));
2702
2703         /* 1-minute per bit */
2704         /* Star is all times */
2705         if (ast_strlen_zero(times) || !strcmp(times, "*")) {
2706                 /* 48, because each hour takes 2 integers; 30 bits each */
2707                 for (x = 0; x < 48; x++) {
2708                         i->minmask[x] = 0x3fffffff; /* 30 bits */
2709                 }
2710                 return;
2711         }
2712         /* Otherwise expect a range */
2713         while ((part = strsep(&times, "&"))) {
2714                 if (!(endpart = strchr(part, '-'))) {
2715                         if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
2716                                 ast_log(LOG_WARNING, "%s isn't a valid time.\n", part);
2717                                 continue;
2718                         }
2719                         i->minmask[st_h * 2 + (st_m >= 30 ? 1 : 0)] |= (1 << (st_m % 30));
2720                         continue;
2721                 }
2722                 *endpart++ = '\0';
2723                 /* why skip non digits? Mostly to skip spaces */
2724                 while (*endpart && !isdigit(*endpart)) {
2725                         endpart++;
2726                 }
2727                 if (!*endpart) {
2728                         ast_log(LOG_WARNING, "Invalid time range starting with '%s-'.\n", part);
2729                         continue;
2730                 }
2731                 if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
2732                         ast_log(LOG_WARNING, "'%s' isn't a valid start time.\n", part);
2733                         continue;
2734                 }
2735                 if (sscanf(endpart, "%2d:%2d", &endh, &endm) != 2 || endh < 0 || endh > 23 || endm < 0 || endm > 59) {
2736                         ast_log(LOG_WARNING, "'%s' isn't a valid end time.\n", endpart);
2737                         continue;
2738                 }
2739                 minute_start = st_h * 60 + st_m;
2740                 minute_end = endh * 60 + endm;
2741                 /* Go through the time and enable each appropriate bit */
2742                 for (x = minute_start; x != minute_end; x = (x + 1) % (24 * 60)) {
2743                         i->minmask[x / 30] |= (1 << (x % 30));
2744                 }
2745                 /* Do the last one */
2746                 i->minmask[x / 30] |= (1 << (x % 30));
2747         }
2748         /* All done */
2749         return;
2750 }
2751
2752 static void null_datad(void *foo)
2753 {
2754 }
2755
2756 /*! \brief Find realtime engine for realtime family */
2757 static struct ast_config_engine *find_engine(const char *family, char *database, int dbsiz, char *table, int tabsiz)
2758 {
2759         struct ast_config_engine *eng, *ret = NULL;
2760         struct ast_config_map *map;
2761
2762
2763         for (map = config_maps; map; map = map->next) {
2764                 if (!strcasecmp(family, map->name)) {
2765                         if (database)
2766                                 ast_copy_string(database, map->database, dbsiz);
2767                         if (table)
2768                                 ast_copy_string(table, map->table ? map->table : family, tabsiz);
2769                         break;
2770                 }
2771         }
2772
2773         /* Check if the required driver (engine) exist */
2774         if (map) {
2775                 for (eng = config_engine_list; !ret && eng; eng = eng->next) {
2776                         if (!strcasecmp(eng->name, map->driver))
2777                                 ret = eng;
2778                 }
2779         }
2780
2781
2782         /* if we found a mapping, but the engine is not available, then issue a warning */
2783         if (map && !ret)
2784                 ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
2785
2786         return ret;
2787 }
2788
2789 struct ast_category *ast_config_get_current_category(const struct ast_config *cfg);
2790
2791 struct ast_category *ast_config_get_current_category(const struct ast_config *cfg)
2792 {
2793         return cfg->current;
2794 }
2795
2796 static struct ast_category *ast_category_new(const char *name, const char *in_file, int lineno);
2797
2798 static struct ast_category *ast_category_new(const char *name, const char *in_file, int lineno)
2799 {
2800         struct ast_category *category;
2801
2802         if ((category = ast_calloc(1, sizeof(*category))))
2803                 ast_copy_string(category->name, name, sizeof(category->name));
2804         category->file = strdup(in_file);
2805         category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
2806         return category;
2807 }
2808
2809 struct ast_category *localized_category_get(const struct ast_config *config, const char *category_name);
2810
2811 struct ast_category *localized_category_get(const struct ast_config *config, const char *category_name)
2812 {
2813         return category_get(config, category_name, 0);
2814 }
2815
2816 static void move_variables(struct ast_category *old, struct ast_category *new)
2817 {
2818         struct ast_variable *var = old->root;
2819         old->root = NULL;
2820 #if 1
2821         /* we can just move the entire list in a single op */
2822         ast_variable_append(new, var);
2823 #else
2824         while (var) {
2825                 struct ast_variable *next = var->next;
2826                 var->next = NULL;
2827                 ast_variable_append(new, var);
2828                 var = next;
2829         }
2830 #endif
2831 }
2832
2833 static void inherit_category(struct ast_category *new, const struct ast_category *base)
2834 {
2835         struct ast_variable *var;
2836
2837         for (var = base->root; var; var = var->next)
2838                 ast_variable_append(new, variable_clone(var));
2839 }
2840
2841 static void ast_category_append(struct ast_config *config, struct ast_category *category);
2842
2843 static void ast_category_append(struct ast_config *config, struct ast_category *category)
2844 {
2845         if (config->last)
2846                 config->last->next = category;
2847         else
2848                 config->root = category;
2849         config->last = category;
2850         config->current = category;
2851 }
2852
2853 static void ast_category_destroy(struct ast_category *cat);
2854
2855 static void ast_category_destroy(struct ast_category *cat)
2856 {
2857         ast_variables_destroy(cat->root);
2858         if (cat->file)
2859                 free(cat->file);
2860
2861         free(cat);
2862 }
2863
2864 static struct ast_config_engine text_file_engine = {
2865         .name = "text",
2866         .load_func = config_text_file_load,
2867 };
2868
2869
2870 static struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_incl_file);
2871
2872 static struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_incl_file)
2873 {
2874         char db[256];
2875         char table[256];
2876         struct ast_config_engine *loader = &text_file_engine;
2877         struct ast_config *result;
2878
2879         if (cfg->include_level == cfg->max_include_level) {
2880                 ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
2881                 return NULL;
2882         }
2883
2884         cfg->include_level++;
2885         /*  silence is golden!
2886                 ast_log(LOG_WARNING, "internal loading file %s level=%d\n", filename, cfg->include_level);
2887         */
2888
2889         if (strcmp(filename, extconfig_conf) && strcmp(filename, "asterisk.conf") && config_engine_list) {
2890                 struct ast_config_engine *eng;
2891
2892                 eng = find_engine(filename, db, sizeof(db), table, sizeof(table));
2893
2894
2895                 if (eng && eng->load_func) {
2896                         loader = eng;
2897                 } else {
2898                         eng = find_engine("global", db, sizeof(db), table, sizeof(table));
2899                         if (eng && eng->load_func)
2900                                 loader = eng;
2901                 }
2902         }
2903
2904         result = loader->load_func(db, table, filename, cfg, withcomments, suggested_incl_file);
2905         /* silence is golden
2906            ast_log(LOG_WARNING, "finished internal loading file %s level=%d\n", filename, cfg->include_level);
2907         */
2908
2909         if (result)
2910                 result->include_level--;
2911
2912         return result;
2913 }
2914
2915
2916 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)
2917 {
2918         char *c;
2919         char *cur = buf;
2920         struct ast_variable *v;
2921         char cmd[512], exec_file[512];
2922         int object, do_exec, do_include;
2923
2924         /* Actually parse the entry */
2925         if (cur[0] == '[') {
2926                 struct ast_category *newcat = NULL;
2927                 char *catname;
2928
2929                 /* A category header */
2930                 c = strchr(cur, ']');
2931                 if (!c) {
2932                         ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
2933                         return -1;
2934                 }
2935                 *c++ = '\0';
2936                 cur++;
2937                 if (*c++ != '(')
2938                         c = NULL;
2939                 catname = cur;
2940                 if (!(*cat = newcat = ast_category_new(catname, ast_strlen_zero(suggested_include_file)?configfile:suggested_include_file, lineno))) {
2941                         return -1;
2942                 }
2943                 (*cat)->lineno = lineno;
2944
2945                 /* add comments */
2946                 if (withcomments && comment_buffer && comment_buffer[0] ) {
2947                         newcat->precomments = ALLOC_COMMENT(comment_buffer);
2948                 }
2949                 if (withcomments && lline_buffer && lline_buffer[0] ) {
2950                         newcat->sameline = ALLOC_COMMENT(lline_buffer);
2951                 }
2952                 if( withcomments )
2953                         CB_RESET();
2954
2955                 /* If there are options or categories to inherit from, process them now */
2956                 if (c) {
2957                         if (!(cur = strchr(c, ')'))) {
2958                                 ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
2959                                 return -1;
2960                         }
2961                         *cur = '\0';
2962                         while ((cur = strsep(&c, ","))) {
2963                                 if (!strcasecmp(cur, "!")) {
2964                                         (*cat)->ignored = 1;
2965                                 } else if (!strcasecmp(cur, "+")) {
2966                                         *cat = category_get(cfg, catname, 1);
2967                                         if (!*cat) {
2968                                                 ast_config_destroy(cfg);
2969                                                 if (newcat)
2970                                                         ast_category_destroy(newcat);
2971                                                 ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
2972                                                 return -1;
2973                                         }
2974                                         if (newcat) {
2975                                                 move_variables(newcat, *cat);
2976                                                 ast_category_destroy(newcat);
2977                                                 newcat = NULL;
2978                                         }
2979                                 } else {
2980                                         struct ast_category *base;
2981
2982                                         base = category_get(cfg, cur, 1);
2983                                         if (!base) {
2984                                                 ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
2985                                                 return -1;
2986                                         }
2987                                         inherit_category(*cat, base);
2988                                 }
2989                         }
2990                 }
2991                 if (newcat)
2992                         ast_category_append(cfg, *cat);
2993         } else if (cur[0] == '#') {
2994                 /* A directive */
2995                 cur++;
2996                 c = cur;
2997                 while(*c && (*c > 32)) c++;
2998                 if (*c) {
2999                         *c = '\0';
3000                         /* Find real argument */
3001                         c = ast_skip_blanks(c + 1);
3002                         if (!*c)
3003                                 c = NULL;
3004                 } else
3005                         c = NULL;
3006                 do_include = !strcasecmp(cur, "include");
3007                 if(!do_include)
3008                         do_exec = !strcasecmp(cur, "exec");
3009                 else
3010                         do_exec = 0;
3011                 if (do_exec && !ast_opt_exec_includes) {
3012                         ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
3013                         do_exec = 0;
3014                 }
3015                 if (do_include || do_exec) {
3016                         if (c) {
3017                                 char *cur2;
3018                                 char real_inclusion_name[256];
3019
3020                                 /* Strip off leading and trailing "'s and <>'s */
3021                                 while((*c == '<') || (*c == '>') || (*c == '\"')) c++;
3022                                 /* Get rid of leading mess */
3023                                 cur = c;
3024                                 cur2 = cur;
3025                                 while (!ast_strlen_zero(cur)) {
3026                                         c = cur + strlen(cur) - 1;
3027                                         if ((*c == '>') || (*c == '<') || (*c == '\"'))
3028                                                 *c = '\0';
3029                                         else
3030                                                 break;
3031                                 }
3032                                 /* #exec </path/to/executable>
3033                                    We create a tmp file, then we #include it, then we delete it. */
3034                                 if (do_exec) {
3035                                         snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d.%ld", (int)time(NULL), (long)pthread_self());
3036                                         snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file);
3037                                         ast_safe_system(cmd);
3038                                         cur = exec_file;
3039                                 } else
3040                                         exec_file[0] = '\0';
3041                                 /* A #include */
3042                                 /* ast_log(LOG_WARNING, "Reading in included file %s withcomments=%d\n", cur, withcomments); */
3043
3044                                 /* record this inclusion */
3045                                 ast_include_new(cfg, configfile, cur, do_exec, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name));
3046
3047                                 do_include = ast_config_internal_load(cur, cfg, withcomments, real_inclusion_name) ? 1 : 0;
3048                                 if(!ast_strlen_zero(exec_file))
3049                                         unlink(exec_file);
3050                                 if(!do_include)
3051                                         return 0;
3052                                 /* ast_log(LOG_WARNING, "Done reading in included file %s withcomments=%d\n", cur, withcomments); */
3053
3054                         } else {
3055                                 ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n",
3056                                                 do_exec ? "exec" : "include",
3057                                                 do_exec ? "/path/to/executable" : "filename",
3058                                                 lineno,
3059                                                 configfile);
3060                         }
3061                 }
3062                 else
3063                         ast_log(LOG_WARNING, "Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile);
3064         } else {
3065                 /* Just a line (variable = value) */
3066                 if (!*cat) {
3067                         ast_log(LOG_WARNING,
3068                                 "parse error: No category context for line %d of %s\n", lineno, configfile);
3069                         return -1;
3070                 }
3071                 c = strchr(cur, '=');
3072                 if (c) {
3073                         *c = 0;
3074                         c++;
3075                         /* Ignore > in => */
3076                         if (*c== '>') {
3077                                 object = 1;
3078                                 c++;
3079                         } else
3080                                 object = 0;
3081                         if ((v = ast_variable_new(ast_strip(cur), ast_strip(c), configfile))) {
3082                                 v->lineno = lineno;
3083                                 v->object = object;
3084                                 /* Put and reset comments */
3085                                 v->blanklines = 0;
3086                                 ast_variable_append(*cat, v);
3087                                 /* add comments */
3088                                 if (withcomments && comment_buffer && comment_buffer[0] ) {
3089                                         v->precomments = ALLOC_COMMENT(comment_buffer);
3090                                 }
3091                                 if (withcomments && lline_buffer && lline_buffer[0] ) {
3092                                         v->sameline = ALLOC_COMMENT(lline_buffer);
3093                                 }
3094                                 if( withcomments )
3095                                         CB_RESET();
3096
3097                         } else {
3098                                 return -1;
3099                         }
3100                 } else {
3101                         ast_log(LOG_WARNING, "EXTENSIONS.CONF: No '=' (equal sign) in line %d of %s\n", lineno, configfile);
3102                 }
3103         }
3104         return 0;
3105 }
3106
3107 static int use_local_dir = 1;
3108
3109 void localized_use_local_dir(void);
3110 void localized_use_conf_dir(void);
3111
3112 void localized_use_local_dir(void)
3113 {
3114         use_local_dir = 1;
3115 }
3116
3117 void localized_use_conf_dir(void)
3118 {
3119         use_local_dir = 0;
3120 }
3121
3122
3123 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)
3124 {
3125         char fn[256];
3126         char buf[8192];
3127         char *new_buf, *comment_p, *process_buf;
3128         FILE *f;
3129         int lineno=0;
3130         int comment = 0, nest[MAX_NESTED_COMMENTS];
3131         struct ast_category *cat = NULL;
3132         int count = 0;
3133         struct stat statbuf;
3134
3135         cat = ast_config_get_current_category(cfg);
3136
3137         if (filename[0] == '/') {
3138                 ast_copy_string(fn, filename, sizeof(fn));
3139         } else {
3140                 if (use_local_dir)
3141                         snprintf(fn, sizeof(fn), "./%s", filename);
3142                 else
3143                         snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
3144         }
3145
3146         if (withcomments && cfg && cfg->include_level < 2 ) {
3147                 CB_INIT();
3148         }
3149
3150 #ifdef AST_INCLUDE_GLOB
3151         {
3152                 int glob_ret;
3153                 glob_t globbuf;
3154
3155                 globbuf.gl_offs = 0;    /* initialize it to silence gcc */
3156 #ifdef SOLARIS
3157                 glob_ret = glob(fn, GLOB_NOCHECK, NULL, &globbuf);
3158 #else
3159                 glob_ret = glob(fn, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf);
3160 #endif
3161                 if (glob_ret == GLOB_NOSPACE)
3162                         ast_log(LOG_WARNING,
3163                                 "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
3164                 else if (glob_ret  == GLOB_ABORTED)
3165                         ast_log(LOG_WARNING,
3166                                 "Glob Expansion of pattern '%s' failed: Read error\n", fn);
3167                 else  {
3168                         /* loop over expanded files */
3169                         int i;
3170                         for (i=0; i<globbuf.gl_pathc; i++) {
3171                                 ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn));
3172 #endif
3173         do {
3174                 if (stat(fn, &statbuf))
3175                         continue;
3176
3177                 if (!S_ISREG(statbuf.st_mode)) {
3178                         ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
3179                         continue;
3180                 }
3181                 if (option_verbose > 1) {
3182                         ast_verbose(VERBOSE_PREFIX_2 "Parsing '%s': ", fn);
3183                         fflush(stdout);
3184                 }
3185                 if (!(f = fopen(fn, "r"))) {
3186                         if (option_debug)
3187                                 ast_log(LOG_DEBUG, "No file to parse: %s\n", fn);
3188                         if (option_verbose > 1)
3189                                 ast_verbose( "Not found (%s)\n", strerror(errno));
3190                         continue;
3191                 }
3192                 count++;
3193                 if (option_debug)
3194                         ast_log(LOG_DEBUG, "Parsing %s\n", fn);
3195                 if (option_verbose > 1)
3196                         ast_verbose("Found\n");
3197                 while(!feof(f)) {
3198                         lineno++;
3199                         if (fgets(buf, sizeof(buf), f)) {
3200                                 if ( withcomments ) {
3201                                         CB_ADD(lline_buffer);       /* add the current lline buffer to the comment buffer */
3202                                         lline_buffer[0] = 0;        /* erase the lline buffer */
3203                                 }
3204
3205                                 new_buf = buf;
3206                                 if (comment)
3207                                         process_buf = NULL;
3208                                 else
3209                                         process_buf = buf;
3210
3211                                 while ((comment_p = strchr(new_buf, COMMENT_META))) {
3212                                         if ((comment_p > new_buf) && (*(comment_p-1) == '\\')) {
3213                                                 /* Yuck, gotta memmove */
3214                                                 memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
3215                                                 new_buf = comment_p;
3216                                         } else if(comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) {
3217                                                 /* Meta-Comment start detected ";--" */
3218                                                 if (comment < MAX_NESTED_COMMENTS) {
3219                                                         *comment_p = '\0';
3220                                                         new_buf = comment_p + 3;
3221                                                         comment++;
3222                                                  &