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/compat.h"
32 #include <sys/types.h>
34 #include <sys/resource.h>
40 #if !defined(SOLARIS) && !defined(__CYGWIN__)
47 #include <sys/param.h>
48 #define ASINCLUDE_GLOB 1
49 #ifdef AST_INCLUDE_GLOB
50 #if defined(__Darwin__) || defined(__CYGWIN__)
51 #define GLOB_ABORTED GLOB_ABEND
56 static char ast_config_AST_CONFIG_DIR[PATH_MAX] = {"/etc/asterisk"};
57 #define AST_API_MODULE 1 /* gimme the inline defs! */
60 char x; /* basically empty! */
65 #include "asterisk/inline_api.h"
66 #include "asterisk/endian.h"
67 #include "asterisk/ast_expr.h"
68 #include "asterisk/ael_structs.h"
69 #include "asterisk/pval.h"
72 #define EVENTLOG "event_log"
73 #define QUEUELOG "queue_log"
75 #define DEBUG_M(a) { \
79 #define VERBOSE_PREFIX_1 " "
80 #define VERBOSE_PREFIX_2 " == "
81 #define VERBOSE_PREFIX_3 " -- "
82 #define VERBOSE_PREFIX_4 " > "
84 /* IN CONFLICT: void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
85 __attribute__ ((format (printf, 5, 6))); */
87 static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__ ((format (printf,5,6)));
90 void ast_backtrace(void);
92 void ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt, ...)
93 __attribute__ ((format (printf, 5, 6)));
95 /* IN CONFLICT: void ast_verbose(const char *fmt, ...)
96 __attribute__ ((format (printf, 1, 2))); */
98 int ast_register_verbose(void (*verboser)(const char *string));
99 int ast_unregister_verbose(void (*verboser)(const char *string));
101 void ast_console_puts(const char *string);
103 void ast_console_puts_mutable(const char *string);
104 void ast_console_toggle_mute(int fd);
106 #define _A_ __FILE__, __LINE__, __PRETTY_FUNCTION__
111 #define __LOG_DEBUG 0
112 #define LOG_DEBUG __LOG_DEBUG, _A_
117 #define __LOG_EVENT 1
118 #define LOG_EVENT __LOG_EVENT, _A_
123 #define __LOG_NOTICE 2
124 #define LOG_NOTICE __LOG_NOTICE, _A_
129 #define __LOG_WARNING 3
130 #define LOG_WARNING __LOG_WARNING, _A_
135 #define __LOG_ERROR 4
136 #define LOG_ERROR __LOG_ERROR, _A_
141 #define __LOG_VERBOSE 5
142 #define LOG_VERBOSE __LOG_VERBOSE, _A_
148 #define LOG_DTMF __LOG_DTMF, _A_
152 static unsigned int __unsigned_int_flags_dummy;
154 struct ast_flags { /* stolen from utils.h */
157 #define ast_test_flag(p,flag) ({ \
158 typeof ((p)->flags) __p = (p)->flags; \
159 typeof (__unsigned_int_flags_dummy) __x = 0; \
160 (void) (&__p == &__x); \
161 ((p)->flags & (flag)); \
164 #define ast_set2_flag(p,value,flag) do { \
165 typeof ((p)->flags) __p = (p)->flags; \
166 typeof (__unsigned_int_flags_dummy) __x = 0; \
167 (void) (&__p == &__x); \
169 (p)->flags |= (flag); \
171 (p)->flags &= ~(flag); \
175 #ifdef __AST_DEBUG_MALLOC
176 static void ast_free(void *ptr) attribute_unused;
177 static void ast_free(void *ptr)
182 #define ast_free free
185 #ifndef __AST_DEBUG_MALLOC
187 #define MALLOC_FAILURE_MSG \
188 ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
190 * \brief A wrapper for malloc()
192 * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
193 * message in the case that the allocation fails.
195 * The argument and return value are the same as malloc()
197 #define ast_malloc(len) \
198 _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
201 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
205 if (!(p = malloc(len)))
213 * \brief A wrapper for calloc()
215 * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
216 * message in the case that the allocation fails.
218 * The arguments and return value are the same as calloc()
220 #define ast_calloc(num, len) \
221 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
224 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
228 if (!(p = calloc(num, len)))
236 * \brief A wrapper for calloc() for use in cache pools
238 * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
239 * message in the case that the allocation fails. When memory debugging is in use,
240 * the memory allocated by this function will be marked as 'cache' so it can be
241 * distinguished from normal memory allocations.
243 * The arguments and return value are the same as calloc()
245 #define ast_calloc_cache(num, len) \
246 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
249 * \brief A wrapper for realloc()
251 * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
252 * message in the case that the allocation fails.
254 * The arguments and return value are the same as realloc()
256 #define ast_realloc(p, len) \
257 _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
260 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
264 if (!(newp = realloc(p, len)))
272 * \brief A wrapper for strdup()
274 * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
275 * message in the case that the allocation fails.
277 * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
278 * argument is provided, ast_strdup will return NULL without generating any
279 * kind of error log message.
281 * The argument and return value are the same as strdup()
283 #define ast_strdup(str) \
284 _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
287 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
292 if (!(newstr = strdup(str)))
301 * \brief A wrapper for strndup()
303 * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
304 * message in the case that the allocation fails.
306 * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
307 * string to duplicate. If a NULL argument is provided, ast_strdup will return
308 * NULL without generating any kind of error log message.
310 * The arguments and return value are the same as strndup()
312 #define ast_strndup(str, len) \
313 _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
316 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
321 if (!(newstr = strndup(str, len)))
330 * \brief A wrapper for asprintf()
332 * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
333 * message in the case that the allocation fails.
335 * The arguments and return value are the same as asprintf()
337 #define ast_asprintf(ret, fmt, ...) \
338 _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
341 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...),
347 if ((res = vasprintf(ret, fmt, ap)) == -1)
356 * \brief A wrapper for vasprintf()
358 * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
359 * message in the case that the allocation fails.
361 * The arguments and return value are the same as vasprintf()
363 #define ast_vasprintf(ret, fmt, ap) \
364 _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
367 int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
371 if ((res = vasprintf(ret, fmt, ap)) == -1)
380 /* If astmm is in use, let it handle these. Otherwise, it will report that
381 all allocations are coming from this header file */
383 #define ast_malloc(a) malloc(a)
384 #define ast_calloc(a,b) calloc(a,b)
385 #define ast_realloc(a,b) realloc(a,b)
386 #define ast_strdup(a) strdup(a)
387 #define ast_strndup(a,b) strndup(a,b)
388 #define ast_asprintf(a,b,c) asprintf(a,b,c)
389 #define ast_vasprintf(a,b,c) vasprintf(a,b,c)
391 #endif /* AST_DEBUG_MALLOC */
393 #if !defined(ast_strdupa) && defined(__GNUC__)
395 \brief duplicate a string in memory from the stack
396 \param s The string to duplicate
398 This macro will duplicate the given string. It returns a pointer to the stack
399 allocatted memory for the new string.
401 #define ast_strdupa(s) \
404 const char *__old = (s); \
405 size_t __len = strlen(__old) + 1; \
406 char *__new = __builtin_alloca(__len); \
407 memcpy (__new, __old, __len); \
415 #define MAX_NESTED_COMMENTS 128
416 #define COMMENT_START ";--"
417 #define COMMENT_END "--;"
418 #define COMMENT_META ';'
419 #define COMMENT_TAG '-'
421 static char *extconfig_conf = "extconfig.conf";
423 /*! Growable string buffer */
424 static char *comment_buffer; /*!< this will be a comment collector.*/
425 static int comment_buffer_size; /*!< the amount of storage so far alloc'd for the comment_buffer */
427 static char *lline_buffer; /*!< A buffer for stuff behind the ; */
428 static int lline_buffer_size;
433 struct ast_comment *next;
437 static void CB_INIT(void)
439 if (!comment_buffer) {
440 comment_buffer = ast_malloc(CB_INCR);
443 comment_buffer[0] = 0;
444 comment_buffer_size = CB_INCR;
445 lline_buffer = ast_malloc(CB_INCR);
449 lline_buffer_size = CB_INCR;
451 comment_buffer[0] = 0;
456 static void CB_ADD(char *str)
458 int rem = comment_buffer_size - strlen(comment_buffer) - 1;
459 int siz = strlen(str);
461 comment_buffer = ast_realloc(comment_buffer, comment_buffer_size + CB_INCR + siz + 1);
464 comment_buffer_size += CB_INCR+siz+1;
466 strcat(comment_buffer,str);
469 static void CB_ADD_LEN(char *str, int len)
471 int cbl = strlen(comment_buffer) + 1;
472 int rem = comment_buffer_size - cbl;
474 comment_buffer = ast_realloc(comment_buffer, comment_buffer_size + CB_INCR + len + 1);
477 comment_buffer_size += CB_INCR+len+1;
479 strncat(comment_buffer,str,len);
480 comment_buffer[cbl+len-1] = 0;
483 static void LLB_ADD(char *str)
485 int rem = lline_buffer_size - strlen(lline_buffer) - 1;
486 int siz = strlen(str);
488 lline_buffer = ast_realloc(lline_buffer, lline_buffer_size + CB_INCR + siz + 1);
491 lline_buffer_size += CB_INCR + siz + 1;
493 strcat(lline_buffer,str);
496 static void CB_RESET(void )
498 comment_buffer[0] = 0;
502 /*! \brief Keep track of how many threads are currently trying to wait*() on
504 static unsigned int safe_system_level = 0;
505 static void *safe_system_prev_handler;
507 /*! \brief NULL handler so we can collect the child exit status */
508 static void null_sig_handler(int signal)
513 void ast_replace_sigchld(void);
515 void ast_replace_sigchld(void)
519 level = safe_system_level++;
521 /* only replace the handler if it has not already been done */
523 safe_system_prev_handler = signal(SIGCHLD, null_sig_handler);
527 void ast_unreplace_sigchld(void);
529 void ast_unreplace_sigchld(void)
533 level = --safe_system_level;
535 /* only restore the handler if we are the last one */
537 signal(SIGCHLD, safe_system_prev_handler);
541 int ast_safe_system(const char *s);
543 int ast_safe_system(const char *s)
546 #ifdef HAVE_WORKING_FORK
550 struct rusage rusage;
553 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
554 ast_replace_sigchld();
556 #ifdef HAVE_WORKING_FORK
563 #ifdef HAVE_WORKING_FORK
564 /* Close file descriptors and launch system command */
565 for (x = STDERR_FILENO + 1; x < 4096; x++)
568 execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
570 } else if (pid > 0) {
572 res = wait4(pid, &status, 0, &rusage);
574 res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
576 } else if (errno != EINTR)
580 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
584 ast_unreplace_sigchld();
592 static struct ast_comment *ALLOC_COMMENT(const char *buffer)
594 struct ast_comment *x = ast_calloc(1,sizeof(struct ast_comment)+strlen(buffer)+1);
595 strcpy(x->cmt, buffer);
599 static struct ast_config_map {
600 struct ast_config_map *next;
606 } *config_maps = NULL;
608 static struct ast_config_engine *config_engine_list;
610 #define MAX_INCLUDE_LEVEL 10
613 struct ast_category {
615 int ignored; /*!< do not let user of the config see this category */
617 char *file; /*!< the file name from whence this declaration was read */
619 struct ast_comment *precomments;
620 struct ast_comment *sameline;
621 struct ast_variable *root;
622 struct ast_variable *last;
623 struct ast_category *next;
627 struct ast_category *root;
628 struct ast_category *last;
629 struct ast_category *current;
630 struct ast_category *last_browse; /*!< used to cache the last category supplied via category_browse */
632 int max_include_level;
633 struct ast_config_include *includes; /*!< a list of inclusions, which should describe the entire tree */
636 struct ast_config_include {
637 char *include_location_file; /*!< file name in which the include occurs */
638 int include_location_lineno; /*!< lineno where include occurred */
639 int exec; /*!< set to non-zero if itsa #exec statement */
640 char *exec_file; /*!< if it's an exec, you'll have both the /var/tmp to read, and the original script */
641 char *included_file; /*!< file name included */
642 int inclusion_count; /*!< if the file is included more than once, a running count thereof -- but, worry not,
643 we explode the instances and will include those-- so all entries will be unique */
644 int output; /*!< a flag to indicate if the inclusion has been output */
645 struct ast_config_include *next; /*!< ptr to next inclusion in the list */
648 typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, int withcomments, const char *suggested_include_file);
649 typedef struct ast_variable *realtime_var_get(const char *database, const char *table, va_list ap);
650 typedef struct ast_config *realtime_multi_get(const char *database, const char *table, va_list ap);
651 typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
653 /*! \brief Configuration engine structure, used to define realtime drivers */
654 struct ast_config_engine {
656 config_load_func *load_func;
657 realtime_var_get *realtime_func;
658 realtime_multi_get *realtime_multi_func;
659 realtime_update *update_func;
660 struct ast_config_engine *next;
663 static struct ast_config_engine *config_engine_list;
665 /* taken from strings.h */
667 static force_inline int ast_strlen_zero(const char *s)
669 return (!s || (*s == '\0'));
672 #define S_OR(a, b) (!ast_strlen_zero(a) ? (a) : (b))
675 void ast_copy_string(char *dst, const char *src, size_t size),
677 while (*src && size) {
681 if (__builtin_expect(!size, 0))
688 char *ast_skip_blanks(const char *str),
690 while (*str && *str < 33)
697 \brief Trims trailing whitespace characters from a string.
698 \param ast_trim_blanks function being used
699 \param str the input string
700 \return a pointer to the modified string
703 char *ast_trim_blanks(char *str),
708 work += strlen(work) - 1;
709 /* It's tempting to only want to erase after we exit this loop,
710 but since ast_trim_blanks *could* receive a constant string
711 (which we presumably wouldn't have to touch), we shouldn't
712 actually set anything unless we must, and it's easier just
713 to set each position to \0 than to keep track of a variable
715 while ((work >= str) && *work < 33)
723 \brief Strip leading/trailing whitespace from a string.
724 \param s The string to be stripped (will be modified).
725 \return The stripped string.
727 This functions strips all leading and trailing whitespace
728 characters from the input string, and returns a pointer to
729 the resulting string. The string is modified in place.
732 char *ast_strip(char *s),
734 s = ast_skip_blanks(s);
744 struct ast_variable {
749 int object; /*!< 0 for variable, 1 for object */
750 int blanklines; /*!< Number of blanklines following entry */
751 struct ast_comment *precomments;
752 struct ast_comment *sameline;
753 struct ast_variable *next;
757 static const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable);
758 static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_include_file);
760 struct ast_config *localized_config_load_with_comments(const char *filename);
761 static char *ast_category_browse(struct ast_config *config, const char *prev);
762 static struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category);
763 static void ast_variables_destroy(struct ast_variable *v);
764 static void ast_config_destroy(struct ast_config *cfg);
765 static struct ast_config_include *ast_include_new(struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size);
766 static struct ast_config_include *ast_include_find(struct ast_config *conf, const char *included_file);
767 void localized_ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file);
769 static struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename);
771 static struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename)
773 struct ast_variable *variable;
774 int name_len = strlen(name) + 1;
776 if ((variable = ast_calloc(1, name_len + strlen(value) + 1 + strlen(filename) + 1 + sizeof(*variable)))) {
777 variable->name = variable->stuff;
778 variable->value = variable->stuff + name_len;
779 variable->file = variable->value + strlen(value) + 1;
780 strcpy(variable->name,name);
781 strcpy(variable->value,value);
782 strcpy(variable->file,filename);
788 static struct ast_config_include *ast_include_new(struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size)
790 /* a file should be included ONCE. Otherwise, if one of the instances is changed,
791 then all be changed. -- how do we know to include it? -- Handling modified
792 instances is possible, I'd have
793 to create a new master for each instance. */
794 struct ast_config_include *inc;
796 inc = ast_include_find(conf, included_file);
799 inc->inclusion_count++;
800 snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count);
801 ast_log(LOG_WARNING,"'%s', line %d: Same File included more than once! This data will be saved in %s if saved back to disk.\n", from_file, from_lineno, real_included_file_name);
803 *real_included_file_name = 0;
805 inc = ast_calloc(1,sizeof(struct ast_config_include));
806 inc->include_location_file = ast_strdup(from_file);
807 inc->include_location_lineno = from_lineno;
808 if (!ast_strlen_zero(real_included_file_name))
809 inc->included_file = ast_strdup(real_included_file_name);
811 inc->included_file = ast_strdup(included_file);
815 inc->exec_file = ast_strdup(exec_file);
817 /* attach this new struct to the conf struct */
818 inc->next = conf->includes;
819 conf->includes = inc;
824 void localized_ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
826 struct ast_config_include *incl;
827 struct ast_category *cat;
828 struct ast_variable *v;
830 int from_len = strlen(from_file);
831 int to_len = strlen(to_file);
833 if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */
836 /* the manager code allows you to read in one config file, then
837 write it back out under a different name. But, the new arrangement
838 ties output lines to the file name. So, before you try to write
839 the config file to disk, better riffle thru the data and make sure
840 the file names are changed.
842 /* file names are on categories, includes (of course), and on variables. So,
843 traverse all this and swap names */
845 for (incl = conf->includes; incl; incl=incl->next) {
846 if (strcmp(incl->include_location_file,from_file) == 0) {
847 if (from_len >= to_len)
848 strcpy(incl->include_location_file, to_file);
850 free(incl->include_location_file);
851 incl->include_location_file = strdup(to_file);
855 for (cat = conf->root; cat; cat = cat->next) {
856 if (strcmp(cat->file,from_file) == 0) {
857 if (from_len >= to_len)
858 strcpy(cat->file, to_file);
861 cat->file = strdup(to_file);
864 for (v = cat->root; v; v = v->next) {
865 if (strcmp(v->file,from_file) == 0) {
866 if (from_len >= to_len)
867 strcpy(v->file, to_file);
870 v->file = strdup(to_file);
877 static struct ast_config_include *ast_include_find(struct ast_config *conf, const char *included_file)
879 struct ast_config_include *x;
880 for (x=conf->includes;x;x=x->next)
882 if (strcmp(x->included_file,included_file) == 0)
889 static void ast_variable_append(struct ast_category *category, struct ast_variable *variable);
891 static void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
896 category->last->next = variable;
898 category->root = variable;
899 category->last = variable;
900 while (category->last->next)
901 category->last = category->last->next;
904 static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored);
906 static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored)
908 struct ast_category *cat;
910 /* try exact match first, then case-insensitive match */
911 for (cat = config->root; cat; cat = cat->next) {
912 if (cat->name == category_name && (ignored || !cat->ignored))
916 for (cat = config->root; cat; cat = cat->next) {
917 if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored))
924 static struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name)
926 return category_get(config, category_name, 0);
929 static struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category)
931 struct ast_category *cat = NULL;
933 if (category && config->last_browse && (config->last_browse->name == category))
934 cat = config->last_browse;
936 cat = ast_category_get(config, category);
938 return (cat) ? cat->root : NULL;
941 static const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
943 struct ast_variable *v;
946 for (v = ast_variable_browse(config, category); v; v = v->next) {
947 if (!strcasecmp(variable, v->name))
951 struct ast_category *cat;
953 for (cat = config->root; cat; cat = cat->next)
954 for (v = cat->root; v; v = v->next)
955 if (!strcasecmp(variable, v->name))
962 static struct ast_variable *variable_clone(const struct ast_variable *old)
964 struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
967 new->lineno = old->lineno;
968 new->object = old->object;
969 new->blanklines = old->blanklines;
970 /* TODO: clone comments? */
976 static void ast_variables_destroy(struct ast_variable *v)
978 struct ast_variable *vn;
987 static void ast_includes_destroy(struct ast_config_include *incls)
989 struct ast_config_include *incl,*inclnext;
991 for (incl=incls; incl; incl = inclnext) {
992 inclnext = incl->next;
993 if (incl->include_location_file)
994 free(incl->include_location_file);
996 free(incl->exec_file);
997 if (incl->included_file)
998 free(incl->included_file);
1003 static void ast_config_destroy(struct ast_config *cfg)
1005 struct ast_category *cat, *catn;
1010 ast_includes_destroy(cfg->includes);
1014 ast_variables_destroy(cat->root);
1023 /* options.h declars ast_options extern; I need it static? */
1025 #define AST_CACHE_DIR_LEN 512
1026 #define AST_FILENAME_MAX 80
1028 /*! \ingroup main_options */
1029 enum ast_option_flags {
1030 /*! Allow \#exec in config files */
1031 AST_OPT_FLAG_EXEC_INCLUDES = (1 << 0),
1032 /*! Do not fork() */
1033 AST_OPT_FLAG_NO_FORK = (1 << 1),
1035 AST_OPT_FLAG_QUIET = (1 << 2),
1037 AST_OPT_FLAG_CONSOLE = (1 << 3),
1038 /*! Run in realtime Linux priority */
1039 AST_OPT_FLAG_HIGH_PRIORITY = (1 << 4),
1040 /*! Initialize keys for RSA authentication */
1041 AST_OPT_FLAG_INIT_KEYS = (1 << 5),
1042 /*! Remote console */
1043 AST_OPT_FLAG_REMOTE = (1 << 6),
1044 /*! Execute an asterisk CLI command upon startup */
1045 AST_OPT_FLAG_EXEC = (1 << 7),
1046 /*! Don't use termcap colors */
1047 AST_OPT_FLAG_NO_COLOR = (1 << 8),
1048 /*! Are we fully started yet? */
1049 AST_OPT_FLAG_FULLY_BOOTED = (1 << 9),
1050 /*! Trascode via signed linear */
1051 AST_OPT_FLAG_TRANSCODE_VIA_SLIN = (1 << 10),
1052 /*! Enable priority jumping in applications */
1053 AST_OPT_FLAG_PRIORITY_JUMPING = (1 << 11),
1054 /*! Dump core on a seg fault */
1055 AST_OPT_FLAG_DUMP_CORE = (1 << 12),
1056 /*! Cache sound files */
1057 AST_OPT_FLAG_CACHE_RECORD_FILES = (1 << 13),
1058 /*! Display timestamp in CLI verbose output */
1059 AST_OPT_FLAG_TIMESTAMP = (1 << 14),
1060 /*! Override config */
1061 AST_OPT_FLAG_OVERRIDE_CONFIG = (1 << 15),
1063 AST_OPT_FLAG_RECONNECT = (1 << 16),
1064 /*! Transmit Silence during Record() */
1065 AST_OPT_FLAG_TRANSMIT_SILENCE = (1 << 17),
1066 /*! Suppress some warnings */
1067 AST_OPT_FLAG_DONT_WARN = (1 << 18),
1068 /*! End CDRs before the 'h' extension */
1069 AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN = (1 << 19),
1070 /*! Use Zaptel Timing for generators if available */
1071 AST_OPT_FLAG_INTERNAL_TIMING = (1 << 20),
1072 /*! Always fork, even if verbose or debug settings are non-zero */
1073 AST_OPT_FLAG_ALWAYS_FORK = (1 << 21),
1074 /*! Disable log/verbose output to remote consoles */
1075 AST_OPT_FLAG_MUTE = (1 << 22)
1078 /*! These are the options that set by default when Asterisk starts */
1079 #define AST_DEFAULT_OPTIONS AST_OPT_FLAG_TRANSCODE_VIA_SLIN
1081 #define ast_opt_exec_includes ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES)
1082 #define ast_opt_no_fork ast_test_flag(&ast_options, AST_OPT_FLAG_NO_FORK)
1083 #define ast_opt_quiet ast_test_flag(&ast_options, AST_OPT_FLAG_QUIET)
1084 #define ast_opt_console ast_test_flag(&ast_options, AST_OPT_FLAG_CONSOLE)
1085 #define ast_opt_high_priority ast_test_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY)
1086 #define ast_opt_init_keys ast_test_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS)
1087 #define ast_opt_remote ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)
1088 #define ast_opt_exec ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC)
1089 #define ast_opt_no_color ast_test_flag(&ast_options, AST_OPT_FLAG_NO_COLOR)
1090 #define ast_fully_booted ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)
1091 #define ast_opt_transcode_via_slin ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN)
1092 #define ast_opt_priority_jumping ast_test_flag(&ast_options, AST_OPT_FLAG_PRIORITY_JUMPING)
1093 #define ast_opt_dump_core ast_test_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE)
1094 #define ast_opt_cache_record_files ast_test_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES)
1095 #define ast_opt_timestamp ast_test_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP)
1096 #define ast_opt_override_config ast_test_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG)
1097 #define ast_opt_reconnect ast_test_flag(&ast_options, AST_OPT_FLAG_RECONNECT)
1098 #define ast_opt_transmit_silence ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE)
1099 #define ast_opt_dont_warn ast_test_flag(&ast_options, AST_OPT_FLAG_DONT_WARN)
1100 #define ast_opt_end_cdr_before_h_exten ast_test_flag(&ast_options, AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN)
1101 #define ast_opt_internal_timing ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING)
1102 #define ast_opt_always_fork ast_test_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK)
1103 #define ast_opt_mute ast_test_flag(&ast_options, AST_OPT_FLAG_MUTE)
1105 /* IN CONFLICT: extern int option_verbose; */
1106 /* IN CONFLICT: extern int option_debug; */ /*!< Debugging */
1107 extern int option_maxcalls; /*!< Maximum number of simultaneous channels */
1108 extern double option_maxload;
1109 extern char defaultlanguage[];
1111 extern time_t ast_startuptime;
1112 extern time_t ast_lastreloadtime;
1113 extern pid_t ast_mainpid;
1115 extern char record_cache_dir[AST_CACHE_DIR_LEN];
1116 extern char debug_filename[AST_FILENAME_MAX];
1118 extern int ast_language_is_prefix;
1124 #ifndef HAVE_MTX_PROFILE
1125 #define __MTX_PROF(a) return pthread_mutex_lock((a))
1127 #define __MTX_PROF(a) do { \
1129 /* profile only non-blocking events */ \
1130 ast_mark(mtx_prof, 1); \
1131 i = pthread_mutex_trylock((a)); \
1132 ast_mark(mtx_prof, 0); \
1136 return pthread_mutex_lock((a)); \
1138 #endif /* HAVE_MTX_PROFILE */
1140 #define AST_PTHREADT_NULL (pthread_t) -1
1141 #define AST_PTHREADT_STOP (pthread_t) -2
1143 #if defined(SOLARIS) || defined(BSD)
1144 #define AST_MUTEX_INIT_W_CONSTRUCTORS
1145 #endif /* SOLARIS || BSD */
1147 /* Asterisk REQUIRES recursive (not error checking) mutexes
1148 and will not run without them. */
1149 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) && defined(PTHREAD_MUTEX_RECURSIVE_NP)
1150 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
1151 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
1153 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_MUTEX_INITIALIZER
1154 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
1155 #endif /* PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
1157 #ifdef DEBUG_THREADS
1159 #define __ast_mutex_logger(...) do { if (canlog) ast_log(LOG_ERROR, __VA_ARGS__); else fprintf(stderr, __VA_ARGS__); } while (0)
1162 #define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
1164 #define DO_THREAD_CRASH do { } while (0)
1167 #define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, { NULL }, { 0 }, 0, { NULL }, { 0 } }
1169 #define AST_MAX_REENTRANCY 10
1171 struct ast_mutex_info {
1172 pthread_mutex_t mutex;
1173 /*! Track which thread holds this lock */
1174 unsigned int track:1;
1175 const char *file[AST_MAX_REENTRANCY];
1176 int lineno[AST_MAX_REENTRANCY];
1178 const char *func[AST_MAX_REENTRANCY];
1179 pthread_t thread[AST_MAX_REENTRANCY];
1182 typedef struct ast_mutex_info ast_mutex_t;
1184 typedef pthread_cond_t ast_cond_t;
1186 static pthread_mutex_t empty_mutex;
1188 static void __attribute__((constructor)) init_empty_mutex(void)
1190 memset(&empty_mutex, 0, sizeof(empty_mutex));
1193 static inline int __ast_pthread_mutex_init_attr(const char *filename, int lineno, const char *func,
1194 const char *mutex_name, ast_mutex_t *t,
1195 pthread_mutexattr_t *attr)
1197 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
1198 int canlog = strcmp(filename, "logger.c");
1200 if ((t->mutex) != ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
1201 if ((t->mutex) != (empty_mutex)) {
1202 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is already initialized.\n",
1203 filename, lineno, func, mutex_name);
1204 __ast_mutex_logger("%s line %d (%s): Error: previously initialization of mutex '%s'.\n",
1205 t->file[0], t->lineno[0], t->func[0], mutex_name);
1212 t->file[0] = filename;
1213 t->lineno[0] = lineno;
1218 return pthread_mutex_init(&t->mutex, attr);
1221 static inline int __ast_pthread_mutex_init(const char *filename, int lineno, const char *func,
1222 const char *mutex_name, ast_mutex_t *t)
1224 static pthread_mutexattr_t attr;
1226 pthread_mutexattr_init(&attr);
1227 pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
1229 return __ast_pthread_mutex_init_attr(filename, lineno, func, mutex_name, t, &attr);
1231 #define ast_mutex_init(pmutex) __ast_pthread_mutex_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
1233 static inline int __ast_pthread_mutex_destroy(const char *filename, int lineno, const char *func,
1234 const char *mutex_name, ast_mutex_t *t)
1237 int canlog = strcmp(filename, "logger.c");
1239 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
1240 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
1241 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
1242 filename, lineno, func, mutex_name);
1246 res = pthread_mutex_trylock(&t->mutex);
1249 pthread_mutex_unlock(&t->mutex);
1252 __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy invalid mutex '%s'.\n",
1253 filename, lineno, func, mutex_name);
1256 __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy locked mutex '%s'.\n",
1257 filename, lineno, func, mutex_name);
1258 __ast_mutex_logger("%s line %d (%s): Error: '%s' was locked here.\n",
1259 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
1263 if ((res = pthread_mutex_destroy(&t->mutex)))
1264 __ast_mutex_logger("%s line %d (%s): Error destroying mutex: %s\n",
1265 filename, lineno, func, strerror(res));
1266 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
1268 t->mutex = PTHREAD_MUTEX_INIT_VALUE;
1270 t->file[0] = filename;
1271 t->lineno[0] = lineno;
1277 static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func,
1278 const char* mutex_name, ast_mutex_t *t)
1281 int canlog = strcmp(filename, "logger.c");
1283 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
1284 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
1285 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
1286 filename, lineno, func, mutex_name);
1289 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
1291 #ifdef DETECT_DEADLOCKS
1293 time_t seconds = time(NULL);
1296 #ifdef HAVE_MTX_PROFILE
1297 ast_mark(mtx_prof, 1);
1299 res = pthread_mutex_trylock(&t->mutex);
1300 #ifdef HAVE_MTX_PROFILE
1301 ast_mark(mtx_prof, 0);
1304 current = time(NULL);
1305 if ((current - seconds) && (!((current - seconds) % 5))) {
1306 __ast_mutex_logger("%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n",
1307 filename, lineno, func, (int)(current - seconds), mutex_name);
1308 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
1309 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
1310 t->func[t->reentrancy-1], mutex_name);
1314 } while (res == EBUSY);
1317 #ifdef HAVE_MTX_PROFILE
1318 ast_mark(mtx_prof, 1);
1319 res = pthread_mutex_trylock(&t->mutex);
1320 ast_mark(mtx_prof, 0);
1323 res = pthread_mutex_lock(&t->mutex);
1324 #endif /* DETECT_DEADLOCKS */
1327 if (t->reentrancy < AST_MAX_REENTRANCY) {
1328 t->file[t->reentrancy] = filename;
1329 t->lineno[t->reentrancy] = lineno;
1330 t->func[t->reentrancy] = func;
1331 t->thread[t->reentrancy] = pthread_self();
1334 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
1335 filename, lineno, func, mutex_name);
1338 __ast_mutex_logger("%s line %d (%s): Error obtaining mutex: %s\n",
1339 filename, lineno, func, strerror(errno));
1346 static inline int __ast_pthread_mutex_trylock(const char *filename, int lineno, const char *func,
1347 const char* mutex_name, ast_mutex_t *t)
1350 int canlog = strcmp(filename, "logger.c");
1352 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
1353 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
1354 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
1355 filename, lineno, func, mutex_name);
1358 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
1360 if (!(res = pthread_mutex_trylock(&t->mutex))) {
1361 if (t->reentrancy < AST_MAX_REENTRANCY) {
1362 t->file[t->reentrancy] = filename;
1363 t->lineno[t->reentrancy] = lineno;
1364 t->func[t->reentrancy] = func;
1365 t->thread[t->reentrancy] = pthread_self();
1368 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
1369 filename, lineno, func, mutex_name);
1372 __ast_mutex_logger("%s line %d (%s): Warning: '%s' was locked here.\n",
1373 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
1379 static inline int __ast_pthread_mutex_unlock(const char *filename, int lineno, const char *func,
1380 const char *mutex_name, ast_mutex_t *t)
1383 int canlog = strcmp(filename, "logger.c");
1385 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
1386 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
1387 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
1388 filename, lineno, func, mutex_name);
1392 if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
1393 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
1394 filename, lineno, func, mutex_name);
1395 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
1396 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
1400 if (--t->reentrancy < 0) {
1401 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
1402 filename, lineno, func, mutex_name);
1406 if (t->reentrancy < AST_MAX_REENTRANCY) {
1407 t->file[t->reentrancy] = NULL;
1408 t->lineno[t->reentrancy] = 0;
1409 t->func[t->reentrancy] = NULL;
1410 t->thread[t->reentrancy] = 0;
1413 if ((res = pthread_mutex_unlock(&t->mutex))) {
1414 __ast_mutex_logger("%s line %d (%s): Error releasing mutex: %s\n",
1415 filename, lineno, func, strerror(res));
1422 static inline int __ast_cond_init(const char *filename, int lineno, const char *func,
1423 const char *cond_name, ast_cond_t *cond, pthread_condattr_t *cond_attr)
1425 return pthread_cond_init(cond, cond_attr);
1428 static inline int __ast_cond_signal(const char *filename, int lineno, const char *func,
1429 const char *cond_name, ast_cond_t *cond)
1431 return pthread_cond_signal(cond);
1434 static inline int __ast_cond_broadcast(const char *filename, int lineno, const char *func,
1435 const char *cond_name, ast_cond_t *cond)
1437 return pthread_cond_broadcast(cond);
1440 static inline int __ast_cond_destroy(const char *filename, int lineno, const char *func,
1441 const char *cond_name, ast_cond_t *cond)
1443 return pthread_cond_destroy(cond);
1446 static inline int __ast_cond_wait(const char *filename, int lineno, const char *func,
1447 const char *cond_name, const char *mutex_name,
1448 ast_cond_t *cond, ast_mutex_t *t)
1451 int canlog = strcmp(filename, "logger.c");
1453 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
1454 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
1455 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
1456 filename, lineno, func, mutex_name);
1460 if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
1461 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
1462 filename, lineno, func, mutex_name);
1463 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
1464 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
1468 if (--t->reentrancy < 0) {
1469 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
1470 filename, lineno, func, mutex_name);
1474 if (t->reentrancy < AST_MAX_REENTRANCY) {
1475 t->file[t->reentrancy] = NULL;
1476 t->lineno[t->reentrancy] = 0;
1477 t->func[t->reentrancy] = NULL;
1478 t->thread[t->reentrancy] = 0;
1481 if ((res = pthread_cond_wait(cond, &t->mutex))) {
1482 __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n",
1483 filename, lineno, func, strerror(res));
1486 if (t->reentrancy < AST_MAX_REENTRANCY) {
1487 t->file[t->reentrancy] = filename;
1488 t->lineno[t->reentrancy] = lineno;
1489 t->func[t->reentrancy] = func;
1490 t->thread[t->reentrancy] = pthread_self();
1493 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
1494 filename, lineno, func, mutex_name);
1501 static inline int __ast_cond_timedwait(const char *filename, int lineno, const char *func,
1502 const char *cond_name, const char *mutex_name, ast_cond_t *cond,
1503 ast_mutex_t *t, const struct timespec *abstime)
1506 int canlog = strcmp(filename, "logger.c");
1508 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
1509 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
1510 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
1511 filename, lineno, func, mutex_name);
1515 if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
1516 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
1517 filename, lineno, func, mutex_name);
1518 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
1519 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
1523 if (--t->reentrancy < 0) {
1524 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
1525 filename, lineno, func, mutex_name);
1529 if (t->reentrancy < AST_MAX_REENTRANCY) {
1530 t->file[t->reentrancy] = NULL;
1531 t->lineno[t->reentrancy] = 0;
1532 t->func[t->reentrancy] = NULL;
1533 t->thread[t->reentrancy] = 0;
1536 if ((res = pthread_cond_timedwait(cond, &t->mutex, abstime)) && (res != ETIMEDOUT)) {
1537 __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n",
1538 filename, lineno, func, strerror(res));
1541 if (t->reentrancy < AST_MAX_REENTRANCY) {
1542 t->file[t->reentrancy] = filename;
1543 t->lineno[t->reentrancy] = lineno;
1544 t->func[t->reentrancy] = func;
1545 t->thread[t->reentrancy] = pthread_self();
1548 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
1549 filename, lineno, func, mutex_name);
1556 #define ast_mutex_destroy(a) __ast_pthread_mutex_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
1557 #define ast_mutex_lock(a) __ast_pthread_mutex_lock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
1558 #define ast_mutex_unlock(a) __ast_pthread_mutex_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
1559 #define ast_mutex_trylock(a) __ast_pthread_mutex_trylock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
1560 #define ast_cond_init(cond, attr) __ast_cond_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond, attr)
1561 #define ast_cond_destroy(cond) __ast_cond_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
1562 #define ast_cond_signal(cond) __ast_cond_signal(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
1563 #define ast_cond_broadcast(cond) __ast_cond_broadcast(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
1564 #define ast_cond_wait(cond, mutex) __ast_cond_wait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex)
1565 #define ast_cond_timedwait(cond, mutex, time) __ast_cond_timedwait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex, time)
1567 #else /* !DEBUG_THREADS */
1570 typedef pthread_mutex_t ast_mutex_t;
1572 #define AST_MUTEX_INIT_VALUE ((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
1574 static inline int ast_mutex_init(ast_mutex_t *pmutex)
1576 pthread_mutexattr_t attr;
1578 pthread_mutexattr_init(&attr);
1579 pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
1581 return pthread_mutex_init(pmutex, &attr);
1584 #define ast_pthread_mutex_init(pmutex,a) pthread_mutex_init(pmutex,a)
1586 static inline int ast_mutex_unlock(ast_mutex_t *pmutex)
1588 return pthread_mutex_unlock(pmutex);
1591 static inline int ast_mutex_destroy(ast_mutex_t *pmutex)
1593 return pthread_mutex_destroy(pmutex);
1596 static inline int ast_mutex_lock(ast_mutex_t *pmutex)
1601 static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
1603 return pthread_mutex_trylock(pmutex);
1606 typedef pthread_cond_t ast_cond_t;
1608 static inline int ast_cond_init(ast_cond_t *cond, pthread_condattr_t *cond_attr)
1610 return pthread_cond_init(cond, cond_attr);
1613 static inline int ast_cond_signal(ast_cond_t *cond)
1615 return pthread_cond_signal(cond);
1618 static inline int ast_cond_broadcast(ast_cond_t *cond)
1620 return pthread_cond_broadcast(cond);
1623 static inline int ast_cond_destroy(ast_cond_t *cond)
1625 return pthread_cond_destroy(cond);
1628 static inline int ast_cond_wait(ast_cond_t *cond, ast_mutex_t *t)
1630 return pthread_cond_wait(cond, t);
1633 static inline int ast_cond_timedwait(ast_cond_t *cond, ast_mutex_t *t, const struct timespec *abstime)
1635 return pthread_cond_timedwait(cond, t, abstime);
1638 #endif /* !DEBUG_THREADS */
1640 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
1641 /* If AST_MUTEX_INIT_W_CONSTRUCTORS is defined, use file scope
1642 constructors/destructors to create/destroy mutexes. */
1643 #define __AST_MUTEX_DEFINE(scope, mutex) \
1644 scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE; \
1645 static void __attribute__ ((constructor)) init_##mutex(void) \
1647 ast_mutex_init(&mutex); \
1649 static void __attribute__ ((destructor)) fini_##mutex(void) \
1651 ast_mutex_destroy(&mutex); \
1653 #else /* !AST_MUTEX_INIT_W_CONSTRUCTORS */
1654 /* By default, use static initialization of mutexes. */
1655 #define __AST_MUTEX_DEFINE(scope, mutex) \
1656 scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE
1657 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
1659 #define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
1660 #define pthread_mutex_lock use_ast_mutex_lock_instead_of_pthread_mutex_lock
1661 #define pthread_mutex_unlock use_ast_mutex_unlock_instead_of_pthread_mutex_unlock
1662 #define pthread_mutex_trylock use_ast_mutex_trylock_instead_of_pthread_mutex_trylock
1663 #define pthread_mutex_init use_ast_mutex_init_instead_of_pthread_mutex_init
1664 #define pthread_mutex_destroy use_ast_mutex_destroy_instead_of_pthread_mutex_destroy
1665 #define pthread_cond_t use_ast_cond_t_instead_of_pthread_cond_t
1666 #define pthread_cond_init use_ast_cond_init_instead_of_pthread_cond_init
1667 #define pthread_cond_destroy use_ast_cond_destroy_instead_of_pthread_cond_destroy
1668 #define pthread_cond_signal use_ast_cond_signal_instead_of_pthread_cond_signal
1669 #define pthread_cond_broadcast use_ast_cond_broadcast_instead_of_pthread_cond_broadcast
1670 #define pthread_cond_wait use_ast_cond_wait_instead_of_pthread_cond_wait
1671 #define pthread_cond_timedwait use_ast_cond_timedwait_instead_of_pthread_cond_timedwait
1673 #define AST_MUTEX_DEFINE_STATIC(mutex) __AST_MUTEX_DEFINE(static, mutex)
1675 #define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
1677 #define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
1680 #define pthread_create __use_ast_pthread_create_instead__
1683 typedef pthread_rwlock_t ast_rwlock_t;
1685 static inline int ast_rwlock_init(ast_rwlock_t *prwlock)
1687 pthread_rwlockattr_t attr;
1689 pthread_rwlockattr_init(&attr);
1691 #ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
1692 pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP);
1695 return pthread_rwlock_init(prwlock, &attr);
1698 static inline int ast_rwlock_destroy(ast_rwlock_t *prwlock)
1700 return pthread_rwlock_destroy(prwlock);
1703 static inline int ast_rwlock_unlock(ast_rwlock_t *prwlock)
1705 return pthread_rwlock_unlock(prwlock);
1708 static inline int ast_rwlock_rdlock(ast_rwlock_t *prwlock)
1710 return pthread_rwlock_rdlock(prwlock);
1713 static inline int ast_rwlock_tryrdlock(ast_rwlock_t *prwlock)
1715 return pthread_rwlock_tryrdlock(prwlock);
1718 static inline int ast_rwlock_wrlock(ast_rwlock_t *prwlock)
1720 return pthread_rwlock_wrlock(prwlock);
1723 static inline int ast_rwlock_trywrlock(ast_rwlock_t *prwlock)
1725 return pthread_rwlock_trywrlock(prwlock);
1728 /* Statically declared read/write locks */
1730 #ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER
1731 #define __AST_RWLOCK_DEFINE(scope, rwlock) \
1732 scope ast_rwlock_t rwlock; \
1733 static void __attribute__ ((constructor)) init_##rwlock(void) \
1735 ast_rwlock_init(&rwlock); \
1737 static void __attribute__ ((destructor)) fini_##rwlock(void) \
1739 ast_rwlock_destroy(&rwlock); \
1742 #define AST_RWLOCK_INIT_VALUE PTHREAD_RWLOCK_INITIALIZER
1743 #define __AST_RWLOCK_DEFINE(scope, rwlock) \
1744 scope ast_rwlock_t rwlock = AST_RWLOCK_INIT_VALUE
1747 #define AST_RWLOCK_DEFINE_STATIC(rwlock) __AST_RWLOCK_DEFINE(static, rwlock)
1750 * Initial support for atomic instructions.
1751 * For platforms that have it, use the native cpu instruction to
1752 * implement them. For other platforms, resort to a 'slow' version
1753 * (defined in utils.c) that protects the atomic instruction with
1755 * The slow versions is always available, for testing purposes,
1756 * as ast_atomic_fetchadd_int_slow()
1759 int ast_atomic_fetchadd_int_slow(volatile int *p, int v);
1761 #if defined(HAVE_OSX_ATOMICS)
1762 #include "libkern/OSAtomic.h"
1765 /*! \brief Atomically add v to *p and return * the previous value of *p.
1766 * This can be used to handle reference counts, and the return value
1767 * can be used to generate unique identifiers.
1770 #if defined(HAVE_GCC_ATOMICS)
1771 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
1773 return __sync_fetch_and_add(p, v);
1775 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
1776 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
1778 return OSAtomicAdd32(v, (int32_t *) p);
1780 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
1781 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
1783 return OSAtomicAdd64(v, (int64_t *) p);
1784 #elif defined (__i386__) || defined(__x86_64__)
1785 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
1788 " lock xaddl %0, %1 ; "
1789 : "+r" (v), /* 0 (result) */
1791 : "m" (*p)); /* 2 */
1794 #else /* low performance version in utils.c */
1795 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
1797 return ast_atomic_fetchadd_int_slow(p, v);
1801 /*! \brief decrement *p by 1 and return true if the variable has reached 0.
1802 * Useful e.g. to check if a refcount has reached 0.
1804 #if defined(HAVE_GCC_ATOMICS)
1805 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
1807 return __sync_sub_and_fetch(p, 1) == 0;
1809 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
1810 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
1812 return OSAtomicAdd32( -1, (int32_t *) p) == 0;
1814 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
1815 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
1817 return OSAtomicAdd64( -1, (int64_t *) p) == 0;
1819 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
1821 int a = ast_atomic_fetchadd_int(p, -1);
1822 return a == 1; /* true if the value is 0 now (so it was 1 previously) */
1826 #ifndef DEBUG_CHANNEL_LOCKS
1827 /*! \brief Lock a channel. If DEBUG_CHANNEL_LOCKS is defined
1828 in the Makefile, print relevant output for debugging */
1829 #define ast_channel_lock(x) ast_mutex_lock(&x->lock)
1830 /*! \brief Unlock a channel. If DEBUG_CHANNEL_LOCKS is defined
1831 in the Makefile, print relevant output for debugging */
1832 #define ast_channel_unlock(x) ast_mutex_unlock(&x->lock)
1833 /*! \brief Try locking a channel. If DEBUG_CHANNEL_LOCKS is defined
1834 in the Makefile, print relevant output for debugging */
1835 #define ast_channel_trylock(x) ast_mutex_trylock(&x->lock)
1838 /*! \brief Lock AST channel (and print debugging output)
1839 \note You need to enable DEBUG_CHANNEL_LOCKS for this function */
1840 int ast_channel_lock(struct ast_channel *chan);
1842 /*! \brief Unlock AST channel (and print debugging output)
1843 \note You need to enable DEBUG_CHANNEL_LOCKS for this function
1845 int ast_channel_unlock(struct ast_channel *chan);
1847 /*! \brief Lock AST channel (and print debugging output)
1848 \note You need to enable DEBUG_CHANNEL_LOCKS for this function */
1849 int ast_channel_trylock(struct ast_channel *chan);
1855 #define AST_LIST_LOCK(head) \
1856 ast_mutex_lock(&(head)->lock)
1859 \brief Write locks a list.
1860 \param head This is a pointer to the list head structure
1862 This macro attempts to place an exclusive write lock in the
1863 list head structure pointed to by head.
1864 Returns non-zero on success, 0 on failure
1866 #define AST_RWLIST_WRLOCK(head) \
1867 ast_rwlock_wrlock(&(head)->lock)
1870 \brief Read locks a list.
1871 \param head This is a pointer to the list head structure
1873 This macro attempts to place a read lock in the
1874 list head structure pointed to by head.
1875 Returns non-zero on success, 0 on failure
1877 #define AST_RWLIST_RDLOCK(head) \
1878 ast_rwlock_rdlock(&(head)->lock)
1881 \brief Locks a list, without blocking if the list is locked.
1882 \param head This is a pointer to the list head structure
1884 This macro attempts to place an exclusive lock in the
1885 list head structure pointed to by head.
1886 Returns non-zero on success, 0 on failure
1888 #define AST_LIST_TRYLOCK(head) \
1889 ast_mutex_trylock(&(head)->lock)
1892 \brief Write locks a list, without blocking if the list is locked.
1893 \param head This is a pointer to the list head structure
1895 This macro attempts to place an exclusive write lock in the
1896 list head structure pointed to by head.
1897 Returns non-zero on success, 0 on failure
1899 #define AST_RWLIST_TRYWRLOCK(head) \
1900 ast_rwlock_trywrlock(&(head)->lock)
1903 \brief Read locks a list, without blocking if the list is locked.
1904 \param head This is a pointer to the list head structure
1906 This macro attempts to place a read lock in the
1907 list head structure pointed to by head.
1908 Returns non-zero on success, 0 on failure
1910 #define AST_RWLIST_TRYRDLOCK(head) \
1911 ast_rwlock_tryrdlock(&(head)->lock)
1914 \brief Attempts to unlock a list.
1915 \param head This is a pointer to the list head structure
1917 This macro attempts to remove an exclusive lock from the
1918 list head structure pointed to by head. If the list
1919 was not locked by this thread, this macro has no effect.
1921 #define AST_LIST_UNLOCK(head) \
1922 ast_mutex_unlock(&(head)->lock)
1925 \brief Attempts to unlock a read/write based list.
1926 \param head This is a pointer to the list head structure
1928 This macro attempts to remove a read or write lock from the
1929 list head structure pointed to by head. If the list
1930 was not locked by this thread, this macro has no effect.
1932 #define AST_RWLIST_UNLOCK(head) \
1933 ast_rwlock_unlock(&(head)->lock)
1936 \brief Defines a structure to be used to hold a list of specified type.
1937 \param name This will be the name of the defined structure.
1938 \param type This is the type of each list entry.
1940 This macro creates a structure definition that can be used
1941 to hold a list of the entries of type \a type. It does not actually
1942 declare (allocate) a structure; to do that, either follow this
1943 macro with the desired name of the instance you wish to declare,
1944 or use the specified \a name to declare instances elsewhere.
1948 static AST_LIST_HEAD(entry_list, entry) entries;
1951 This would define \c struct \c entry_list, and declare an instance of it named
1952 \a entries, all intended to hold a list of type \c struct \c entry.
1954 #define AST_LIST_HEAD(name, type) \
1956 struct type *first; \
1957 struct type *last; \
1962 \brief Defines a structure to be used to hold a read/write list of specified type.
1963 \param name This will be the name of the defined structure.
1964 \param type This is the type of each list entry.
1966 This macro creates a structure definition that can be used
1967 to hold a list of the entries of type \a type. It does not actually
1968 declare (allocate) a structure; to do that, either follow this
1969 macro with the desired name of the instance you wish to declare,
1970 or use the specified \a name to declare instances elsewhere.
1974 static AST_RWLIST_HEAD(entry_list, entry) entries;
1977 This would define \c struct \c entry_list, and declare an instance of it named
1978 \a entries, all intended to hold a list of type \c struct \c entry.
1980 #define AST_RWLIST_HEAD(name, type) \
1982 struct type *first; \
1983 struct type *last; \
1984 ast_rwlock_t lock; \
1988 \brief Defines a structure to be used to hold a list of specified type (with no lock).
1989 \param name This will be the name of the defined structure.
1990 \param type This is the type of each list entry.
1992 This macro creates a structure definition that can be used
1993 to hold a list of the entries of type \a type. It does not actually
1994 declare (allocate) a structure; to do that, either follow this
1995 macro with the desired name of the instance you wish to declare,
1996 or use the specified \a name to declare instances elsewhere.
2000 static AST_LIST_HEAD_NOLOCK(entry_list, entry) entries;
2003 This would define \c struct \c entry_list, and declare an instance of it named
2004 \a entries, all intended to hold a list of type \c struct \c entry.
2006 #define AST_LIST_HEAD_NOLOCK(name, type) \
2008 struct type *first; \
2009 struct type *last; \
2013 \brief Defines initial values for a declaration of AST_LIST_HEAD
2015 #define AST_LIST_HEAD_INIT_VALUE { \
2018 .lock = AST_MUTEX_INIT_VALUE, \
2022 \brief Defines initial values for a declaration of AST_RWLIST_HEAD
2024 #define AST_RWLIST_HEAD_INIT_VALUE { \
2027 .lock = AST_RWLOCK_INIT_VALUE, \
2031 \brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK
2033 #define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \
2039 \brief Defines a structure to be used to hold a list of specified type, statically initialized.
2040 \param name This will be the name of the defined structure.
2041 \param type This is the type of each list entry.
2043 This macro creates a structure definition that can be used
2044 to hold a list of the entries of type \a type, and allocates an instance
2045 of it, initialized to be empty.
2049 static AST_LIST_HEAD_STATIC(entry_list, entry);
2052 This would define \c struct \c entry_list, intended to hold a list of
2053 type \c struct \c entry.
2055 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
2056 #define AST_LIST_HEAD_STATIC(name, type) \
2058 struct type *first; \
2059 struct type *last; \
2062 static void __attribute__ ((constructor)) init_##name(void) \
2064 AST_LIST_HEAD_INIT(&name); \
2066 static void __attribute__ ((destructor)) fini_##name(void) \
2068 AST_LIST_HEAD_DESTROY(&name); \
2070 struct __dummy_##name
2072 #define AST_LIST_HEAD_STATIC(name, type) \
2074 struct type *first; \
2075 struct type *last; \
2077 } name = AST_LIST_HEAD_INIT_VALUE
2081 \brief Defines a structure to be used to hold a read/write list of specified type, statically initialized.
2082 \param name This will be the name of the defined structure.
2083 \param type This is the type of each list entry.
2085 This macro creates a structure definition that can be used
2086 to hold a list of the entries of type \a type, and allocates an instance
2087 of it, initialized to be empty.
2091 static AST_RWLIST_HEAD_STATIC(entry_list, entry);
2094 This would define \c struct \c entry_list, intended to hold a list of
2095 type \c struct \c entry.
2097 #ifndef AST_RWLOCK_INIT_VALUE
2098 #define AST_RWLIST_HEAD_STATIC(name, type) \
2100 struct type *first; \
2101 struct type *last; \
2102 ast_rwlock_t lock; \
2104 static void __attribute__ ((constructor)) init_##name(void) \
2106 AST_RWLIST_HEAD_INIT(&name); \
2108 static void __attribute__ ((destructor)) fini_##name(void) \
2110 AST_RWLIST_HEAD_DESTROY(&name); \
2112 struct __dummy_##name
2114 #define AST_RWLIST_HEAD_STATIC(name, type) \
2116 struct type *first; \
2117 struct type *last; \
2118 ast_rwlock_t lock; \
2119 } name = AST_RWLIST_HEAD_INIT_VALUE
2123 \brief Defines a structure to be used to hold a list of specified type, statically initialized.
2125 This is the same as AST_LIST_HEAD_STATIC, except without the lock included.
2127 #define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \
2129 struct type *first; \
2130 struct type *last; \
2131 } name = AST_LIST_HEAD_NOLOCK_INIT_VALUE
2134 \brief Initializes a list head structure with a specified first entry.
2135 \param head This is a pointer to the list head structure
2136 \param entry pointer to the list entry that will become the head of the list
2138 This macro initializes a list head structure by setting the head
2139 entry to the supplied value and recreating the embedded lock.
2141 #define AST_LIST_HEAD_SET(head, entry) do { \
2142 (head)->first = (entry); \
2143 (head)->last = (entry); \
2144 ast_mutex_init(&(head)->lock); \
2148 \brief Initializes an rwlist head structure with a specified first entry.
2149 \param head This is a pointer to the list head structure
2150 \param entry pointer to the list entry that will become the head of the list
2152 This macro initializes a list head structure by setting the head
2153 entry to the supplied value and recreating the embedded lock.
2155 #define AST_RWLIST_HEAD_SET(head, entry) do { \
2156 (head)->first = (entry); \
2157 (head)->last = (entry); \
2158 ast_rwlock_init(&(head)->lock); \
2162 \brief Initializes a list head structure with a specified first entry.
2163 \param head This is a pointer to the list head structure
2164 \param entry pointer to the list entry that will become the head of the list
2166 This macro initializes a list head structure by setting the head
2167 entry to the supplied value.
2169 #define AST_LIST_HEAD_SET_NOLOCK(head, entry) do { \
2170 (head)->first = (entry); \
2171 (head)->last = (entry); \
2175 \brief Declare a forward link structure inside a list entry.
2176 \param type This is the type of each list entry.
2178 This macro declares a structure to be used to link list entries together.
2179 It must be used inside the definition of the structure named in
2180 \a type, as follows:
2185 AST_LIST_ENTRY(list_entry) list;
2189 The field name \a list here is arbitrary, and can be anything you wish.
2191 #define AST_LIST_ENTRY(type) \
2193 struct type *next; \
2196 #define AST_RWLIST_ENTRY AST_LIST_ENTRY
2199 \brief Returns the first entry contained in a list.
2200 \param head This is a pointer to the list head structure
2202 #define AST_LIST_FIRST(head) ((head)->first)
2204 #define AST_RWLIST_FIRST AST_LIST_FIRST
2207 \brief Returns the last entry contained in a list.
2208 \param head This is a pointer to the list head structure
2210 #define AST_LIST_LAST(head) ((head)->last)
2212 #define AST_RWLIST_LAST AST_LIST_LAST
2215 \brief Returns the next entry in the list after the given entry.
2216 \param elm This is a pointer to the current entry.
2217 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2218 used to link entries of this list together.
2220 #define AST_LIST_NEXT(elm, field) ((elm)->field.next)
2222 #define AST_RWLIST_NEXT AST_LIST_NEXT
2225 \brief Checks whether the specified list contains any entries.
2226 \param head This is a pointer to the list head structure
2228 Returns non-zero if the list has entries, zero if not.
2230 #define AST_LIST_EMPTY(head) (AST_LIST_FIRST(head) == NULL)
2232 #define AST_RWLIST_EMPTY AST_LIST_EMPTY
2235 \brief Loops over (traverses) the entries in a list.
2236 \param head This is a pointer to the list head structure
2237 \param var This is the name of the variable that will hold a pointer to the
2238 current list entry on each iteration. It must be declared before calling
2240 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2241 used to link entries of this list together.
2243 This macro is use to loop over (traverse) the entries in a list. It uses a
2244 \a for loop, and supplies the enclosed code with a pointer to each list
2245 entry as it loops. It is typically used as follows:
2247 static AST_LIST_HEAD(entry_list, list_entry) entries;
2251 AST_LIST_ENTRY(list_entry) list;
2254 struct list_entry *current;
2256 AST_LIST_TRAVERSE(&entries, current, list) {
2257 (do something with current here)
2260 \warning If you modify the forward-link pointer contained in the \a current entry while
2261 inside the loop, the behavior will be unpredictable. At a minimum, the following
2262 macros will modify the forward-link pointer, and should not be used inside
2263 AST_LIST_TRAVERSE() against the entry pointed to by the \a current pointer without
2264 careful consideration of their consequences:
2265 \li AST_LIST_NEXT() (when used as an lvalue)
2266 \li AST_LIST_INSERT_AFTER()
2267 \li AST_LIST_INSERT_HEAD()
2268 \li AST_LIST_INSERT_TAIL()
2270 #define AST_LIST_TRAVERSE(head,var,field) \
2271 for((var) = (head)->first; (var); (var) = (var)->field.next)
2273 #define AST_RWLIST_TRAVERSE AST_LIST_TRAVERSE
2276 \brief Loops safely over (traverses) the entries in a list.
2277 \param head This is a pointer to the list head structure
2278 \param var This is the name of the variable that will hold a pointer to the
2279 current list entry on each iteration. It must be declared before calling
2281 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2282 used to link entries of this list together.
2284 This macro is used to safely loop over (traverse) the entries in a list. It
2285 uses a \a for loop, and supplies the enclosed code with a pointer to each list
2286 entry as it loops. It is typically used as follows:
2289 static AST_LIST_HEAD(entry_list, list_entry) entries;
2293 AST_LIST_ENTRY(list_entry) list;
2296 struct list_entry *current;
2298 AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
2299 (do something with current here)
2301 AST_LIST_TRAVERSE_SAFE_END;
2304 It differs from AST_LIST_TRAVERSE() in that the code inside the loop can modify
2305 (or even free, after calling AST_LIST_REMOVE_CURRENT()) the entry pointed to by
2306 the \a current pointer without affecting the loop traversal.
2308 #define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) { \
2309 typeof((head)->first) __list_next; \
2310 typeof((head)->first) __list_prev = NULL; \
2311 typeof((head)->first) __new_prev = NULL; \
2312 for ((var) = (head)->first, __new_prev = (var), \
2313 __list_next = (var) ? (var)->field.next : NULL; \
2315 __list_prev = __new_prev, (var) = __list_next, \
2316 __new_prev = (var), \
2317 __list_next = (var) ? (var)->field.next : NULL \
2320 #define AST_RWLIST_TRAVERSE_SAFE_BEGIN AST_LIST_TRAVERSE_SAFE_BEGIN
2323 \brief Removes the \a current entry from a list during a traversal.
2324 \param head This is a pointer to the list head structure
2325 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2326 used to link entries of this list together.
2328 \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
2329 block; it is used to unlink the current entry from the list without affecting
2330 the list traversal (and without having to re-traverse the list to modify the
2331 previous entry, if any).
2333 #define AST_LIST_REMOVE_CURRENT(head, field) \
2334 __new_prev->field.next = NULL; \
2335 __new_prev = __list_prev; \
2337 __list_prev->field.next = __list_next; \
2339 (head)->first = __list_next; \
2341 (head)->last = __list_prev;
2343 #define AST_RWLIST_REMOVE_CURRENT AST_LIST_REMOVE_CURRENT
2346 \brief Inserts a list entry before the current entry during a traversal.
2347 \param head This is a pointer to the list head structure
2348 \param elm This is a pointer to the entry to be inserted.
2349 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2350 used to link entries of this list together.
2352 \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
2355 #define AST_LIST_INSERT_BEFORE_CURRENT(head, elm, field) do { \
2356 if (__list_prev) { \
2357 (elm)->field.next = __list_prev->field.next; \
2358 __list_prev->field.next = elm; \
2360 (elm)->field.next = (head)->first; \
2361 (head)->first = (elm); \
2363 __new_prev = (elm); \
2366 #define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT
2369 \brief Closes a safe loop traversal block.
2371 #define AST_LIST_TRAVERSE_SAFE_END }
2373 #define AST_RWLIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END
2376 \brief Initializes a list head structure.
2377 \param head This is a pointer to the list head structure
2379 This macro initializes a list head structure by setting the head
2380 entry to \a NULL (empty list) and recreating the embedded lock.
2382 #define AST_LIST_HEAD_INIT(head) { \
2383 (head)->first = NULL; \
2384 (head)->last = NULL; \
2385 ast_mutex_init(&(head)->lock); \
2389 \brief Initializes an rwlist head structure.
2390 \param head This is a pointer to the list head structure
2392 This macro initializes a list head structure by setting the head
2393 entry to \a NULL (empty list) and recreating the embedded lock.
2395 #define AST_RWLIST_HEAD_INIT(head) { \
2396 (head)->first = NULL; \
2397 (head)->last = NULL; \
2398 ast_rwlock_init(&(head)->lock); \
2402 \brief Destroys a list head structure.
2403 \param head This is a pointer to the list head structure
2405 This macro destroys a list head structure by setting the head
2406 entry to \a NULL (empty list) and destroying the embedded lock.
2407 It does not free the structure from memory.
2409 #define AST_LIST_HEAD_DESTROY(head) { \
2410 (head)->first = NULL; \
2411 (head)->last = NULL; \
2412 ast_mutex_destroy(&(head)->lock); \
2416 \brief Destroys an rwlist head structure.
2417 \param head This is a pointer to the list head structure
2419 This macro destroys a list head structure by setting the head
2420 entry to \a NULL (empty list) and destroying the embedded lock.
2421 It does not free the structure from memory.
2423 #define AST_RWLIST_HEAD_DESTROY(head) { \
2424 (head)->first = NULL; \
2425 (head)->last = NULL; \
2426 ast_rwlock_destroy(&(head)->lock); \
2430 \brief Initializes a list head structure.
2431 \param head This is a pointer to the list head structure
2433 This macro initializes a list head structure by setting the head
2434 entry to \a NULL (empty list). There is no embedded lock handling
2437 #define AST_LIST_HEAD_INIT_NOLOCK(head) { \
2438 (head)->first = NULL; \
2439 (head)->last = NULL; \
2443 \brief Inserts a list entry after a given entry.
2444 \param head This is a pointer to the list head structure
2445 \param listelm This is a pointer to the entry after which the new entry should
2447 \param elm This is a pointer to the entry to be inserted.
2448 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2449 used to link entries of this list together.
2451 #define AST_LIST_INSERT_AFTER(head, listelm, elm, field) do { \
2452 (elm)->field.next = (listelm)->field.next; \
2453 (listelm)->field.next = (elm); \
2454 if ((head)->last == (listelm)) \
2455 (head)->last = (elm); \
2458 #define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER
2461 \brief Inserts a list entry at the head of a list.
2462 \param head This is a pointer to the list head structure
2463 \param elm This is a pointer to the entry to be inserted.
2464 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2465 used to link entries of this list together.
2467 #define AST_LIST_INSERT_HEAD(head, elm, field) do { \
2468 (elm)->field.next = (head)->first; \
2469 (head)->first = (elm); \
2470 if (!(head)->last) \
2471 (head)->last = (elm); \
2474 #define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD
2477 \brief Appends a list entry to the tail of a list.
2478 \param head This is a pointer to the list head structure
2479 \param elm This is a pointer to the entry to be appended.
2480 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2481 used to link entries of this list together.
2483 Note: The link field in the appended entry is \b not modified, so if it is
2484 actually the head of a list itself, the entire list will be appended
2485 temporarily (until the next AST_LIST_INSERT_TAIL is performed).
2487 #define AST_LIST_INSERT_TAIL(head, elm, field) do { \
2488 if (!(head)->first) { \
2489 (head)->first = (elm); \
2490 (head)->last = (elm); \
2492 (head)->last->field.next = (elm); \
2493 (head)->last = (elm); \
2497 #define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL
2500 \brief Appends a whole list to the tail of a list.
2501 \param head This is a pointer to the list head structure
2502 \param list This is a pointer to the list to be appended.
2503 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2504 used to link entries of this list together.
2506 #define AST_LIST_APPEND_LIST(head, list, field) do { \
2507 if (!(head)->first) { \
2508 (head)->first = (list)->first; \
2509 (head)->last = (list)->last; \
2511 (head)->last->field.next = (list)->first; \
2512 (head)->last = (list)->last; \
2516 #define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST
2519 \brief Removes and returns the head entry from a list.
2520 \param head This is a pointer to the list head structure
2521 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2522 used to link entries of this list together.
2524 Removes the head entry from the list, and returns a pointer to it.
2525 This macro is safe to call on an empty list.
2527 #define AST_LIST_REMOVE_HEAD(head, field) ({ \
2528 typeof((head)->first) cur = (head)->first; \
2530 (head)->first = cur->field.next; \
2531 cur->field.next = NULL; \
2532 if ((head)->last == cur) \
2533 (head)->last = NULL; \
2538 #define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD
2541 \brief Removes a specific entry from a list.
2542 \param head This is a pointer to the list head structure
2543 \param elm This is a pointer to the entry to be removed.
2544 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2545 used to link entries of this list together.
2546 \warning The removed entry is \b not freed nor modified in any way.
2548 #define AST_LIST_REMOVE(head, elm, field) do { \
2549 if ((head)->first == (elm)) { \
2550 (head)->first = (elm)->field.next; \
2551 if ((head)->last == (elm)) \
2552 (head)->last = NULL; \
2554 typeof(elm) curelm = (head)->first; \
2555 while (curelm && (curelm->field.next != (elm))) \
2556 curelm = curelm->field.next; \
2558 curelm->field.next = (elm)->field.next; \
2559 if ((head)->last == (elm)) \
2560 (head)->last = curelm; \
2563 (elm)->field.next = NULL; \
2566 #define AST_RWLIST_REMOVE AST_LIST_REMOVE
2571 AST_LIST_ENTRY(ast_var_t) entries;
2576 AST_LIST_HEAD_NOLOCK(varshead, ast_var_t);
2578 AST_RWLOCK_DEFINE_STATIC(globalslock);
2579 static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
2582 /* IN CONFLICT: struct ast_var_t *ast_var_assign(const char *name, const char *value); */
2584 static struct ast_var_t *ast_var_assign(const char *name, const char *value);
2586 static void ast_var_delete(struct ast_var_t *var);
2589 #define AST_MAX_EXTENSION 80 /*!< Max length of an extension */
2593 #define PRIORITY_HINT -1 /*!< Special Priority for a hint */
2595 enum ast_extension_states {
2596 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */
2597 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */
2598 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */
2599 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */
2600 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */
2601 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */
2602 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */
2603 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */
2606 struct ast_custom_function {
2607 const char *name; /*!< Name */
2608 const char *synopsis; /*!< Short description for "show functions" */
2609 const char *desc; /*!< Help text that explains it all */
2610 const char *syntax; /*!< Syntax description */
2611 int (*read)(struct ast_channel *, const char *, char *, char *, size_t); /*!< Read function, if read is supported */
2612 int (*write)(struct ast_channel *, const char *, char *, const char *); /*!< Write function, if write is supported */
2613 AST_RWLIST_ENTRY(ast_custom_function) acflist;
2616 typedef int (ast_switch_f)(struct ast_channel *chan, const char *context,
2617 const char *exten, int priority, const char *callerid, const char *data);
2620 AST_LIST_ENTRY(ast_switch) list;
2621 const char *name; /*!< Name of the switch */
2622 const char *description; /*!< Description of the switch */
2624 ast_switch_f *exists;
2625 ast_switch_f *canmatch;
2627 ast_switch_f *matchmore;
2631 static char *config = "extensions.conf";
2632 static char *registrar = "conf2ael";
2633 static char userscontext[AST_MAX_EXTENSION] = "default";
2634 static int static_config = 0;
2635 static int write_protect_config = 1;
2636 static int autofallthrough_config = 0;
2637 static int clearglobalvars_config = 0;
2638 /*! Go no deeper than this through includes (not counting loops) */
2639 #define AST_PBX_MAX_STACK 128
2640 static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
2643 /* stolen from callerid.c */
2645 /*! \brief Clean up phone string
2646 * remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets.
2647 * Basically, remove anything that could be invalid in a pattern.
2649 static void ast_shrink_phone_number(char *n)
2654 for (x=0; n[x]; x++) {
2673 if (!strchr("()", n[x]))
2681 /* stolen from chanvars.c */
2683 static const char *ast_var_name(const struct ast_var_t *var)
2687 if (var == NULL || (name = var->name) == NULL)
2689 /* Return the name without the initial underscores */
2690 if (name[0] == '_') {
2699 /* stolen from asterisk.c */
2701 static struct ast_flags ast_options = { AST_DEFAULT_OPTIONS };
2702 static int option_verbose = 0; /*!< Verbosity level */
2703 static int option_debug = 0; /*!< Debug level */
2706 /* experiment 1: see if it's easier just to use existing config code
2707 * to read in the extensions.conf file. In this scenario,
2708 I have to rip/copy code from other modules, because they
2709 are staticly declared as-is. A solution would be to move
2710 the ripped code to another location and make them available
2711 to other modules and standalones */
2713 /* Our own version of ast_log, since the expr parser uses it. -- stolen from utils/check_expr.c */
2715 static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
2720 printf("LOG: lev:%d file:%s line:%d func: %s ",
2721 level, file, line, function);
2727 static void ast_verbose(const char *fmt, ...)
2732 printf("VERBOSE: ");
2738 /* stolen from main/utils.c */
2739 static char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
2741 char *dataPut = start;
2745 for (; *start; start++) {
2747 *dataPut++ = *start; /* Always goes verbatim */
2750 if (*start == '\\') {
2751 inEscape = 1; /* Do not copy \ into the data */
2752 } else if (*start == '\'') {
2753 inQuotes = 1 - inQuotes; /* Do not copy ' into the data */
2755 /* Replace , with |, unless in quotes */
2756 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
2760 if (start != dataPut)
2765 static int ast_true(const char *s)
2767 if (ast_strlen_zero(s))
2770 /* Determine if this is a true value */
2771 if (!strcasecmp(s, "yes") ||
2772 !strcasecmp(s, "true") ||
2773 !strcasecmp(s, "y") ||
2774 !strcasecmp(s, "t") ||
2775 !strcasecmp(s, "1") ||
2776 !strcasecmp(s, "on"))
2782 /* stolen from pbx.c */
2783 #define VAR_BUF_SIZE 4096
2785 #define VAR_NORMAL 1
2786 #define VAR_SOFTTRAN 2
2787 #define VAR_HARDTRAN 3
2789 #define BACKGROUND_SKIP (1 << 0)
2790 #define BACKGROUND_NOANSWER (1 << 1)
2791 #define BACKGROUND_MATCHEXTEN (1 << 2)
2792 #define BACKGROUND_PLAYBACK (1 << 3)
2795 \brief ast_exten: An extension
2796 The dialplan is saved as a linked list with each context
2797 having it's own linked list of extensions - one item per
2801 char *exten; /*!< Extension name */
2802 int matchcid; /*!< Match caller id ? */
2803 const char *cidmatch; /*!< Caller id to match for this extension */
2804 int priority; /*!< Priority */
2805 const char *label; /*!< Label */
2806 struct ast_context *parent; /*!< The context this extension belongs to */
2807 const char *app; /*!< Application to execute */
2808 struct ast_app *cached_app; /*!< Cached location of application */
2809 void *data; /*!< Data to use (arguments) */
2810 void (*datad)(void *); /*!< Data destructor */
2811 struct ast_exten *peer; /*!< Next higher priority with our extension */
2812 const char *registrar; /*!< Registrar */
2813 struct ast_exten *next; /*!< Extension with a greater ID */
2817 typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data);
2819 int hastime; /*!< If time construct exists */
2820 unsigned int monthmask; /*!< Mask for month */
2821 unsigned int daymask; /*!< Mask for date */
2822 unsigned int dowmask; /*!< Mask for day of week (mon-sun) */
2823 unsigned int minmask[24]; /*!< Mask for minute */
2826 /*! \brief ast_include: include= support in extensions.conf */
2827 struct ast_include {
2829 const char *rname; /*!< Context to include */
2830 const char *registrar; /*!< Registrar */
2831 int hastime; /*!< If time construct exists */
2832 struct ast_timing timing; /*!< time construct */
2833 struct ast_include *next; /*!< Link them together */
2837 /*! \brief ast_sw: Switch statement in extensions.conf */
2840 const char *registrar; /*!< Registrar */
2841 char *data; /*!< Data load */
2843 AST_LIST_ENTRY(ast_sw) list;
2848 /*! \brief ast_ignorepat: Ignore patterns in dial plan */
2849 struct ast_ignorepat {
2850 const char *registrar;
2851 struct ast_ignorepat *next;
2852 const char pattern[0];
2855 /*! \brief ast_context: An extension context */
2856 struct ast_context {
2857 ast_rwlock_t lock; /*!< A lock to prevent multiple threads from clobbering the context */
2858 struct ast_exten *root; /*!< The root of the list of extensions */
2859 struct ast_context *next; /*!< Link them together */
2860 struct ast_include *includes; /*!< Include other contexts */
2861 struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
2862 const char *registrar; /*!< Registrar */
2863 AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
2864 ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
2865 char name[0]; /*!< Name of the context */
2869 /*! \brief ast_app: A registered application */
2871 int (*execute)(struct ast_channel *chan, void *data);
2872 const char *synopsis; /*!< Synopsis text for 'show applications' */
2873 const char *description; /*!< Description (help text) for 'show application <name>' */
2874 AST_RWLIST_ENTRY(ast_app) list; /*!< Next app in list */
2875 void *module; /*!< Module this app belongs to */
2876 char name[0]; /*!< Name of the application */
2880 /*! \brief ast_state_cb: An extension state notify register item */
2881 struct ast_state_cb {
2884 ast_state_cb_type callback;
2885 struct ast_state_cb *next;
2888 /*! \brief Structure for dial plan hints
2890 \note Hints are pointers from an extension in the dialplan to one or
2891 more devices (tech/name)
2892 - See \ref AstExtState
2895 struct ast_exten *exten; /*!< Extension */
2896 int laststate; /*!< Last known state */
2897 struct ast_state_cb *callbacks; /*!< Callback list for this extension */
2898 AST_RWLIST_ENTRY(ast_hint) list;/*!< Pointer to next hint in list */
2904 struct ast_state_cb *callbacks;
2906 AST_LIST_ENTRY(store_hint) list;
2910 AST_LIST_HEAD(store_hints, store_hint);
2912 static const struct cfextension_states {
2913 int extension_state;
2914 const char * const text;
2915 } extension_states[] = {
2916 { AST_EXTENSION_NOT_INUSE, "Idle" },
2917 { AST_EXTENSION_INUSE, "InUse" },
2918 { AST_EXTENSION_BUSY, "Busy" },
2919 { AST_EXTENSION_UNAVAILABLE, "Unavailable" },
2920 { AST_EXTENSION_RINGING, "Ringing" },
2921 { AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
2922 { AST_EXTENSION_ONHOLD, "Hold" },
2923 { AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD, "InUse&Hold" }
2925 #define STATUS_NO_CONTEXT 1
2926 #define STATUS_NO_EXTENSION 2
2927 #define STATUS_NO_PRIORITY 3
2928 #define STATUS_NO_LABEL 4
2929 #define STATUS_SUCCESS 5
2932 #if defined ( __i386__) && (defined(__FreeBSD__) || defined(linux))
2933 #if defined(__FreeBSD__)
2934 #include <machine/cpufunc.h>
2935 #elif defined(linux)
2936 static __inline uint64_t
2941 __asm __volatile(".byte 0x0f, 0x31" : "=A" (rv));
2945 #else /* supply a dummy function on other platforms */
2946 static __inline uint64_t
2954 static struct ast_var_t *ast_var_assign(const char *name, const char *value)
2956 struct ast_var_t *var;
2957 int name_len = strlen(name) + 1;
2958 int value_len = strlen(value) + 1;
2960 if (!(var = ast_calloc(sizeof(*var) + name_len + value_len, sizeof(char)))) {
2964 ast_copy_string(var->name, name, name_len);
2965 var->value = var->name + name_len;
2966 ast_copy_string(var->value, value, value_len);
2971 static void ast_var_delete(struct ast_var_t *var)
2978 /* chopped this one off at the knees! */
2979 static int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
2982 /* ast_log(LOG_ERROR, "Function %s not registered\n", function); we are not interested in the details here */
2987 static unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
2991 int paren = 0, quote = 0;
2993 if (!buf || !array || !arraylen)
2996 memset(array, 0, arraylen * sizeof(*array));
3000 for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
3002 for (; *scan; scan++) {
3005 else if (*scan == ')') {
3008 } else if (*scan == '"' && delim != '"') {
3009 quote = quote ? 0 : 1;
3010 /* Remove quote character from argument */
3011 memmove(scan, scan + 1, strlen(scan));
3013 } else if (*scan == '\\') {
3014 /* Literal character, don't parse */
3015 memmove(scan, scan + 1, strlen(scan));
3016 } else if ((*scan == delim) && !paren && !quote) {
3024 array[argc++] = scan;
3029 static void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
3031 struct ast_var_t *newvariable;
3032 struct varshead *headp;
3033 const char *nametail = name;
3035 /* XXX may need locking on the channel ? */
3036 if (name[strlen(name)-1] == ')') {
3037 char *function = ast_strdupa(name);
3039 ast_func_write(chan, function, value);
3045 /* For comparison purposes, we have to strip leading underscores */
3046 if (*nametail == '_') {
3048 if (*nametail == '_')
3052 AST_LIST_TRAVERSE (headp, newvariable, entries) {
3053 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
3054 /* there is already such a variable, delete it */
3055 AST_LIST_REMOVE(headp, newvariable, entries);
3056 ast_var_delete(newvariable);
3062 if ((option_verbose > 1) && (headp == &globals))
3063 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
3064 newvariable = ast_var_assign(name, value);
3065 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
3070 static int pbx_builtin_setvar(struct ast_channel *chan, void *data)
3072 char *name, *value, *mydata;
3074 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */
3078 if (ast_strlen_zero(data)) {
3079 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n");
3083 mydata = ast_strdupa(data);
3084 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
3086 /* check for a trailing flags argument */
3087 if ((argc > 1) && !strchr(argv[argc-1], '=')) {
3089 if (strchr(argv[argc], 'g'))
3093 for (x = 0; x < argc; x++) {
3095 if ((value = strchr(name, '='))) {
3097 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value);
3099 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name);
3105 int localized_pbx_builtin_setvar(struct ast_channel *chan, void *data);
3107 int localized_pbx_builtin_setvar(struct ast_channel *chan, void *data)
3109 return pbx_builtin_setvar(chan, data);
3113 /*! \brief Helper for get_range.
3114 * return the index of the matching entry, starting from 1.
3115 * If names is not supplied, try numeric values.
3118 static int lookup_name(const char *s, char *const names[], int max)
3123 for (i = 0; names[i]; i++) {
3124 if (!strcasecmp(s, names[i]))
3127 } else if (sscanf(s, "%d", &i) == 1 && i >= 1 && i <= max) {
3130 return 0; /* error return */
3133 /*! \brief helper function to return a range up to max (7, 12, 31 respectively).
3134 * names, if supplied, is an array of names that should be mapped to numbers.
3136 static unsigned get_range(char *src, int max, char *const names[], const char *msg)
3138 int s, e; /* start and ending position */
3139 unsigned int mask = 0;
3141 /* Check for whole range */
3142 if (ast_strlen_zero(src) || !strcmp(src, "*")) {
3146 /* Get start and ending position */
3147 char *c = strchr(src, '-');
3150 /* Find the start */
3151 s = lookup_name(src, names, max);
3153 ast_log(LOG_WARNING, "Invalid %s '%s', assuming none\n", msg, src);
3157 if (c) { /* find end of range */
3158 e = lookup_name(c, names, max);
3160 ast_log(LOG_WARNING, "Invalid end %s '%s', assuming none\n", msg, c);
3167 /* Fill the mask. Remember that ranges are cyclic */
3168 mask = 1 << e; /* initialize with last element */
3181 /*! \brief store a bitmask of valid times, one bit each 2 minute */
3182 static void get_timerange(struct ast_timing *i, char *times)
3190 /* start disabling all times, fill the fields with 0's, as they may contain garbage */
3191 memset(i->minmask, 0, sizeof(i->minmask));
3193 /* 2-minutes per bit, since the mask has only 32 bits :( */
3194 /* Star is all times */
3195 if (ast_strlen_zero(times) || !strcmp(times, "*")) {
3196 for (x=0; x<24; x++)
3197 i->minmask[x] = 0x3fffffff; /* 30 bits */
3200 /* Otherwise expect a range */
3201 e = strchr(times, '-');
3203 ast_log(LOG_WARNING, "Time range is not valid. Assuming no restrictions based on time.\n");
3207 /* XXX why skip non digits ? */
3208 while (*e && !isdigit(*e))
3211 ast_log(LOG_WARNING, "Invalid time range. Assuming no restrictions based on time.\n");
3214 if (sscanf(times, "%d:%d", &s1, &s2) != 2) {
3215 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", times);
3218 if (sscanf(e, "%d:%d", &e1, &e2) != 2) {
3219 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", e);
3222 /* XXX this needs to be optimized */
3224 s1 = s1 * 30 + s2/2;
3225 if ((s1 < 0) || (s1 >= 24*30)) {
3226 ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times);
3229 e1 = e1 * 30 + e2/2;
3230 if ((e1 < 0) || (e1 >= 24*30)) {
3231 ast_log(LOG_WARNING, "%s isn't a valid end time. Assuming no time.\n", e);
3234 /* Go through the time and enable each appropriate bit */
3235 for (x=s1;x != e1;x = (x + 1) % (24 * 30)) {
3236 i->minmask[x/30] |= (1 << (x % 30));
3238 /* Do the last one */
3239 i->minmask[x/30] |= (1 << (x % 30));
3241 for (cth=0; cth<24; cth++) {
3242 /* Initialize masks to blank */
3243 i->minmask[cth] = 0;
3244 for (ctm=0; ctm<30; ctm++) {
3246 /* First hour with more than one hour */
3247 (((cth == s1) && (ctm >= s2)) &&
3250 || (((cth == s1) && (ctm >= s2)) &&
3251 ((cth == e1) && (ctm <= e2)))
3252 /* In between first and last hours (more than 2 hours) */
3255 /* Last hour with more than one hour */
3257 ((cth == e1) && (ctm <= e2)))
3259 i->minmask[cth] |= (1 << (ctm / 2));
3267 static void null_datad(void *foo)
3271 /*! \brief Find realtime engine for realtime family */
3272 static struct ast_config_engine *find_engine(const char *family, char *database, int dbsiz, char *table, int tabsiz)
3274 struct ast_config_engine *eng, *ret = NULL;
3275 struct ast_config_map *map;
3278 for (map = config_maps; map; map = map->next) {
3279 if (!strcasecmp(family, map->name)) {
3281 ast_copy_string(database, map->database, dbsiz);
3283 ast_copy_string(table, map->table ? map->table : family, tabsiz);
3288 /* Check if the required driver (engine) exist */
3290 for (eng = config_engine_list; !ret && eng; eng = eng->next) {
3291 if (!strcasecmp(eng->name, map->driver))
3297 /* if we found a mapping, but the engine is not available, then issue a warning */
3299 ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
3304 struct ast_category *ast_config_get_current_category(const struct ast_config *cfg);
3306 struct ast_category *ast_config_get_current_category(const struct ast_config *cfg)
3308 return cfg->current;
3311 static struct ast_category *ast_category_new(const char *name, const char *in_file, int lineno);
3313 static struct ast_category *ast_category_new(const char *name, const char *in_file, int lineno)
3315 struct ast_category *category;
3317 if ((category = ast_calloc(1, sizeof(*category))))
3318 ast_copy_string(category->name, name, sizeof(category->name));
3319 category->file = strdup(in_file);
3320 category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
3324 struct ast_category *localized_category_get(const struct ast_config *config, const char *category_name);
3326 struct ast_category *localized_category_get(const struct ast_config *config, const char *category_name)
3328 return category_get(config, category_name, 0);
3331 static void move_variables(struct ast_category *old, struct ast_category *new)
3333 struct ast_variable *var = old->root;
3336 /* we can just move the entire list in a single op */
3337 ast_variable_append(new, var);
3340 struct ast_variable *next = var->next;
3342 ast_variable_append(new, var);
3348 static void inherit_category(struct ast_category *new, const struct ast_category *base)
3350 struct ast_variable *var;
3352 for (var = base->root; var; var = var->next)
3353 ast_variable_append(new, variable_clone(var));
3356 static void ast_category_append(struct ast_config *config, struct ast_category *category);
3358 static void ast_category_append(struct ast_config *config, struct ast_category *category)
3361 config->last->next = category;
3363 config->root = category;
3364 config->last = category;
3365 config->current = category;
3368 static void ast_category_destroy(struct ast_category *cat);
3370 static void ast_category_destroy(struct ast_category *cat)
3372 ast_variables_destroy(cat->root);
3379 static struct ast_config_engine text_file_engine = {
3381 .load_func = config_text_file_load,
3385 static struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_incl_file);
3387 static struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_incl_file)
3391 struct ast_config_engine *loader = &text_file_engine;
3392 struct ast_config *result;
3394 if (cfg->include_level == cfg->max_include_level) {
3395 ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
3399 cfg->include_level++;
3400 /* silence is golden!
3401 ast_log(LOG_WARNING, "internal loading file %s level=%d\n", filename, cfg->include_level);
3404 if (strcmp(filename, extconfig_conf) && strcmp(filename, "asterisk.conf") && config_engine_list) {
3405 struct ast_config_engine *eng;
3407 eng = find_engine(filename, db, sizeof(db), table, sizeof(table));
3410 if (eng && eng->load_func) {
3413 eng = find_engine("global", db, sizeof(db), table, sizeof(table));
3414 if (eng && eng->load_func)
3419 result = loader->load_func(db, table, filename, cfg, withcomments, suggested_incl_file);
3420 /* silence is golden
3421 ast_log(LOG_WARNING, "finished internal loading file %s level=%d\n", filename, cfg->include_level);
3425 result->include_level--;
3431 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)
3435 struct ast_variable *v;
3436 char cmd[512], exec_file[512];
3437 int object, do_exec, do_include;
3439 /* Actually parse the entry */
3440 if (cur[0] == '[') {
3441 struct ast_category *newcat = NULL;
3444 /* A category header */
3445 c = strchr(cur, ']');
3447 ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
3455 if (!(*cat = newcat = ast_category_new(catname, ast_strlen_zero(suggested_include_file)?configfile:suggested_include_file, lineno))) {
3458 (*cat)->lineno = lineno;
3461 if (withcomments && comment_buffer && comment_buffer[0] ) {
3462 newcat->precomments = ALLOC_COMMENT(comment_buffer);
3464 if (withcomments && lline_buffer && lline_buffer[0] ) {
3465 newcat->sameline = ALLOC_COMMENT(lline_buffer);
3470 /* If there are options or categories to inherit from, process them now */
3472 if (!(cur = strchr(c, ')'))) {
3473 ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
3477 while ((cur = strsep(&c, ","))) {
3478 if (!strcasecmp(cur, "!")) {
3479 (*cat)->ignored = 1;
3480 } else if (!strcasecmp(cur, "+")) {
3481 *cat = category_get(cfg, catname, 1);
3483 ast_config_destroy(cfg);
3485 ast_category_destroy(newcat);
3486 ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
3490 move_variables(newcat, *cat);
3491 ast_category_destroy(newcat);
3495 struct ast_category *base;
3497 base = category_get(cfg, cur, 1);
3499 ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
3502 inherit_category(*cat, base);
3507 ast_category_append(cfg, *cat);
3508 } else if (cur[0] == '#') {
3512 while(*c && (*c > 32)) c++;
3515 /* Find real argument */
3516 c = ast_skip_blanks(c + 1);
3521 do_include = !strcasecmp(cur, "include");
3523 do_exec = !strcasecmp(cur, "exec");
3526 if (do_exec && !ast_opt_exec_includes) {
3527 ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
3530 if (do_include || do_exec) {
3533 char real_inclusion_name[256];
3534 struct ast_config_include *inclu;
3536 /* Strip off leading and trailing "'s and <>'s */
3537 while((*c == '<') || (*c == '>') || (*c == '\"')) c++;
3538 /* Get rid of leading mess */
3541 while (!ast_strlen_zero(cur)) {
3542 c = cur + strlen(cur) - 1;
3543 if ((*c == '>') || (*c == '<') || (*c == '\"'))
3548 /* #exec </path/to/executable>
3549 We create a tmp file, then we #include it, then we delete it. */
3551 snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d.%ld", (int)time(NULL), (long)pthread_self());
3552 snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file);
3553 ast_safe_system(cmd);
3556 exec_file[0] = '\0';
3558 /* ast_log(LOG_WARNING, "Reading in included file %s withcomments=%d\n", cur, withcomments); */
3560 /* record this inclusion */
3561 inclu = ast_include_new(cfg, configfile, cur, do_exec, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name));
3563 do_include = ast_config_internal_load(cur, cfg, withcomments, real_inclusion_name) ? 1 : 0;
3564 if(!ast_strlen_zero(exec_file))
3568 /* ast_log(LOG_WARNING, "Done reading in included file %s withcomments=%d\n", cur, withcomments); */
3571 ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n",
3572 do_exec ? "exec" : "include",
3573 do_exec ? "/path/to/executable" : "filename",
3579 ast_log(LOG_WARNING, "Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile);
3581 /* Just a line (variable = value) */
3583 ast_log(LOG_WARNING,
3584 "parse error: No category context for line %d of %s\n", lineno, configfile);
3587 c = strchr(cur, '=');
3591 /* Ignore > in => */
3597 if ((v = ast_variable_new(ast_strip(cur), ast_strip(c), configfile))) {
3600 /* Put and reset comments */
3602 ast_variable_append(*cat, v);
3604 if (withcomments && comment_buffer && comment_buffer[0] ) {
3605 v->precomments = ALLOC_COMMENT(comment_buffer);
3607 if (withcomments && lline_buffer && lline_buffer[0] ) {
3608 v->sameline = ALLOC_COMMENT(lline_buffer);
3617 ast_log(LOG_WARNING, "EXTENSIONS.CONF: No '=' (equal sign) in line %d of %s\n", lineno, configfile);
3623 static int use_local_dir = 1;
3625 void localized_use_local_dir(void);
3626 void localized_use_conf_dir(void);
3628 void localized_use_local_dir(void)
3633 void localized_use_conf_dir(void)
3639 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)
3643 char *new_buf, *comment_p, *process_buf;
3646 int comment = 0, nest[MAX_NESTED_COMMENTS];
3647 struct ast_category *cat = NULL;
3649 struct stat statbuf;
3651 cat = ast_config_get_current_category(cfg);
3653 if (filename[0] == '/') {
3654 ast_copy_string(fn, filename, sizeof(fn));
3657 snprintf(fn, sizeof(fn), "./%s", filename);
3659 snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
3662 if (withcomments && cfg && cfg->include_level < 2 ) {
3666 #ifdef AST_INCLUDE_GLOB
3671 globbuf.gl_offs = 0; /* initialize it to silence gcc */
3673 glob_ret = glob(fn, GLOB_NOCHECK, NULL, &globbuf);
3675 glob_ret = glob(fn, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf);
3677 if (glob_ret == GLOB_NOSPACE)
3678 ast_log(LOG_WARNING,
3679 "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
3680 else if (glob_ret == GLOB_ABORTED)
3681 ast_log(LOG_WARNING,
3682 "Glob Expansion of pattern '%s' failed: Read error\n", fn);
3684 /* loop over expanded files */
3686 for (i=0; i<globbuf.gl_pathc; i++) {
3687 ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn));
3690 if (stat(fn, &statbuf))
3693 if (!S_ISREG(statbuf.st_mode)) {
3694 ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
3697 if (option_verbose > 1) {
3698 ast_verbose(VERBOSE_PREFIX_2 "Parsing '%s': ", fn);
3701 if (!(f = fopen(fn, "r"))) {
3703 ast_log(LOG_DEBUG, "No file to parse: %s\n", fn);
3704 if (option_verbose > 1)
3705 ast_verbose( "Not found (%s)\n", strerror(errno));
3710 ast_log(LOG_DEBUG, "Parsing %s\n", fn);
3711 if (option_verbose > 1)
3712 ast_verbose("Found\n");
3715 if (fgets(buf, sizeof(buf), f)) {
3716 if ( withcomments ) {
3717 CB_ADD(lline_buffer); /* add the current lline buffer to the comment buffer */
3718 lline_buffer[0] = 0; /* erase the lline buffer */
3727 while ((comment_p = strchr(new_buf, COMMENT_META))) {
3728 if ((comment_p > new_buf) && (*(comment_p-1) == '\\')) {
3729 /* Yuck, gotta memmove */
3730 memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
3731 new_buf = comment_p;
3732 } else if(comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) {
3733 /* Meta-Comment start detected ";--" */
3734 if (comment < MAX_NESTED_COMMENTS) {
3736 new_buf = comment_p + 3;