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