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