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