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