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