2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2006, Digium, Inc.
6 * Steve Murphy <murf@digium.com>
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.
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.
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.
27 #include "asterisk/autoconfig.h"
36 #include <sys/types.h>
38 #include <sys/resource.h>
44 #if !defined(SOLARIS) && !defined(__CYGWIN__)
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
60 static char ast_config_AST_CONFIG_DIR[PATH_MAX] = {"/etc/asterisk"};
61 #define AST_API_MODULE 1 /* gimme the inline defs! */
64 char x; /* basically empty! */
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"
78 #define EVENTLOG "event_log"
79 #define QUEUELOG "queue_log"
81 #define DEBUG_M(a) { \
85 #define VERBOSE_PREFIX_1 " "
86 #define VERBOSE_PREFIX_2 " == "
87 #define VERBOSE_PREFIX_3 " -- "
88 #define VERBOSE_PREFIX_4 " > "
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))); */
93 static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__ ((format (printf,5,6)));
96 void ast_backtrace(void);
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)));
101 /* IN CONFLICT: void ast_verbose(const char *fmt, ...)
102 __attribute__ ((format (printf, 1, 2))); */
104 int ast_register_verbose(void (*verboser)(const char *string));
105 int ast_unregister_verbose(void (*verboser)(const char *string));
107 void ast_console_puts(const char *string);
109 void ast_console_puts_mutable(const char *string);
110 void ast_console_toggle_mute(int fd);
112 #define _A_ __FILE__, __LINE__, __PRETTY_FUNCTION__
117 #define __LOG_DEBUG 0
118 #define LOG_DEBUG __LOG_DEBUG, _A_
123 #define __LOG_EVENT 1
124 #define LOG_EVENT __LOG_EVENT, _A_
129 #define __LOG_NOTICE 2
130 #define LOG_NOTICE __LOG_NOTICE, _A_
135 #define __LOG_WARNING 3
136 #define LOG_WARNING __LOG_WARNING, _A_
141 #define __LOG_ERROR 4
142 #define LOG_ERROR __LOG_ERROR, _A_
147 #define __LOG_VERBOSE 5
148 #define LOG_VERBOSE __LOG_VERBOSE, _A_
154 #define LOG_DTMF __LOG_DTMF, _A_
158 static unsigned int __unsigned_int_flags_dummy;
160 struct ast_flags { /* stolen from utils.h */
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)); \
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); \
175 (p)->flags |= (flag); \
177 (p)->flags &= ~(flag); \
181 #ifdef __AST_DEBUG_MALLOC
182 static void ast_free(void *ptr) attribute_unused;
183 static void ast_free(void *ptr)
188 #define ast_free free
191 #ifndef __AST_DEBUG_MALLOC
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);
196 * \brief A wrapper for malloc()
198 * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
199 * message in the case that the allocation fails.
201 * The argument and return value are the same as malloc()
203 #define ast_malloc(len) \
204 _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
207 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
211 if (!(p = malloc(len)))
219 * \brief A wrapper for calloc()
221 * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
222 * message in the case that the allocation fails.
224 * The arguments and return value are the same as calloc()
226 #define ast_calloc(num, len) \
227 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
230 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
234 if (!(p = calloc(num, len)))
242 * \brief A wrapper for calloc() for use in cache pools
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.
249 * The arguments and return value are the same as calloc()
251 #define ast_calloc_cache(num, len) \
252 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
255 * \brief A wrapper for realloc()
257 * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
258 * message in the case that the allocation fails.
260 * The arguments and return value are the same as realloc()
262 #define ast_realloc(p, len) \
263 _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
266 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
270 if (!(newp = realloc(p, len)))
278 * \brief A wrapper for strdup()
280 * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
281 * message in the case that the allocation fails.
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.
287 * The argument and return value are the same as strdup()
289 #define ast_strdup(str) \
290 _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
293 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
298 if (!(newstr = strdup(str)))
307 * \brief A wrapper for strndup()
309 * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
310 * message in the case that the allocation fails.
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.
316 * The arguments and return value are the same as strndup()
318 #define ast_strndup(str, len) \
319 _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
322 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
327 if (!(newstr = strndup(str, len)))
336 * \brief A wrapper for asprintf()
338 * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
339 * message in the case that the allocation fails.
341 * The arguments and return value are the same as asprintf()
343 #define ast_asprintf(ret, fmt, ...) \
344 _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
347 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...),
353 if ((res = vasprintf(ret, fmt, ap)) == -1)
362 * \brief A wrapper for vasprintf()
364 * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
365 * message in the case that the allocation fails.
367 * The arguments and return value are the same as vasprintf()
369 #define ast_vasprintf(ret, fmt, ap) \
370 _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
373 int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
377 if ((res = vasprintf(ret, fmt, ap)) == -1)
386 /* If astmm is in use, let it handle these. Otherwise, it will report that
387 all allocations are coming from this header file */
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)
397 #endif /* AST_DEBUG_MALLOC */
399 #if !defined(ast_strdupa) && defined(__GNUC__)
401 \brief duplicate a string in memory from the stack
402 \param s The string to duplicate
404 This macro will duplicate the given string. It returns a pointer to the stack
405 allocatted memory for the new string.
407 #define ast_strdupa(s) \
410 const char *__old = (s); \
411 size_t __len = strlen(__old) + 1; \
412 char *__new = __builtin_alloca(__len); \
413 memcpy (__new, __old, __len); \
421 #define MAX_NESTED_COMMENTS 128
422 #define COMMENT_START ";--"
423 #define COMMENT_END "--;"
424 #define COMMENT_META ';'
425 #define COMMENT_TAG '-'
427 static char *extconfig_conf = "extconfig.conf";
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 */
433 static char *lline_buffer; /*!< A buffer for stuff behind the ; */
434 static int lline_buffer_size;
439 struct ast_comment *next;
443 static void CB_INIT(void)
445 if (!comment_buffer) {
446 comment_buffer = ast_malloc(CB_INCR);
449 comment_buffer[0] = 0;
450 comment_buffer_size = CB_INCR;
451 lline_buffer = ast_malloc(CB_INCR);
455 lline_buffer_size = CB_INCR;
457 comment_buffer[0] = 0;
462 static void CB_ADD(char *str)
464 int rem = comment_buffer_size - strlen(comment_buffer) - 1;
465 int siz = strlen(str);
467 comment_buffer = ast_realloc(comment_buffer, comment_buffer_size + CB_INCR + siz + 1);
470 comment_buffer_size += CB_INCR+siz+1;
472 strcat(comment_buffer,str);
475 static void CB_ADD_LEN(char *str, int len)
477 int cbl = strlen(comment_buffer) + 1;
478 int rem = comment_buffer_size - cbl;
480 comment_buffer = ast_realloc(comment_buffer, comment_buffer_size + CB_INCR + len + 1);
483 comment_buffer_size += CB_INCR+len+1;
485 strncat(comment_buffer,str,len);
486 comment_buffer[cbl+len-1] = 0;
489 static void LLB_ADD(char *str)
491 int rem = lline_buffer_size - strlen(lline_buffer) - 1;
492 int siz = strlen(str);
494 lline_buffer = ast_realloc(lline_buffer, lline_buffer_size + CB_INCR + siz + 1);
497 lline_buffer_size += CB_INCR + siz + 1;
499 strcat(lline_buffer,str);
502 static void CB_RESET(void )
504 comment_buffer[0] = 0;
508 /*! \brief Keep track of how many threads are currently trying to wait*() on
510 static unsigned int safe_system_level = 0;
511 static void *safe_system_prev_handler;
513 /*! \brief NULL handler so we can collect the child exit status */
514 static void null_sig_handler(int signal)
519 void ast_replace_sigchld(void);
521 void ast_replace_sigchld(void)
525 level = safe_system_level++;
527 /* only replace the handler if it has not already been done */
529 safe_system_prev_handler = signal(SIGCHLD, null_sig_handler);
533 void ast_unreplace_sigchld(void);
535 void ast_unreplace_sigchld(void)
539 level = --safe_system_level;
541 /* only restore the handler if we are the last one */
543 signal(SIGCHLD, safe_system_prev_handler);
547 int ast_safe_system(const char *s);
549 int ast_safe_system(const char *s)
552 #ifdef HAVE_WORKING_FORK
556 struct rusage rusage;
559 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
560 ast_replace_sigchld();
562 #ifdef HAVE_WORKING_FORK
569 #ifdef HAVE_WORKING_FORK
570 /* Close file descriptors and launch system command */
571 for (x = STDERR_FILENO + 1; x < 4096; x++)
574 execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
576 } else if (pid > 0) {
578 res = wait4(pid, &status, 0, &rusage);
580 res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
582 } else if (errno != EINTR)
586 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
590 ast_unreplace_sigchld();
598 static struct ast_comment *ALLOC_COMMENT(const char *buffer)
600 struct ast_comment *x = ast_calloc(1,sizeof(struct ast_comment)+strlen(buffer)+1);
601 strcpy(x->cmt, buffer);
605 static struct ast_config_map {
606 struct ast_config_map *next;
612 } *config_maps = NULL;
614 static struct ast_config_engine *config_engine_list;
616 #define MAX_INCLUDE_LEVEL 10
619 struct ast_category {
621 int ignored; /*!< do not let user of the config see this category */
623 char *file; /*!< the file name from whence this declaration was read */
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;
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 */
638 int max_include_level;
639 struct ast_config_include *includes; /*!< a list of inclusions, which should describe the entire tree */
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 */
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);
659 /*! \brief Configuration engine structure, used to define realtime drivers */
660 struct ast_config_engine {
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;
669 static struct ast_config_engine *config_engine_list;
671 /* taken from strings.h */
673 static force_inline int ast_strlen_zero(const char *s)
675 return (!s || (*s == '\0'));
678 #define S_OR(a, b) (!ast_strlen_zero(a) ? (a) : (b))
681 void ast_copy_string(char *dst, const char *src, size_t size),
683 while (*src && size) {
687 if (__builtin_expect(!size, 0))
694 char *ast_skip_blanks(const char *str),
696 while (*str && *str < 33)
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
709 char *ast_trim_blanks(char *str),
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
721 while ((work >= str) && *work < 33)
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.
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.
738 char *ast_strip(char *s),
740 s = ast_skip_blanks(s);
750 struct ast_variable {
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;
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);
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);
775 static struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename);
777 static struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename)
779 struct ast_variable *variable;
780 int name_len = strlen(name) + 1;
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);
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)
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;
802 inc = ast_include_find(conf, included_file);
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);
809 *real_included_file_name = 0;
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);
817 inc->included_file = ast_strdup(included_file);
821 inc->exec_file = ast_strdup(exec_file);
823 /* attach this new struct to the conf struct */
824 inc->next = conf->includes;
825 conf->includes = inc;
830 void localized_ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
832 struct ast_config_include *incl;
833 struct ast_category *cat;
834 struct ast_variable *v;
836 int from_len = strlen(from_file);
837 int to_len = strlen(to_file);
839 if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */
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.
848 /* file names are on categories, includes (of course), and on variables. So,
849 traverse all this and swap names */
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);
856 free(incl->include_location_file);
857 incl->include_location_file = strdup(to_file);
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);
867 cat->file = strdup(to_file);
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);
876 v->file = strdup(to_file);
883 static struct ast_config_include *ast_include_find(struct ast_config *conf, const char *included_file)
885 struct ast_config_include *x;
886 for (x=conf->includes;x;x=x->next)
888 if (strcmp(x->included_file,included_file) == 0)
895 static void ast_variable_append(struct ast_category *category, struct ast_variable *variable);
897 static void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
902 category->last->next = variable;
904 category->root = variable;
905 category->last = variable;
906 while (category->last->next)
907 category->last = category->last->next;
910 static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored);
912 static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored)
914 struct ast_category *cat;
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))
922 for (cat = config->root; cat; cat = cat->next) {
923 if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored))
930 static struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name)
932 return category_get(config, category_name, 0);
935 static struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category)
937 struct ast_category *cat = NULL;
939 if (category && config->last_browse && (config->last_browse->name == category))
940 cat = config->last_browse;
942 cat = ast_category_get(config, category);
944 return (cat) ? cat->root : NULL;
947 static const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
949 struct ast_variable *v;
952 for (v = ast_variable_browse(config, category); v; v = v->next) {
953 if (!strcasecmp(variable, v->name))
957 struct ast_category *cat;
959 for (cat = config->root; cat; cat = cat->next)
960 for (v = cat->root; v; v = v->next)
961 if (!strcasecmp(variable, v->name))
968 static struct ast_variable *variable_clone(const struct ast_variable *old)
970 struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
973 new->lineno = old->lineno;
974 new->object = old->object;
975 new->blanklines = old->blanklines;
976 /* TODO: clone comments? */
982 static void ast_variables_destroy(struct ast_variable *v)
984 struct ast_variable *vn;
993 static void ast_includes_destroy(struct ast_config_include *incls)
995 struct ast_config_include *incl,*inclnext;
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);
1009 static void ast_config_destroy(struct ast_config *cfg)
1011 struct ast_category *cat, *catn;
1016 ast_includes_destroy(cfg->includes);
1020 ast_variables_destroy(cat->root);
1029 /* options.h declars ast_options extern; I need it static? */
1031 #define AST_CACHE_DIR_LEN 512
1032 #define AST_FILENAME_MAX 80
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),
1041 AST_OPT_FLAG_QUIET = (1 << 2),
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),
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)
1084 /*! These are the options that set by default when Asterisk starts */
1085 #define AST_DEFAULT_OPTIONS AST_OPT_FLAG_TRANSCODE_VIA_SLIN
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)
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[];
1117 extern time_t ast_startuptime;
1118 extern time_t ast_lastreloadtime;
1119 extern pid_t ast_mainpid;
1121 extern char record_cache_dir[AST_CACHE_DIR_LEN];
1122 extern char debug_filename[AST_FILENAME_MAX];
1124 extern int ast_language_is_prefix;
1130 #ifndef HAVE_MTX_PROFILE
1131 #define __MTX_PROF(a) return pthread_mutex_lock((a))
1133 #define __MTX_PROF(a) do { \
1135 /* profile only non-blocking events */ \
1136 ast_mark(mtx_prof, 1); \
1137 i = pthread_mutex_trylock((a)); \
1138 ast_mark(mtx_prof, 0); \
1142 return pthread_mutex_lock((a)); \
1144 #endif /* HAVE_MTX_PROFILE */
1146 #define AST_PTHREADT_NULL (pthread_t) -1
1147 #define AST_PTHREADT_STOP (pthread_t) -2
1149 #if defined(SOLARIS) || defined(BSD)
1150 #define AST_MUTEX_INIT_W_CONSTRUCTORS
1151 #endif /* SOLARIS || BSD */
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
1159 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_MUTEX_INITIALIZER
1160 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
1161 #endif /* PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
1163 #ifdef DEBUG_THREADS
1165 #define __ast_mutex_logger(...) do { if (canlog) ast_log(LOG_ERROR, __VA_ARGS__); else fprintf(stderr, __VA_ARGS__); } while (0)
1168 #define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
1170 #define DO_THREAD_CRASH do { } while (0)
1173 #define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, { NULL }, { 0 }, 0, { NULL }, { 0 } }
1175 #define AST_MAX_REENTRANCY 10
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];
1184 const char *func[AST_MAX_REENTRANCY];
1185 pthread_t thread[AST_MAX_REENTRANCY];
1188 typedef struct ast_mutex_info ast_mutex_t;
1190 typedef pthread_cond_t ast_cond_t;
1192 static pthread_mutex_t empty_mutex;
1194 static void __attribute__((constructor)) init_empty_mutex(void)
1196 memset(&empty_mutex, 0, sizeof(empty_mutex));
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)
1203 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
1204 int canlog = strcmp(filename, "logger.c");
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);
1218 t->file[0] = filename;
1219 t->lineno[0] = lineno;
1224 return pthread_mutex_init(&t->mutex, attr);
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)
1230 static pthread_mutexattr_t attr;
1232 pthread_mutexattr_init(&attr);
1233 pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
1235 return __ast_pthread_mutex_init_attr(filename, lineno, func, mutex_name, t, &attr);
1237 #define ast_mutex_init(pmutex) __ast_pthread_mutex_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
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)
1243 int canlog = strcmp(filename, "logger.c");
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);
1252 res = pthread_mutex_trylock(&t->mutex);
1255 pthread_mutex_unlock(&t->mutex);
1258 __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy invalid mutex '%s'.\n",
1259 filename, lineno, func, mutex_name);
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);
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
1274 t->mutex = PTHREAD_MUTEX_INIT_VALUE;
1276 t->file[0] = filename;
1277 t->lineno[0] = lineno;
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)
1287 int canlog = strcmp(filename, "logger.c");
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);
1295 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
1297 #ifdef DETECT_DEADLOCKS
1299 time_t seconds = time(NULL);
1302 #ifdef HAVE_MTX_PROFILE
1303 ast_mark(mtx_prof, 1);
1305 res = pthread_mutex_trylock(&t->mutex);
1306 #ifdef HAVE_MTX_PROFILE
1307 ast_mark(mtx_prof, 0);
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);
1320 } while (res == EBUSY);
1323 #ifdef HAVE_MTX_PROFILE
1324 ast_mark(mtx_prof, 1);
1325 res = pthread_mutex_trylock(&t->mutex);
1326 ast_mark(mtx_prof, 0);
1329 res = pthread_mutex_lock(&t->mutex);
1330 #endif /* DETECT_DEADLOCKS */
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();
1340 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
1341 filename, lineno, func, mutex_name);
1344 __ast_mutex_logger("%s line %d (%s): Error obtaining mutex: %s\n",
1345 filename, lineno, func, strerror(errno));
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)
1356 int canlog = strcmp(filename, "logger.c");
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);
1364 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
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();
1374 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
1375 filename, lineno, func, mutex_name);
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);
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)
1389 int canlog = strcmp(filename, "logger.c");
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);
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);
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);
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;
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));
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)
1431 return pthread_cond_init(cond, cond_attr);
1434 static inline int __ast_cond_signal(const char *filename, int lineno, const char *func,
1435 const char *cond_name, ast_cond_t *cond)
1437 return pthread_cond_signal(cond);
1440 static inline int __ast_cond_broadcast(const char *filename, int lineno, const char *func,
1441 const char *cond_name, ast_cond_t *cond)
1443 return pthread_cond_broadcast(cond);
1446 static inline int __ast_cond_destroy(const char *filename, int lineno, const char *func,
1447 const char *cond_name, ast_cond_t *cond)
1449 return pthread_cond_destroy(cond);
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)
1457 int canlog = strcmp(filename, "logger.c");
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);
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);
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);
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;
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));
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();
1499 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
1500 filename, lineno, func, mutex_name);
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)
1512 int canlog = strcmp(filename, "logger.c");
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);
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);
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);
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;
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));
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();
1554 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
1555 filename, lineno, func, mutex_name);
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)
1573 #else /* !DEBUG_THREADS */
1576 typedef pthread_mutex_t ast_mutex_t;
1578 #define AST_MUTEX_INIT_VALUE ((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
1580 static inline int ast_mutex_init(ast_mutex_t *pmutex)
1582 pthread_mutexattr_t attr;
1584 pthread_mutexattr_init(&attr);
1585 pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
1587 return pthread_mutex_init(pmutex, &attr);
1590 #define ast_pthread_mutex_init(pmutex,a) pthread_mutex_init(pmutex,a)
1592 static inline int ast_mutex_unlock(ast_mutex_t *pmutex)
1594 return pthread_mutex_unlock(pmutex);
1597 static inline int ast_mutex_destroy(ast_mutex_t *pmutex)
1599 return pthread_mutex_destroy(pmutex);
1602 static inline int ast_mutex_lock(ast_mutex_t *pmutex)
1607 static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
1609 return pthread_mutex_trylock(pmutex);
1612 typedef pthread_cond_t ast_cond_t;
1614 static inline int ast_cond_init(ast_cond_t *cond, pthread_condattr_t *cond_attr)
1616 return pthread_cond_init(cond, cond_attr);
1619 static inline int ast_cond_signal(ast_cond_t *cond)
1621 return pthread_cond_signal(cond);
1624 static inline int ast_cond_broadcast(ast_cond_t *cond)
1626 return pthread_cond_broadcast(cond);
1629 static inline int ast_cond_destroy(ast_cond_t *cond)
1631 return pthread_cond_destroy(cond);
1634 static inline int ast_cond_wait(ast_cond_t *cond, ast_mutex_t *t)
1636 return pthread_cond_wait(cond, t);
1639 static inline int ast_cond_timedwait(ast_cond_t *cond, ast_mutex_t *t, const struct timespec *abstime)
1641 return pthread_cond_timedwait(cond, t, abstime);
1644 #endif /* !DEBUG_THREADS */
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) \
1653 ast_mutex_init(&mutex); \
1655 static void __attribute__ ((destructor)) fini_##mutex(void) \
1657 ast_mutex_destroy(&mutex); \
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 */
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
1679 #define AST_MUTEX_DEFINE_STATIC(mutex) __AST_MUTEX_DEFINE(static, mutex)
1681 #define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
1683 #define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
1686 #define pthread_create __use_ast_pthread_create_instead__
1689 typedef pthread_rwlock_t ast_rwlock_t;
1691 static inline int ast_rwlock_init(ast_rwlock_t *prwlock)
1693 pthread_rwlockattr_t attr;
1695 pthread_rwlockattr_init(&attr);
1697 #ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
1698 pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP);
1701 return pthread_rwlock_init(prwlock, &attr);
1704 static inline int ast_rwlock_destroy(ast_rwlock_t *prwlock)
1706 return pthread_rwlock_destroy(prwlock);
1709 static inline int ast_rwlock_unlock(ast_rwlock_t *prwlock)
1711 return pthread_rwlock_unlock(prwlock);
1714 static inline int ast_rwlock_rdlock(ast_rwlock_t *prwlock)
1716 return pthread_rwlock_rdlock(prwlock);
1719 static inline int ast_rwlock_tryrdlock(ast_rwlock_t *prwlock)
1721 return pthread_rwlock_tryrdlock(prwlock);
1724 static inline int ast_rwlock_wrlock(ast_rwlock_t *prwlock)
1726 return pthread_rwlock_wrlock(prwlock);
1729 static inline int ast_rwlock_trywrlock(ast_rwlock_t *prwlock)
1731 return pthread_rwlock_trywrlock(prwlock);
1734 /* Statically declared read/write locks */
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) \
1741 ast_rwlock_init(&rwlock); \
1743 static void __attribute__ ((destructor)) fini_##rwlock(void) \
1745 ast_rwlock_destroy(&rwlock); \
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
1753 #define AST_RWLOCK_DEFINE_STATIC(rwlock) __AST_RWLOCK_DEFINE(static, rwlock)
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
1761 * The slow versions is always available, for testing purposes,
1762 * as ast_atomic_fetchadd_int_slow()
1765 int ast_atomic_fetchadd_int_slow(volatile int *p, int v);
1767 #if defined(HAVE_OSX_ATOMICS)
1768 #include "libkern/OSAtomic.h"
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.
1776 #if defined(HAVE_GCC_ATOMICS)
1777 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
1779 return __sync_fetch_and_add(p, v);
1781 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
1782 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
1784 return OSAtomicAdd32(v, (int32_t *) p);
1786 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
1787 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
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),
1794 " lock xaddl %0, %1 ; "
1795 : "+r" (v), /* 0 (result) */
1797 : "m" (*p)); /* 2 */
1800 #else /* low performance version in utils.c */
1801 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
1803 return ast_atomic_fetchadd_int_slow(p, v);
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.
1810 #if defined(HAVE_GCC_ATOMICS)
1811 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
1813 return __sync_sub_and_fetch(p, 1) == 0;
1815 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
1816 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
1818 return OSAtomicAdd32( -1, (int32_t *) p) == 0;
1820 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
1821 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
1823 return OSAtomicAdd64( -1, (int64_t *) p) == 0;
1825 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
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) */
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)
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);
1850 /*! \brief Unlock AST channel (and print debugging output)
1851 \note You need to enable DEBUG_CHANNEL_LOCKS for this function
1853 int ast_channel_unlock(struct ast_channel *chan);
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);
1863 #define AST_LIST_LOCK(head) \
1864 ast_mutex_lock(&(head)->lock)
1867 \brief Write locks a list.
1868 \param head This is a pointer to the list head structure
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
1874 #define AST_RWLIST_WRLOCK(head) \
1875 ast_rwlock_wrlock(&(head)->lock)
1878 \brief Read locks a list.
1879 \param head This is a pointer to the list head structure
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
1885 #define AST_RWLIST_RDLOCK(head) \
1886 ast_rwlock_rdlock(&(head)->lock)
1889 \brief Locks a list, without blocking if the list is locked.
1890 \param head This is a pointer to the list head structure
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
1896 #define AST_LIST_TRYLOCK(head) \
1897 ast_mutex_trylock(&(head)->lock)
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
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
1907 #define AST_RWLIST_TRYWRLOCK(head) \
1908 ast_rwlock_trywrlock(&(head)->lock)
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
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
1918 #define AST_RWLIST_TRYRDLOCK(head) \
1919 ast_rwlock_tryrdlock(&(head)->lock)
1922 \brief Attempts to unlock a list.
1923 \param head This is a pointer to the list head structure
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.
1929 #define AST_LIST_UNLOCK(head) \
1930 ast_mutex_unlock(&(head)->lock)
1933 \brief Attempts to unlock a read/write based list.
1934 \param head This is a pointer to the list head structure
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.
1940 #define AST_RWLIST_UNLOCK(head) \
1941 ast_rwlock_unlock(&(head)->lock)
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.
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.
1956 static AST_LIST_HEAD(entry_list, entry) entries;
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.
1962 #define AST_LIST_HEAD(name, type) \
1964 struct type *first; \
1965 struct type *last; \
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.
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.
1982 static AST_RWLIST_HEAD(entry_list, entry) entries;
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.
1988 #define AST_RWLIST_HEAD(name, type) \
1990 struct type *first; \
1991 struct type *last; \
1992 ast_rwlock_t lock; \
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.
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.
2008 static AST_LIST_HEAD_NOLOCK(entry_list, entry) entries;
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.
2014 #define AST_LIST_HEAD_NOLOCK(name, type) \
2016 struct type *first; \
2017 struct type *last; \
2021 \brief Defines initial values for a declaration of AST_LIST_HEAD
2023 #define AST_LIST_HEAD_INIT_VALUE { \
2026 .lock = AST_MUTEX_INIT_VALUE, \
2030 \brief Defines initial values for a declaration of AST_RWLIST_HEAD
2032 #define AST_RWLIST_HEAD_INIT_VALUE { \
2035 .lock = AST_RWLOCK_INIT_VALUE, \
2039 \brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK
2041 #define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \
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.
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.
2057 static AST_LIST_HEAD_STATIC(entry_list, entry);
2060 This would define \c struct \c entry_list, intended to hold a list of
2061 type \c struct \c entry.
2063 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
2064 #define AST_LIST_HEAD_STATIC(name, type) \
2066 struct type *first; \
2067 struct type *last; \
2070 static void __attribute__ ((constructor)) init_##name(void) \
2072 AST_LIST_HEAD_INIT(&name); \
2074 static void __attribute__ ((destructor)) fini_##name(void) \
2076 AST_LIST_HEAD_DESTROY(&name); \
2078 struct __dummy_##name
2080 #define AST_LIST_HEAD_STATIC(name, type) \
2082 struct type *first; \
2083 struct type *last; \
2085 } name = AST_LIST_HEAD_INIT_VALUE
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.
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.
2099 static AST_RWLIST_HEAD_STATIC(entry_list, entry);
2102 This would define \c struct \c entry_list, intended to hold a list of
2103 type \c struct \c entry.
2105 #ifndef AST_RWLOCK_INIT_VALUE
2106 #define AST_RWLIST_HEAD_STATIC(name, type) \
2108 struct type *first; \
2109 struct type *last; \
2110 ast_rwlock_t lock; \
2112 static void __attribute__ ((constructor)) init_##name(void) \
2114 AST_RWLIST_HEAD_INIT(&name); \
2116 static void __attribute__ ((destructor)) fini_##name(void) \
2118 AST_RWLIST_HEAD_DESTROY(&name); \
2120 struct __dummy_##name
2122 #define AST_RWLIST_HEAD_STATIC(name, type) \
2124 struct type *first; \
2125 struct type *last; \
2126 ast_rwlock_t lock; \
2127 } name = AST_RWLIST_HEAD_INIT_VALUE
2131 \brief Defines a structure to be used to hold a list of specified type, statically initialized.
2133 This is the same as AST_LIST_HEAD_STATIC, except without the lock included.
2135 #define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \
2137 struct type *first; \
2138 struct type *last; \
2139 } name = AST_LIST_HEAD_NOLOCK_INIT_VALUE
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
2146 This macro initializes a list head structure by setting the head
2147 entry to the supplied value and recreating the embedded lock.
2149 #define AST_LIST_HEAD_SET(head, entry) do { \
2150 (head)->first = (entry); \
2151 (head)->last = (entry); \
2152 ast_mutex_init(&(head)->lock); \
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
2160 This macro initializes a list head structure by setting the head
2161 entry to the supplied value and recreating the embedded lock.
2163 #define AST_RWLIST_HEAD_SET(head, entry) do { \
2164 (head)->first = (entry); \
2165 (head)->last = (entry); \
2166 ast_rwlock_init(&(head)->lock); \
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
2174 This macro initializes a list head structure by setting the head
2175 entry to the supplied value.
2177 #define AST_LIST_HEAD_SET_NOLOCK(head, entry) do { \
2178 (head)->first = (entry); \
2179 (head)->last = (entry); \
2183 \brief Declare a forward link structure inside a list entry.
2184 \param type This is the type of each list entry.
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:
2193 AST_LIST_ENTRY(list_entry) list;
2197 The field name \a list here is arbitrary, and can be anything you wish.
2199 #define AST_LIST_ENTRY(type) \
2201 struct type *next; \
2204 #define AST_RWLIST_ENTRY AST_LIST_ENTRY
2207 \brief Returns the first entry contained in a list.
2208 \param head This is a pointer to the list head structure
2210 #define AST_LIST_FIRST(head) ((head)->first)
2212 #define AST_RWLIST_FIRST AST_LIST_FIRST
2215 \brief Returns the last entry contained in a list.
2216 \param head This is a pointer to the list head structure
2218 #define AST_LIST_LAST(head) ((head)->last)
2220 #define AST_RWLIST_LAST AST_LIST_LAST
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.
2228 #define AST_LIST_NEXT(elm, field) ((elm)->field.next)
2230 #define AST_RWLIST_NEXT AST_LIST_NEXT
2233 \brief Checks whether the specified list contains any entries.
2234 \param head This is a pointer to the list head structure
2236 Returns non-zero if the list has entries, zero if not.
2238 #define AST_LIST_EMPTY(head) (AST_LIST_FIRST(head) == NULL)
2240 #define AST_RWLIST_EMPTY AST_LIST_EMPTY
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
2248 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2249 used to link entries of this list together.
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:
2255 static AST_LIST_HEAD(entry_list, list_entry) entries;
2259 AST_LIST_ENTRY(list_entry) list;
2262 struct list_entry *current;
2264 AST_LIST_TRAVERSE(&entries, current, list) {
2265 (do something with current here)
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()
2278 #define AST_LIST_TRAVERSE(head,var,field) \
2279 for((var) = (head)->first; (var); (var) = (var)->field.next)
2281 #define AST_RWLIST_TRAVERSE AST_LIST_TRAVERSE
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
2289 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2290 used to link entries of this list together.
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:
2297 static AST_LIST_HEAD(entry_list, list_entry) entries;
2301 AST_LIST_ENTRY(list_entry) list;
2304 struct list_entry *current;
2306 AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
2307 (do something with current here)
2309 AST_LIST_TRAVERSE_SAFE_END;
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.
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; \
2323 __list_prev = __new_prev, (var) = __list_next, \
2324 __new_prev = (var), \
2325 __list_next = (var) ? (var)->field.next : NULL \
2328 #define AST_RWLIST_TRAVERSE_SAFE_BEGIN AST_LIST_TRAVERSE_SAFE_BEGIN
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.
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).
2341 #define AST_LIST_REMOVE_CURRENT(head, field) \
2342 __new_prev->field.next = NULL; \
2343 __new_prev = __list_prev; \
2345 __list_prev->field.next = __list_next; \
2347 (head)->first = __list_next; \
2349 (head)->last = __list_prev;
2351 #define AST_RWLIST_REMOVE_CURRENT AST_LIST_REMOVE_CURRENT
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.
2360 \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
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; \
2368 (elm)->field.next = (head)->first; \
2369 (head)->first = (elm); \
2371 __new_prev = (elm); \
2374 #define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT
2377 \brief Closes a safe loop traversal block.
2379 #define AST_LIST_TRAVERSE_SAFE_END }
2381 #define AST_RWLIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END
2384 \brief Initializes a list head structure.
2385 \param head This is a pointer to the list head structure
2387 This macro initializes a list head structure by setting the head
2388 entry to \a NULL (empty list) and recreating the embedded lock.
2390 #define AST_LIST_HEAD_INIT(head) { \
2391 (head)->first = NULL; \
2392 (head)->last = NULL; \
2393 ast_mutex_init(&(head)->lock); \
2397 \brief Initializes an rwlist head structure.
2398 \param head This is a pointer to the list head structure
2400 This macro initializes a list head structure by setting the head
2401 entry to \a NULL (empty list) and recreating the embedded lock.
2403 #define AST_RWLIST_HEAD_INIT(head) { \
2404 (head)->first = NULL; \
2405 (head)->last = NULL; \
2406 ast_rwlock_init(&(head)->lock); \
2410 \brief Destroys a list head structure.
2411 \param head This is a pointer to the list head structure
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.
2417 #define AST_LIST_HEAD_DESTROY(head) { \
2418 (head)->first = NULL; \
2419 (head)->last = NULL; \
2420 ast_mutex_destroy(&(head)->lock); \
2424 \brief Destroys an rwlist head structure.
2425 \param head This is a pointer to the list head structure
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.
2431 #define AST_RWLIST_HEAD_DESTROY(head) { \
2432 (head)->first = NULL; \
2433 (head)->last = NULL; \
2434 ast_rwlock_destroy(&(head)->lock); \
2438 \brief Initializes a list head structure.
2439 \param head This is a pointer to the list head structure
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
2445 #define AST_LIST_HEAD_INIT_NOLOCK(head) { \
2446 (head)->first = NULL; \
2447 (head)->last = NULL; \
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
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.
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); \
2466 #define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER
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.
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); \
2482 #define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD
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.
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).
2495 #define AST_LIST_INSERT_TAIL(head, elm, field) do { \
2496 if (!(head)->first) { \
2497 (head)->first = (elm); \
2498 (head)->last = (elm); \
2500 (head)->last->field.next = (elm); \
2501 (head)->last = (elm); \
2505 #define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL
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.
2514 #define AST_LIST_APPEND_LIST(head, list, field) do { \
2515 if (!(head)->first) { \
2516 (head)->first = (list)->first; \
2517 (head)->last = (list)->last; \
2519 (head)->last->field.next = (list)->first; \
2520 (head)->last = (list)->last; \
2524 #define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST
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.
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.
2535 #define AST_LIST_REMOVE_HEAD(head, field) ({ \
2536 typeof((head)->first) cur = (head)->first; \
2538 (head)->first = cur->field.next; \
2539 cur->field.next = NULL; \
2540 if ((head)->last == cur) \
2541 (head)->last = NULL; \
2546 #define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD
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.
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; \
2562 typeof(elm) curelm = (head)->first; \
2563 while (curelm && (curelm->field.next != (elm))) \
2564 curelm = curelm->field.next; \
2566 curelm->field.next = (elm)->field.next; \
2567 if ((head)->last == (elm)) \
2568 (head)->last = curelm; \
2571 (elm)->field.next = NULL; \
2574 #define AST_RWLIST_REMOVE AST_LIST_REMOVE
2579 AST_LIST_ENTRY(ast_var_t) entries;
2584 AST_LIST_HEAD_NOLOCK(varshead, ast_var_t);
2586 AST_RWLOCK_DEFINE_STATIC(globalslock);
2587 static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
2590 /* IN CONFLICT: struct ast_var_t *ast_var_assign(const char *name, const char *value); */
2592 static struct ast_var_t *ast_var_assign(const char *name, const char *value);
2594 static void ast_var_delete(struct ast_var_t *var);
2597 #define AST_MAX_EXTENSION 80 /*!< Max length of an extension */
2601 #define PRIORITY_HINT -1 /*!< Special Priority for a hint */
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 */
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;
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);
2628 AST_LIST_ENTRY(ast_switch) list;
2629 const char *name; /*!< Name of the switch */
2630 const char *description; /*!< Description of the switch */
2632 ast_switch_f *exists;
2633 ast_switch_f *canmatch;
2635 ast_switch_f *matchmore;
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);
2651 /* stolen from callerid.c */
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.
2657 static void ast_shrink_phone_number(char *n)
2662 for (x=0; n[x]; x++) {
2681 if (!strchr("()", n[x]))
2689 /* stolen from chanvars.c */
2691 static const char *ast_var_name(const struct ast_var_t *var)
2695 if (var == NULL || (name = var->name) == NULL)
2697 /* Return the name without the initial underscores */
2698 if (name[0] == '_') {
2707 /* stolen from asterisk.c */
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 */
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 */
2721 /* Our own version of ast_log, since the expr parser uses it. -- stolen from utils/check_expr.c */
2723 static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
2728 printf("LOG: lev:%d file:%s line:%d func: %s ",
2729 level, file, line, function);
2735 static void ast_verbose(const char *fmt, ...)
2740 printf("VERBOSE: ");
2746 /* stolen from main/utils.c */
2747 static char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
2749 char *dataPut = start;
2753 for (; *start; start++) {
2755 *dataPut++ = *start; /* Always goes verbatim */
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 */
2763 /* Replace , with |, unless in quotes */
2764 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
2768 if (start != dataPut)
2773 static int ast_true(const char *s)
2775 if (ast_strlen_zero(s))
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"))
2790 /* stolen from pbx.c */
2791 #define VAR_BUF_SIZE 4096
2793 #define VAR_NORMAL 1
2794 #define VAR_SOFTTRAN 2
2795 #define VAR_HARDTRAN 3
2797 #define BACKGROUND_SKIP (1 << 0)
2798 #define BACKGROUND_NOANSWER (1 << 1)
2799 #define BACKGROUND_MATCHEXTEN (1 << 2)
2800 #define BACKGROUND_PLAYBACK (1 << 3)
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
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 */
2825 typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data);
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 */
2834 /*! \brief ast_include: include= support in extensions.conf */
2835 struct ast_include {
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 */
2845 /*! \brief ast_sw: Switch statement in extensions.conf */
2848 const char *registrar; /*!< Registrar */
2849 char *data; /*!< Data load */
2851 AST_LIST_ENTRY(ast_sw) list;
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];
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 */
2877 /*! \brief ast_app: A registered application */
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 <name>' */
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 */
2888 /*! \brief ast_state_cb: An extension state notify register item */
2889 struct ast_state_cb {
2892 ast_state_cb_type callback;
2893 struct ast_state_cb *next;
2896 /*! \brief Structure for dial plan hints
2898 \note Hints are pointers from an extension in the dialplan to one or
2899 more devices (tech/name)
2900 - See \ref AstExtState
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 */
2912 struct ast_state_cb *callbacks;
2914 AST_LIST_ENTRY(store_hint) list;
2918 AST_LIST_HEAD(store_hints, store_hint);
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" }
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
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
2949 __asm __volatile(".byte 0x0f, 0x31" : "=A" (rv));
2953 #else /* supply a dummy function on other platforms */
2954 static __inline uint64_t
2962 static struct ast_var_t *ast_var_assign(const char *name, const char *value)
2964 struct ast_var_t *var;
2965 int name_len = strlen(name) + 1;
2966 int value_len = strlen(value) + 1;
2968 if (!(var = ast_calloc(sizeof(*var) + name_len + value_len, sizeof(char)))) {
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);
2979 static void ast_var_delete(struct ast_var_t *var)
2986 /* chopped this one off at the knees! */
2987 static int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
2990 /* ast_log(LOG_ERROR, "Function %s not registered\n", function); we are not interested in the details here */
2995 static unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
2999 int paren = 0, quote = 0;
3001 if (!buf || !array || !arraylen)
3004 memset(array, 0, arraylen * sizeof(*array));
3008 for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
3010 for (; *scan; scan++) {
3013 else if (*scan == ')') {
3016 } else if (*scan == '"' && delim != '"') {
3017 quote = quote ? 0 : 1;
3018 /* Remove quote character from argument */
3019 memmove(scan, scan + 1, strlen(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) {
3032 array[argc++] = scan;
3037 static void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
3039 struct ast_var_t *newvariable;
3040 struct varshead *headp;
3041 const char *nametail = name;
3043 /* XXX may need locking on the channel ? */
3044 if (name[strlen(name)-1] == ')') {
3045 char *function = ast_strdupa(name);
3047 ast_func_write(chan, function, value);
3053 /* For comparison purposes, we have to strip leading underscores */
3054 if (*nametail == '_') {
3056 if (*nametail == '_')
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);
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);
3078 static int pbx_builtin_setvar(struct ast_channel *chan, void *data)
3080 char *name, *value, *mydata;
3082 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */
3086 if (ast_strlen_zero(data)) {
3087 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n");
3091 mydata = ast_strdupa(data);
3092 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
3094 /* check for a trailing flags argument */
3095 if ((argc > 1) && !strchr(argv[argc-1], '=')) {
3097 if (strchr(argv[argc], 'g'))
3101 for (x = 0; x < argc; x++) {
3103 if ((value = strchr(name, '='))) {
3105 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value);
3107 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name);
3113 int localized_pbx_builtin_setvar(struct ast_channel *chan, void *data);
3115 int localized_pbx_builtin_setvar(struct ast_channel *chan, void *data)
3117 return pbx_builtin_setvar(chan, data);
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.
3126 static int lookup_name(const char *s, char *const names[], int max)
3131 for (i = 0; names[i]; i++) {
3132 if (!strcasecmp(s, names[i]))
3135 } else if (sscanf(s, "%d", &i) == 1 && i >= 1 && i <= max) {
3138 return 0; /* error return */
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.
3144 static unsigned get_range(char *src, int max, char *const names[], const char *msg)
3146 int s, e; /* start and ending position */
3147 unsigned int mask = 0;
3149 /* Check for whole range */
3150 if (ast_strlen_zero(src) || !strcmp(src, "*")) {
3154 /* Get start and ending position */
3155 char *c = strchr(src, '-');
3158 /* Find the start */
3159 s = lookup_name(src, names, max);
3161 ast_log(LOG_WARNING, "Invalid %s '%s', assuming none\n", msg, src);
3165 if (c) { /* find end of range */
3166 e = lookup_name(c, names, max);
3168 ast_log(LOG_WARNING, "Invalid end %s '%s', assuming none\n", msg, c);
3175 /* Fill the mask. Remember that ranges are cyclic */
3176 mask = 1 << e; /* initialize with last element */
3189 /*! \brief store a bitmask of valid times, one bit each 2 minute */
3190 static void get_timerange(struct ast_timing *i, char *times)
3198 /* start disabling all times, fill the fields with 0's, as they may contain garbage */
3199 memset(i->minmask, 0, sizeof(i->minmask));
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 */
3208 /* Otherwise expect a range */
3209 e = strchr(times, '-');
3211 ast_log(LOG_WARNING, "Time range is not valid. Assuming no restrictions based on time.\n");
3215 /* XXX why skip non digits ? */
3216 while (*e && !isdigit(*e))
3219 ast_log(LOG_WARNING, "Invalid time range. Assuming no restrictions based on time.\n");
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);
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);
3230 /* XXX this needs to be optimized */
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);
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);
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));
3246 /* Do the last one */
3247 i->minmask[x/30] |= (1 << (x % 30));
3249 for (cth=0; cth<24; cth++) {
3250 /* Initialize masks to blank */
3251 i->minmask[cth] = 0;
3252 for (ctm=0; ctm<30; ctm++) {
3254 /* First hour with more than one hour */
3255 (((cth == s1) && (ctm >= s2)) &&
3258 || (((cth == s1) && (ctm >= s2)) &&
3259 ((cth == e1) && (ctm <= e2)))
3260 /* In between first and last hours (more than 2 hours) */
3263 /* Last hour with more than one hour */
3265 ((cth == e1) && (ctm <= e2)))
3267 i->minmask[cth] |= (1 << (ctm / 2));
3275 static void null_datad(void *foo)
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)
3282 struct ast_config_engine *eng, *ret = NULL;
3283 struct ast_config_map *map;
3286 for (map = config_maps; map; map = map->next) {
3287 if (!strcasecmp(family, map->name)) {
3289 ast_copy_string(database, map->database, dbsiz);
3291 ast_copy_string(table, map->table ? map->table : family, tabsiz);
3296 /* Check if the required driver (engine) exist */
3298 for (eng = config_engine_list; !ret && eng; eng = eng->next) {
3299 if (!strcasecmp(eng->name, map->driver))
3305 /* if we found a mapping, but the engine is not available, then issue a warning */
3307 ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
3312 struct ast_category *ast_config_get_current_category(const struct ast_config *cfg);
3314 struct ast_category *ast_config_get_current_category(const struct ast_config *cfg)
3316 return cfg->current;
3319 static struct ast_category *ast_category_new(const char *name, const char *in_file, int lineno);
3321 static struct ast_category *ast_category_new(const char *name, const char *in_file, int lineno)
3323 struct ast_category *category;
3325 if ((category = ast_calloc(1, sizeof(*category))))
3326 ast_copy_string(category->name, name, sizeof(category->name));
3327 category->file = strdup(in_file);
3328 category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
3332 struct ast_category *localized_category_get(const struct ast_config *config, const char *category_name);
3334 struct ast_category *localized_category_get(const struct ast_config *config, const char *category_name)
3336 return category_get(config, category_name, 0);
3339 static void move_variables(struct ast_category *old, struct ast_category *new)
3341 struct ast_variable *var = old->root;
3344 /* we can just move the entire list in a single op */
3345 ast_variable_append(new, var);
3348 struct ast_variable *next = var->next;
3350 ast_variable_append(new, var);
3356 static void inherit_category(struct ast_category *new, const struct ast_category *base)
3358 struct ast_variable *var;
3360 for (var = base->root; var; var = var->next)
3361 ast_variable_append(new, variable_clone(var));
3364 static void ast_category_append(struct ast_config *config, struct ast_category *category);
3366 static void ast_category_append(struct ast_config *config, struct ast_category *category)
3369 config->last->next = category;
3371 config->root = category;
3372 config->last = category;
3373 config->current = category;
3376 static void ast_category_destroy(struct ast_category *cat);
3378 static void ast_category_destroy(struct ast_category *cat)
3380 ast_variables_destroy(cat->root);
3387 static struct ast_config_engine text_file_engine = {
3389 .load_func = config_text_file_load,
3393 static struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_incl_file);
3395 static struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_incl_file)
3399 struct ast_config_engine *loader = &text_file_engine;
3400 struct ast_config *result;
3402 if (cfg->include_level == cfg->max_include_level) {
3403 ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
3407 cfg->include_level++;
3408 /* silence is golden!
3409 ast_log(LOG_WARNING, "internal loading file %s level=%d\n", filename, cfg->include_level);
3412 if (strcmp(filename, extconfig_conf) && strcmp(filename, "asterisk.conf") && config_engine_list) {
3413 struct ast_config_engine *eng;
3415 eng = find_engine(filename, db, sizeof(db), table, sizeof(table));
3418 if (eng && eng->load_func) {
3421 eng = find_engine("global", db, sizeof(db), table, sizeof(table));
3422 if (eng && eng->load_func)
3427 result = loader->load_func(db, table, filename, cfg, withcomments, suggested_incl_file);
3428 /* silence is golden
3429 ast_log(LOG_WARNING, "finished internal loading file %s level=%d\n", filename, cfg->include_level);
3433 result->include_level--;
3439 static int process_text_line(struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, int withcomments, const char *suggested_include_file)
3443 struct ast_variable *v;
3444 char cmd[512], exec_file[512];
3445 int object, do_exec, do_include;
3447 /* Actually parse the entry */
3448 if (cur[0] == '[') {
3449 struct ast_category *newcat = NULL;
3452 /* A category header */
3453 c = strchr(cur, ']');
3455 ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
3463 if (!(*cat = newcat = ast_category_new(catname, ast_strlen_zero(suggested_include_file)?configfile:suggested_include_file, lineno))) {
3466 (*cat)->lineno = lineno;
3469 if (withcomments && comment_buffer && comment_buffer[0] ) {
3470 newcat->precomments = ALLOC_COMMENT(comment_buffer);
3472 if (withcomments && lline_buffer && lline_buffer[0] ) {
3473 newcat->sameline = ALLOC_COMMENT(lline_buffer);
3478 /* If there are options or categories to inherit from, process them now */
3480 if (!(cur = strchr(c, ')'))) {
3481 ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
3485 while ((cur = strsep(&c, ","))) {
3486 if (!strcasecmp(cur, "!")) {
3487 (*cat)->ignored = 1;
3488 } else if (!strcasecmp(cur, "+")) {
3489 *cat = category_get(cfg, catname, 1);
3491 ast_config_destroy(cfg);
3493 ast_category_destroy(newcat);
3494 ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
3498 move_variables(newcat, *cat);
3499 ast_category_destroy(newcat);
3503 struct ast_category *base;
3505 base = category_get(cfg, cur, 1);
3507 ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
3510 inherit_category(*cat, base);
3515 ast_category_append(cfg, *cat);
3516 } else if (cur[0] == '#') {
3520 while(*c && (*c > 32)) c++;
3523 /* Find real argument */
3524 c = ast_skip_blanks(c + 1);
3529 do_include = !strcasecmp(cur, "include");
3531 do_exec = !strcasecmp(cur, "exec");
3534 if (do_exec && !ast_opt_exec_includes) {
3535 ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
3538 if (do_include || do_exec) {
3541 char real_inclusion_name[256];
3542 struct ast_config_include *inclu;
3544 /* Strip off leading and trailing "'s and <>'s */
3545 while((*c == '<') || (*c == '>') || (*c == '\"')) c++;
3546 /* Get rid of leading mess */
3549 while (!ast_strlen_zero(cur)) {
3550 c = cur + strlen(cur) - 1;
3551 if ((*c == '>') || (*c == '<') || (*c == '\"'))
3556 /* #exec </path/to/executable>
3557 We create a tmp file, then we #include it, then we delete it. */
3559 snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d.%ld", (int)time(NULL), (long)pthread_self());
3560 snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file);
3561 ast_safe_system(cmd);
3564 exec_file[0] = '\0';
3566 /* ast_log(LOG_WARNING, "Reading in included file %s withcomments=%d\n", cur, withcomments); */
3568 /* record this inclusion */
3569 inclu = ast_include_new(cfg, configfile, cur, do_exec, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name));
3571 do_include = ast_config_internal_load(cur, cfg, withcomments, real_inclusion_name) ? 1 : 0;
3572 if(!ast_strlen_zero(exec_file))
3576 /* ast_log(LOG_WARNING, "Done reading in included file %s withcomments=%d\n", cur, withcomments); */
3579 ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n",
3580 do_exec ? "exec" : "include",
3581 do_exec ? "/path/to/executable" : "filename",
3587 ast_log(LOG_WARNING, "Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile);
3589 /* Just a line (variable = value) */
3591 ast_log(LOG_WARNING,
3592 "parse error: No category context for line %d of %s\n", lineno, configfile);
3595 c = strchr(cur, '=');
3599 /* Ignore > in => */
3605 if ((v = ast_variable_new(ast_strip(cur), ast_strip(c), configfile))) {
3608 /* Put and reset comments */
3610 ast_variable_append(*cat, v);
3612 if (withcomments && comment_buffer && comment_buffer[0] ) {
3613 v->precomments = ALLOC_COMMENT(comment_buffer);
3615 if (withcomments && lline_buffer && lline_buffer[0] ) {
3616 v->sameline = ALLOC_COMMENT(lline_buffer);
3625 ast_log(LOG_WARNING, "EXTENSIONS.CONF: No '=' (equal sign) in line %d of %s\n", lineno, configfile);
3631 static int use_local_dir = 1;
3633 void localized_use_local_dir(void);
3634 void localized_use_conf_dir(void);
3636 void localized_use_local_dir(void)
3641 void localized_use_conf_dir(void)
3647 static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_include_file)
3651 char *new_buf, *comment_p, *process_buf;
3654 int comment = 0, nest[MAX_NESTED_COMMENTS];
3655 struct ast_category *cat = NULL;
3657 struct stat statbuf;
3659 cat = ast_config_get_current_category(cfg);
3661 if (filename[0] == '/') {
3662 ast_copy_string(fn, filename, sizeof(fn));
3665 snprintf(fn, sizeof(fn), "./%s", filename);
3667 snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, filename);
3670 if (withcomments && cfg && cfg->include_level < 2 ) {
3674 #ifdef AST_INCLUDE_GLOB
3679 globbuf.gl_offs = 0; /* initialize it to silence gcc */
3681 glob_ret = glob(fn, GLOB_NOCHECK, NULL, &globbuf);
3683 glob_ret = glob(fn, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf);
3685 if (glob_ret == GLOB_NOSPACE)
3686 ast_log(LOG_WARNING,
3687 "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
3688 else if (glob_ret == GLOB_ABORTED)
3689 ast_log(LOG_WARNING,
3690 "Glob Expansion of pattern '%s' failed: Read error\n", fn);
3692 /* loop over expanded files */
3694 for (i=0; i<globbuf.gl_pathc; i++) {
3695 ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn));
3698 if (stat(fn, &statbuf))
3701 if (!S_ISREG(statbuf.st_mode)) {
3702 ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
3705 if (option_verbose > 1) {
3706 ast_verbose(VERBOSE_PREFIX_2 "Parsing '%s': ", fn);
3709 if (!(f = fopen(fn, "r"))) {
3711 ast_log(LOG_DEBUG, "No file to parse: %s\n", fn);
3712 if (option_verbose > 1)
3713 ast_verbose( "Not found (%s)\n", strerror(errno));
3718 ast_log(LOG_DEBUG, "Parsing %s\n", fn);
3719 if (option_verbose > 1)
3720 ast_verbose("Found\n");
3723 if (fgets(buf, sizeof(buf), f)) {
3724 if ( withcomments ) {
3725 CB_ADD(lline_buffer); /* add the current lline buffer to the comment buffer */
3726 lline_buffer[0] = 0; /* erase the lline buffer */
3735 while ((comment_p = strchr(new_buf, COMMENT_META))) {
3736 if ((comment_p > new_buf) && (*(comment_p-1) == '\\')) {
3737 /* Yuck, gotta memmove */
3738 memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
3739 new_buf = comment_p;
3740 } else if(comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) {
3741 /* Meta-Comment start detected ";--" */
3742 if (comment < MAX_NESTED_COMMENTS) {