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