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