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