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