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.
28 * \li \ref extconf.c uses the configuration file \ref extconfig.conf and \ref extensions.conf and \ref asterisk.conf
29 * \addtogroup configuration_file Configuration Files
33 * \page extconfig.conf extconfig.conf
34 * \verbinclude extconfig.conf.sample
38 * \page extensions.conf extensions.conf
39 * \verbinclude extensions.conf.sample
43 <support_level>extended</support_level>
50 #include "asterisk/compat.h"
51 #include "asterisk/paths.h" /* we use AST_CONFIG_DIR */
56 #include <sys/types.h>
58 #include <sys/resource.h>
64 #if !defined(SOLARIS) && !defined(__CYGWIN__)
71 #include <sys/param.h>
74 static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__((format(printf, 5, 6)));
75 void ast_verbose(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
77 #define ASINCLUDE_GLOB 1
78 #ifdef AST_INCLUDE_GLOB
80 #if !defined(GLOB_ABORTED)
81 #define GLOB_ABORTED GLOB_ABEND
87 #define AST_API_MODULE 1 /* gimme the inline defs! */
90 char x; /* basically empty! */
95 #include "asterisk/inline_api.h"
96 #include "asterisk/endian.h"
97 #include "asterisk/ast_expr.h"
101 #define EVENTLOG "event_log"
102 #define QUEUELOG "queue_log"
104 #define DEBUG_M(a) { \
108 #define VERBOSE_PREFIX_1 " "
109 #define VERBOSE_PREFIX_2 " == "
110 #define VERBOSE_PREFIX_3 " -- "
111 #define VERBOSE_PREFIX_4 " > "
113 void ast_backtrace(void);
115 void ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt, ...)
116 __attribute__((format(printf, 5, 6)));
118 /* IN CONFLICT: void ast_verbose(const char *fmt, ...)
119 __attribute__((format(printf, 1, 2))); */
121 int ast_register_verbose(void (*verboser)(const char *string));
122 int ast_unregister_verbose(void (*verboser)(const char *string));
124 void ast_console_puts(const char *string);
126 #define _A_ __FILE__, __LINE__, __PRETTY_FUNCTION__
131 #define __LOG_DEBUG 0
132 #define LOG_DEBUG __LOG_DEBUG, _A_
137 #define __LOG_EVENT 1
138 #define LOG_EVENT __LOG_EVENT, _A_
143 #define __LOG_NOTICE 2
144 #define LOG_NOTICE __LOG_NOTICE, _A_
149 #define __LOG_WARNING 3
150 #define LOG_WARNING __LOG_WARNING, _A_
155 #define __LOG_ERROR 4
156 #define LOG_ERROR __LOG_ERROR, _A_
161 #define __LOG_VERBOSE 5
162 #define LOG_VERBOSE __LOG_VERBOSE, _A_
168 #define LOG_DTMF __LOG_DTMF, _A_
172 #ifndef HAVE_MTX_PROFILE
173 #define __MTX_PROF(a) return pthread_mutex_lock((a))
177 #define __MTX_PROF(a) do { \
179 /* profile only non-blocking events */ \
180 ast_mark(mtx_prof, 1); \
181 i = pthread_mutex_trylock((a)); \
182 ast_mark(mtx_prof, 0); \
186 return pthread_mutex_lock((a)); \
188 #endif /* HAVE_MTX_PROFILE */
190 #define AST_PTHREADT_NULL (pthread_t) -1
191 #define AST_PTHREADT_STOP (pthread_t) -2
193 #if defined(SOLARIS) || defined(BSD)
194 #define AST_MUTEX_INIT_W_CONSTRUCTORS
195 #endif /* SOLARIS || BSD */
197 /* Asterisk REQUIRES recursive (not error checking) mutexes
198 and will not run without them. */
199 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) && defined(PTHREAD_MUTEX_RECURSIVE_NP)
200 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
201 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
203 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_MUTEX_INITIALIZER
204 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
205 #endif /* PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
209 #define __ast_mutex_logger(...) do { if (canlog) ast_log(LOG_ERROR, __VA_ARGS__); else fprintf(stderr, __VA_ARGS__); } while (0)
212 #define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
214 #define DO_THREAD_CRASH do { } while (0)
217 #define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, { NULL }, { 0 }, 0, { NULL }, { 0 } }
219 #define AST_MAX_REENTRANCY 10
221 struct ast_mutex_info {
222 pthread_mutex_t mutex;
223 /*! Track which thread holds this lock */
224 unsigned int track:1;
225 const char *file[AST_MAX_REENTRANCY];
226 int lineno[AST_MAX_REENTRANCY];
228 const char *func[AST_MAX_REENTRANCY];
229 pthread_t thread[AST_MAX_REENTRANCY];
232 typedef struct ast_mutex_info ast_mutex_t;
234 typedef pthread_cond_t ast_cond_t;
236 static pthread_mutex_t empty_mutex;
238 static void __attribute__((constructor)) init_empty_mutex(void)
240 memset(&empty_mutex, 0, sizeof(empty_mutex));
243 static inline int __ast_pthread_mutex_init_attr(const char *filename, int lineno, const char *func,
244 const char *mutex_name, ast_mutex_t *t,
245 pthread_mutexattr_t *attr)
247 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
248 int canlog = strcmp(filename, "logger.c");
250 if ((t->mutex) != ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
251 if ((t->mutex) != (empty_mutex)) {
252 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is already initialized.\n",
253 filename, lineno, func, mutex_name);
254 __ast_mutex_logger("%s line %d (%s): Error: previously initialization of mutex '%s'.\n",
255 t->file[0], t->lineno[0], t->func[0], mutex_name);
262 t->file[0] = filename;
263 t->lineno[0] = lineno;
268 return pthread_mutex_init(&t->mutex, attr);
271 static inline int __ast_pthread_mutex_init(const char *filename, int lineno, const char *func,
272 const char *mutex_name, ast_mutex_t *t)
274 static pthread_mutexattr_t attr;
276 pthread_mutexattr_init(&attr);
277 pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
279 return __ast_pthread_mutex_init_attr(filename, lineno, func, mutex_name, t, &attr);
281 #define ast_mutex_init(pmutex) __ast_pthread_mutex_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
283 static inline int __ast_pthread_mutex_destroy(const char *filename, int lineno, const char *func,
284 const char *mutex_name, ast_mutex_t *t)
287 int canlog = strcmp(filename, "logger.c");
289 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
290 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
291 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
292 filename, lineno, func, mutex_name);
296 res = pthread_mutex_trylock(&t->mutex);
299 pthread_mutex_unlock(&t->mutex);
302 __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy invalid mutex '%s'.\n",
303 filename, lineno, func, mutex_name);
306 __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy locked mutex '%s'.\n",
307 filename, lineno, func, mutex_name);
308 __ast_mutex_logger("%s line %d (%s): Error: '%s' was locked here.\n",
309 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
313 if ((res = pthread_mutex_destroy(&t->mutex)))
314 __ast_mutex_logger("%s line %d (%s): Error destroying mutex: %s\n",
315 filename, lineno, func, strerror(res));
316 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
318 t->mutex = PTHREAD_MUTEX_INIT_VALUE;
320 t->file[0] = filename;
321 t->lineno[0] = lineno;
327 static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func,
328 const char* mutex_name, ast_mutex_t *t)
331 int canlog = strcmp(filename, "logger.c");
333 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
334 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
335 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
336 filename, lineno, func, mutex_name);
339 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
341 #ifdef DETECT_DEADLOCKS
343 time_t seconds = time(NULL);
346 #ifdef HAVE_MTX_PROFILE
347 ast_mark(mtx_prof, 1);
349 res = pthread_mutex_trylock(&t->mutex);
350 #ifdef HAVE_MTX_PROFILE
351 ast_mark(mtx_prof, 0);
354 current = time(NULL);
355 if ((current - seconds) && (!((current - seconds) % 5))) {
356 __ast_mutex_logger("%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n",
357 filename, lineno, func, (int)(current - seconds), mutex_name);
358 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
359 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
360 t->func[t->reentrancy-1], mutex_name);
364 } while (res == EBUSY);
367 #ifdef HAVE_MTX_PROFILE
368 ast_mark(mtx_prof, 1);
369 res = pthread_mutex_trylock(&t->mutex);
370 ast_mark(mtx_prof, 0);
373 res = pthread_mutex_lock(&t->mutex);
374 #endif /* DETECT_DEADLOCKS */
377 if (t->reentrancy < AST_MAX_REENTRANCY) {
378 t->file[t->reentrancy] = filename;
379 t->lineno[t->reentrancy] = lineno;
380 t->func[t->reentrancy] = func;
381 t->thread[t->reentrancy] = pthread_self();
384 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
385 filename, lineno, func, mutex_name);
388 __ast_mutex_logger("%s line %d (%s): Error obtaining mutex: %s\n",
389 filename, lineno, func, strerror(errno));
396 static inline int __ast_pthread_mutex_trylock(const char *filename, int lineno, const char *func,
397 const char* mutex_name, ast_mutex_t *t)
400 int canlog = strcmp(filename, "logger.c");
402 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
403 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
404 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
405 filename, lineno, func, mutex_name);
408 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
410 if (!(res = pthread_mutex_trylock(&t->mutex))) {
411 if (t->reentrancy < AST_MAX_REENTRANCY) {
412 t->file[t->reentrancy] = filename;
413 t->lineno[t->reentrancy] = lineno;
414 t->func[t->reentrancy] = func;
415 t->thread[t->reentrancy] = pthread_self();
418 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
419 filename, lineno, func, mutex_name);
422 __ast_mutex_logger("%s line %d (%s): Warning: '%s' was locked here.\n",
423 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
429 static inline int __ast_pthread_mutex_unlock(const char *filename, int lineno, const char *func,
430 const char *mutex_name, ast_mutex_t *t)
433 int canlog = strcmp(filename, "logger.c");
435 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
436 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
437 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
438 filename, lineno, func, mutex_name);
442 if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
443 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
444 filename, lineno, func, mutex_name);
445 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
446 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
450 if (--t->reentrancy < 0) {
451 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
452 filename, lineno, func, mutex_name);
456 if (t->reentrancy < AST_MAX_REENTRANCY) {
457 t->file[t->reentrancy] = NULL;
458 t->lineno[t->reentrancy] = 0;
459 t->func[t->reentrancy] = NULL;
460 t->thread[t->reentrancy] = 0;
463 if ((res = pthread_mutex_unlock(&t->mutex))) {
464 __ast_mutex_logger("%s line %d (%s): Error releasing mutex: %s\n",
465 filename, lineno, func, strerror(res));
472 static inline int __ast_cond_init(const char *filename, int lineno, const char *func,
473 const char *cond_name, ast_cond_t *cond, pthread_condattr_t *cond_attr)
475 return pthread_cond_init(cond, cond_attr);
478 static inline int __ast_cond_signal(const char *filename, int lineno, const char *func,
479 const char *cond_name, ast_cond_t *cond)
481 return pthread_cond_signal(cond);
484 static inline int __ast_cond_broadcast(const char *filename, int lineno, const char *func,
485 const char *cond_name, ast_cond_t *cond)
487 return pthread_cond_broadcast(cond);
490 static inline int __ast_cond_destroy(const char *filename, int lineno, const char *func,
491 const char *cond_name, ast_cond_t *cond)
493 return pthread_cond_destroy(cond);
496 static inline int __ast_cond_wait(const char *filename, int lineno, const char *func,
497 const char *cond_name, const char *mutex_name,
498 ast_cond_t *cond, ast_mutex_t *t)
501 int canlog = strcmp(filename, "logger.c");
503 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
504 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
505 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
506 filename, lineno, func, mutex_name);
510 if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
511 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
512 filename, lineno, func, mutex_name);
513 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
514 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
518 if (--t->reentrancy < 0) {
519 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
520 filename, lineno, func, mutex_name);
524 if (t->reentrancy < AST_MAX_REENTRANCY) {
525 t->file[t->reentrancy] = NULL;
526 t->lineno[t->reentrancy] = 0;
527 t->func[t->reentrancy] = NULL;
528 t->thread[t->reentrancy] = 0;
531 if ((res = pthread_cond_wait(cond, &t->mutex))) {
532 __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n",
533 filename, lineno, func, strerror(res));
536 if (t->reentrancy < AST_MAX_REENTRANCY) {
537 t->file[t->reentrancy] = filename;
538 t->lineno[t->reentrancy] = lineno;
539 t->func[t->reentrancy] = func;
540 t->thread[t->reentrancy] = pthread_self();
543 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
544 filename, lineno, func, mutex_name);
551 static inline int __ast_cond_timedwait(const char *filename, int lineno, const char *func,
552 const char *cond_name, const char *mutex_name, ast_cond_t *cond,
553 ast_mutex_t *t, const struct timespec *abstime)
556 int canlog = strcmp(filename, "logger.c");
558 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
559 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
560 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
561 filename, lineno, func, mutex_name);
565 if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
566 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
567 filename, lineno, func, mutex_name);
568 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
569 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
573 if (--t->reentrancy < 0) {
574 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
575 filename, lineno, func, mutex_name);
579 if (t->reentrancy < AST_MAX_REENTRANCY) {
580 t->file[t->reentrancy] = NULL;
581 t->lineno[t->reentrancy] = 0;
582 t->func[t->reentrancy] = NULL;
583 t->thread[t->reentrancy] = 0;
586 if ((res = pthread_cond_timedwait(cond, &t->mutex, abstime)) && (res != ETIMEDOUT)) {
587 __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n",
588 filename, lineno, func, strerror(res));
591 if (t->reentrancy < AST_MAX_REENTRANCY) {
592 t->file[t->reentrancy] = filename;
593 t->lineno[t->reentrancy] = lineno;
594 t->func[t->reentrancy] = func;
595 t->thread[t->reentrancy] = pthread_self();
598 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
599 filename, lineno, func, mutex_name);
606 #define ast_mutex_destroy(a) __ast_pthread_mutex_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
607 #define ast_mutex_lock(a) __ast_pthread_mutex_lock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
608 #define ast_mutex_unlock(a) __ast_pthread_mutex_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
609 #define ast_mutex_trylock(a) __ast_pthread_mutex_trylock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
610 #define ast_cond_init(cond, attr) __ast_cond_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond, attr)
611 #define ast_cond_destroy(cond) __ast_cond_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
612 #define ast_cond_signal(cond) __ast_cond_signal(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
613 #define ast_cond_broadcast(cond) __ast_cond_broadcast(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
614 #define ast_cond_wait(cond, mutex) __ast_cond_wait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex)
615 #define ast_cond_timedwait(cond, mutex, time) __ast_cond_timedwait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex, time)
617 #else /* !DEBUG_THREADS */
620 typedef pthread_mutex_t ast_mutex_t;
622 #define AST_MUTEX_INIT_VALUE ((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
624 static inline int ast_mutex_init(ast_mutex_t *pmutex)
626 pthread_mutexattr_t attr;
628 pthread_mutexattr_init(&attr);
629 pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
631 return pthread_mutex_init(pmutex, &attr);
634 #define ast_pthread_mutex_init(pmutex,a) pthread_mutex_init(pmutex,a)
636 static inline int ast_mutex_unlock(ast_mutex_t *pmutex)
638 return pthread_mutex_unlock(pmutex);
641 static inline int ast_mutex_destroy(ast_mutex_t *pmutex)
643 return pthread_mutex_destroy(pmutex);
646 static inline int ast_mutex_lock(ast_mutex_t *pmutex)
651 static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
653 return pthread_mutex_trylock(pmutex);
656 typedef pthread_cond_t ast_cond_t;
658 static inline int ast_cond_init(ast_cond_t *cond, pthread_condattr_t *cond_attr)
660 return pthread_cond_init(cond, cond_attr);
663 static inline int ast_cond_signal(ast_cond_t *cond)
665 return pthread_cond_signal(cond);
668 static inline int ast_cond_broadcast(ast_cond_t *cond)
670 return pthread_cond_broadcast(cond);
673 static inline int ast_cond_destroy(ast_cond_t *cond)
675 return pthread_cond_destroy(cond);
678 static inline int ast_cond_wait(ast_cond_t *cond, ast_mutex_t *t)
680 return pthread_cond_wait(cond, t);
683 static inline int ast_cond_timedwait(ast_cond_t *cond, ast_mutex_t *t, const struct timespec *abstime)
685 return pthread_cond_timedwait(cond, t, abstime);
688 #endif /* !DEBUG_THREADS */
690 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
691 /* If AST_MUTEX_INIT_W_CONSTRUCTORS is defined, use file scope
692 constructors/destructors to create/destroy mutexes. */
693 #define __AST_MUTEX_DEFINE(scope, mutex) \
694 scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE; \
695 static void __attribute__((constructor)) init_##mutex(void) \
697 ast_mutex_init(&mutex); \
699 static void __attribute__((destructor)) fini_##mutex(void) \
701 ast_mutex_destroy(&mutex); \
703 #else /* !AST_MUTEX_INIT_W_CONSTRUCTORS */
704 /* By default, use static initialization of mutexes. */
705 #define __AST_MUTEX_DEFINE(scope, mutex) \
706 scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE
707 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
709 #define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
710 #define pthread_mutex_lock use_ast_mutex_lock_instead_of_pthread_mutex_lock
711 #define pthread_mutex_unlock use_ast_mutex_unlock_instead_of_pthread_mutex_unlock
712 #define pthread_mutex_trylock use_ast_mutex_trylock_instead_of_pthread_mutex_trylock
713 #define pthread_mutex_init use_ast_mutex_init_instead_of_pthread_mutex_init
714 #define pthread_mutex_destroy use_ast_mutex_destroy_instead_of_pthread_mutex_destroy
715 #define pthread_cond_t use_ast_cond_t_instead_of_pthread_cond_t
716 #define pthread_cond_init use_ast_cond_init_instead_of_pthread_cond_init
717 #define pthread_cond_destroy use_ast_cond_destroy_instead_of_pthread_cond_destroy
718 #define pthread_cond_signal use_ast_cond_signal_instead_of_pthread_cond_signal
719 #define pthread_cond_broadcast use_ast_cond_broadcast_instead_of_pthread_cond_broadcast
720 #define pthread_cond_wait use_ast_cond_wait_instead_of_pthread_cond_wait
721 #define pthread_cond_timedwait use_ast_cond_timedwait_instead_of_pthread_cond_timedwait
723 #define AST_MUTEX_DEFINE_STATIC(mutex) __AST_MUTEX_DEFINE(static, mutex)
725 #define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
727 #define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
730 #define pthread_create __use_ast_pthread_create_instead__
733 typedef pthread_rwlock_t ast_rwlock_t;
735 static inline int ast_rwlock_init(ast_rwlock_t *prwlock)
737 pthread_rwlockattr_t attr;
739 pthread_rwlockattr_init(&attr);
741 #ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
742 pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP);
745 return pthread_rwlock_init(prwlock, &attr);
748 static inline int ast_rwlock_destroy(ast_rwlock_t *prwlock)
750 return pthread_rwlock_destroy(prwlock);
753 static inline int ast_rwlock_unlock(ast_rwlock_t *prwlock)
755 return pthread_rwlock_unlock(prwlock);
758 static inline int ast_rwlock_rdlock(ast_rwlock_t *prwlock)
760 return pthread_rwlock_rdlock(prwlock);
763 static inline int ast_rwlock_tryrdlock(ast_rwlock_t *prwlock)
765 return pthread_rwlock_tryrdlock(prwlock);
768 static inline int ast_rwlock_wrlock(ast_rwlock_t *prwlock)
770 return pthread_rwlock_wrlock(prwlock);
773 static inline int ast_rwlock_trywrlock(ast_rwlock_t *prwlock)
775 return pthread_rwlock_trywrlock(prwlock);
778 /* Statically declared read/write locks */
780 #ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER
781 #define __AST_RWLOCK_DEFINE(scope, rwlock) \
782 scope ast_rwlock_t rwlock; \
783 static void __attribute__((constructor)) init_##rwlock(void) \
785 ast_rwlock_init(&rwlock); \
787 static void __attribute__((destructor)) fini_##rwlock(void) \
789 ast_rwlock_destroy(&rwlock); \
792 #define AST_RWLOCK_INIT_VALUE PTHREAD_RWLOCK_INITIALIZER
793 #define __AST_RWLOCK_DEFINE(scope, rwlock) \
794 scope ast_rwlock_t rwlock = AST_RWLOCK_INIT_VALUE
797 #define AST_RWLOCK_DEFINE_STATIC(rwlock) __AST_RWLOCK_DEFINE(static, rwlock)
800 * Initial support for atomic instructions.
801 * For platforms that have it, use the native cpu instruction to
802 * implement them. For other platforms, resort to a 'slow' version
803 * (defined in utils.c) that protects the atomic instruction with
805 * The slow versions is always available, for testing purposes,
806 * as ast_atomic_fetchadd_int_slow()
809 #if defined(HAVE_OSX_ATOMICS)
810 #include "libkern/OSAtomic.h"
813 /*! \brief Atomically add v to *p and return * the previous value of *p.
814 * This can be used to handle reference counts, and the return value
815 * can be used to generate unique identifiers.
818 #if defined(HAVE_GCC_ATOMICS)
819 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
821 return __sync_fetch_and_add(p, v);
823 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
824 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
826 return OSAtomicAdd32(v, (int32_t *) p);
828 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
829 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
831 return OSAtomicAdd64(v, (int64_t *) p);
832 #elif defined (__i386__) || defined(__x86_64__)
833 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
836 " lock xaddl %0, %1 ; "
837 : "+r" (v), /* 0 (result) */
843 static int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
850 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
852 return ast_atomic_fetchadd_int_slow(p, v);
856 /*! \brief decrement *p by 1 and return true if the variable has reached 0.
857 * Useful e.g. to check if a refcount has reached 0.
859 #if defined(HAVE_GCC_ATOMICS)
860 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
862 return __sync_sub_and_fetch(p, 1) == 0;
864 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
865 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
867 return OSAtomicAdd32( -1, (int32_t *) p) == 0;
869 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
870 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
872 return OSAtomicAdd64( -1, (int64_t *) p) == 0;
874 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
876 int a = ast_atomic_fetchadd_int(p, -1);
877 return a == 1; /* true if the value is 0 now (so it was 1 previously) */
881 #ifndef DEBUG_CHANNEL_LOCKS
882 /*! \brief Lock a channel. If DEBUG_CHANNEL_LOCKS is defined
883 in the Makefile, print relevant output for debugging */
884 #define ast_channel_lock(x) ast_mutex_lock(&x->lock)
885 /*! \brief Unlock a channel. If DEBUG_CHANNEL_LOCKS is defined
886 in the Makefile, print relevant output for debugging */
887 #define ast_channel_unlock(x) ast_mutex_unlock(&x->lock)
888 /*! \brief Try locking a channel. If DEBUG_CHANNEL_LOCKS is defined
889 in the Makefile, print relevant output for debugging */
890 #define ast_channel_trylock(x) ast_mutex_trylock(&x->lock)
893 /*! \brief Lock AST channel (and print debugging output)
894 \note You need to enable DEBUG_CHANNEL_LOCKS for this function */
895 int ast_channel_lock(struct ast_channel *chan);
897 /*! \brief Unlock AST channel (and print debugging output)
898 \note You need to enable DEBUG_CHANNEL_LOCKS for this function
900 int ast_channel_unlock(struct ast_channel *chan);
902 /*! \brief Lock AST channel (and print debugging output)
903 \note You need to enable DEBUG_CHANNEL_LOCKS for this function */
904 int ast_channel_trylock(struct ast_channel *chan);
908 #include "asterisk/hashtab.h"
909 #include "asterisk/ael_structs.h"
910 #include "asterisk/pval.h"
914 #define ast_free free
915 #define ast_free_ptr free
917 #define MALLOC_FAILURE_MSG \
918 ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
921 * \brief A wrapper for malloc()
923 * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
924 * message in the case that the allocation fails.
926 * The argument and return value are the same as malloc()
928 #define ast_malloc(len) \
929 _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
931 #define ast_calloc(num, len) \
932 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
934 #define ast_calloc_cache(num, len) \
935 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
937 #define ast_realloc(p, len) \
938 _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
940 #define ast_strdup(str) \
941 _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
943 #define ast_strndup(str, len) \
944 _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
946 #define ast_asprintf(ret, fmt, ...) \
947 _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
949 #define ast_vasprintf(ret, fmt, ap) \
950 _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
953 static unsigned int __unsigned_int_flags_dummy;
955 struct ast_flags { /* stolen from utils.h */
958 #define ast_test_flag(p,flag) ({ \
959 typeof ((p)->flags) __p = (p)->flags; \
960 typeof (__unsigned_int_flags_dummy) __x = 0; \
961 (void) (&__p == &__x); \
962 ((p)->flags & (flag)); \
965 #define ast_set2_flag(p,value,flag) do { \
966 typeof ((p)->flags) __p = (p)->flags; \
967 typeof (__unsigned_int_flags_dummy) __x = 0; \
968 (void) (&__p == &__x); \
970 (p)->flags |= (flag); \
972 (p)->flags &= ~(flag); \
977 #define MALLOC_FAILURE_MSG \
978 ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
980 * \brief A wrapper for malloc()
982 * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
983 * message in the case that the allocation fails.
985 * The argument and return value are the same as malloc()
987 #define ast_malloc(len) \
988 _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
991 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
995 if (!(p = malloc(len)))
1003 * \brief A wrapper for calloc()
1005 * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
1006 * message in the case that the allocation fails.
1008 * The arguments and return value are the same as calloc()
1010 #define ast_calloc(num, len) \
1011 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1014 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
1018 if (!(p = calloc(num, len)))
1026 * \brief A wrapper for calloc() for use in cache pools
1028 * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
1029 * message in the case that the allocation fails. When memory debugging is in use,
1030 * the memory allocated by this function will be marked as 'cache' so it can be
1031 * distinguished from normal memory allocations.
1033 * The arguments and return value are the same as calloc()
1035 #define ast_calloc_cache(num, len) \
1036 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1039 * \brief A wrapper for realloc()
1041 * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
1042 * message in the case that the allocation fails.
1044 * The arguments and return value are the same as realloc()
1046 #define ast_realloc(p, len) \
1047 _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1050 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
1054 if (!(newp = realloc(p, len)))
1062 * \brief A wrapper for strdup()
1064 * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
1065 * message in the case that the allocation fails.
1067 * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
1068 * argument is provided, ast_strdup will return NULL without generating any
1069 * kind of error log message.
1071 * The argument and return value are the same as strdup()
1073 #define ast_strdup(str) \
1074 _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1077 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
1079 char *newstr = NULL;
1082 if (!(newstr = strdup(str)))
1091 * \brief A wrapper for strndup()
1093 * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
1094 * message in the case that the allocation fails.
1096 * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
1097 * string to duplicate. If a NULL argument is provided, ast_strdup will return
1098 * NULL without generating any kind of error log message.
1100 * The arguments and return value are the same as strndup()
1102 #define ast_strndup(str, len) \
1103 _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1106 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
1108 char *newstr = NULL;
1111 if (!(newstr = strndup(str, len)))
1120 * \brief A wrapper for asprintf()
1122 * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
1123 * message in the case that the allocation fails.
1125 * The arguments and return value are the same as asprintf()
1127 #define ast_asprintf(ret, fmt, ...) \
1128 _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
1131 __attribute__((format(printf, 5, 6)))
1132 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...),
1138 if ((res = vasprintf(ret, fmt, ap)) == -1)
1147 * \brief A wrapper for vasprintf()
1149 * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
1150 * message in the case that the allocation fails.
1152 * The arguments and return value are the same as vasprintf()
1154 #define ast_vasprintf(ret, fmt, ap) \
1155 _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
1158 __attribute__((format(printf, 5, 0)))
1159 int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
1163 if ((res = vasprintf(ret, fmt, ap)) == -1)
1170 #if !defined(ast_strdupa) && defined(__GNUC__)
1172 \brief duplicate a string in memory from the stack
1173 \param s The string to duplicate
1175 This macro will duplicate the given string. It returns a pointer to the stack
1176 allocatted memory for the new string.
1178 #define ast_strdupa(s) \
1181 const char *__old = (s); \
1182 size_t __len = strlen(__old) + 1; \
1183 char *__new = __builtin_alloca(__len); \
1184 memcpy (__new, __old, __len); \
1192 #define MAX_NESTED_COMMENTS 128
1193 #define COMMENT_START ";--"
1194 #define COMMENT_END "--;"
1195 #define COMMENT_META ';'
1196 #define COMMENT_TAG '-'
1198 static char *extconfig_conf = "extconfig.conf";
1200 /*! Growable string buffer */
1201 static char *comment_buffer; /*!< this will be a comment collector.*/
1202 static int comment_buffer_size; /*!< the amount of storage so far alloc'd for the comment_buffer */
1204 static char *lline_buffer; /*!< A buffer for stuff behind the ; */
1205 static int lline_buffer_size;
1209 struct ast_comment {
1210 struct ast_comment *next;
1214 static void CB_INIT(void)
1216 if (!comment_buffer) {
1217 comment_buffer = ast_malloc(CB_INCR);
1218 if (!comment_buffer)
1220 comment_buffer[0] = 0;
1221 comment_buffer_size = CB_INCR;
1222 lline_buffer = ast_malloc(CB_INCR);
1225 lline_buffer[0] = 0;
1226 lline_buffer_size = CB_INCR;
1228 comment_buffer[0] = 0;
1229 lline_buffer[0] = 0;
1233 static void CB_ADD(char *str)
1235 int rem = comment_buffer_size - strlen(comment_buffer) - 1;
1236 int siz = strlen(str);
1238 comment_buffer = ast_realloc(comment_buffer, comment_buffer_size + CB_INCR + siz + 1);
1239 if (!comment_buffer)
1241 comment_buffer_size += CB_INCR+siz+1;
1243 strcat(comment_buffer,str);
1246 static void CB_ADD_LEN(char *str, int len)
1248 int cbl = strlen(comment_buffer) + 1;
1249 int rem = comment_buffer_size - cbl;
1251 comment_buffer = ast_realloc(comment_buffer, comment_buffer_size + CB_INCR + len + 1);
1252 if (!comment_buffer)
1254 comment_buffer_size += CB_INCR+len+1;
1256 strncat(comment_buffer,str,len); /* safe */
1257 comment_buffer[cbl+len-1] = 0;
1260 static void LLB_ADD(char *str)
1262 int rem = lline_buffer_size - strlen(lline_buffer) - 1;
1263 int siz = strlen(str);
1265 lline_buffer = ast_realloc(lline_buffer, lline_buffer_size + CB_INCR + siz + 1);
1268 lline_buffer_size += CB_INCR + siz + 1;
1270 strcat(lline_buffer,str);
1273 static void CB_RESET(void )
1275 comment_buffer[0] = 0;
1276 lline_buffer[0] = 0;
1279 /*! \brief Keep track of how many threads are currently trying to wait*() on
1280 * a child process */
1281 static unsigned int safe_system_level = 0;
1282 static struct sigaction safe_system_prev_handler;
1284 /*! \brief NULL handler so we can collect the child exit status */
1285 static void _null_sig_handler(int sig)
1290 static struct sigaction null_sig_handler = {
1291 .sa_handler = _null_sig_handler,
1292 .sa_flags = SA_RESTART,
1295 void ast_replace_sigchld(void);
1297 void ast_replace_sigchld(void)
1301 level = safe_system_level++;
1303 /* only replace the handler if it has not already been done */
1305 sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
1309 void ast_unreplace_sigchld(void);
1311 void ast_unreplace_sigchld(void)
1315 level = --safe_system_level;
1317 /* only restore the handler if we are the last one */
1319 sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
1323 int ast_safe_system(const char *s);
1325 int ast_safe_system(const char *s)
1328 #ifdef HAVE_WORKING_FORK
1332 struct rusage rusage;
1335 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
1336 ast_replace_sigchld();
1338 #ifdef HAVE_WORKING_FORK
1345 #ifdef HAVE_WORKING_FORK
1346 /* Close file descriptors and launch system command */
1347 for (x = STDERR_FILENO + 1; x < 4096; x++)
1350 execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
1352 } else if (pid > 0) {
1354 res = wait4(pid, &status, 0, &rusage);
1356 res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
1358 } else if (errno != EINTR)
1362 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
1366 ast_unreplace_sigchld();
1374 static struct ast_comment *ALLOC_COMMENT(const char *buffer)
1376 struct ast_comment *x = ast_calloc(1,sizeof(struct ast_comment)+strlen(buffer)+1);
1377 strcpy(x->cmt, buffer);
1381 static struct ast_config_map {
1382 struct ast_config_map *next;
1388 } *config_maps = NULL;
1390 static struct ast_config_engine *config_engine_list;
1392 #define MAX_INCLUDE_LEVEL 10
1395 struct ast_category {
1397 int ignored; /*!< do not let user of the config see this category */
1399 char *file; /*!< the file name from whence this declaration was read */
1401 struct ast_comment *precomments;
1402 struct ast_comment *sameline;
1403 struct ast_variable *root;
1404 struct ast_variable *last;
1405 struct ast_category *next;
1409 struct ast_category *root;
1410 struct ast_category *last;
1411 struct ast_category *current;
1412 struct ast_category *last_browse; /*!< used to cache the last category supplied via category_browse */
1414 int max_include_level;
1415 struct ast_config_include *includes; /*!< a list of inclusions, which should describe the entire tree */
1418 struct ast_config_include {
1419 char *include_location_file; /*!< file name in which the include occurs */
1420 int include_location_lineno; /*!< lineno where include occurred */
1421 int exec; /*!< set to non-zero if itsa #exec statement */
1422 char *exec_file; /*!< if it's an exec, you'll have both the /var/tmp to read, and the original script */
1423 char *included_file; /*!< file name included */
1424 int inclusion_count; /*!< if the file is included more than once, a running count thereof -- but, worry not,
1425 we explode the instances and will include those-- so all entries will be unique */
1426 int output; /*!< a flag to indicate if the inclusion has been output */
1427 struct ast_config_include *next; /*!< ptr to next inclusion in the list */
1430 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);
1431 typedef struct ast_variable *realtime_var_get(const char *database, const char *table, va_list ap);
1432 typedef struct ast_config *realtime_multi_get(const char *database, const char *table, va_list ap);
1433 typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
1435 /*! \brief Configuration engine structure, used to define realtime drivers */
1436 struct ast_config_engine {
1438 config_load_func *load_func;
1439 realtime_var_get *realtime_func;
1440 realtime_multi_get *realtime_multi_func;
1441 realtime_update *update_func;
1442 struct ast_config_engine *next;
1445 static struct ast_config_engine *config_engine_list;
1447 /* taken from strings.h */
1449 static force_inline int ast_strlen_zero(const char *s)
1451 return (!s || (*s == '\0'));
1454 #define S_OR(a, b) (!ast_strlen_zero(a) ? (a) : (b))
1457 void ast_copy_string(char *dst, const char *src, size_t size),
1459 while (*src && size) {
1463 if (__builtin_expect(!size, 0))
1470 char *ast_skip_blanks(const char *str),
1472 while (*str && *str < 33)
1479 \brief Trims trailing whitespace characters from a string.
1480 \param ast_trim_blanks function being used
1481 \param str the input string
1482 \return a pointer to the modified string
1485 char *ast_trim_blanks(char *str),
1490 work += strlen(work) - 1;
1491 /* It's tempting to only want to erase after we exit this loop,
1492 but since ast_trim_blanks *could* receive a constant string
1493 (which we presumably wouldn't have to touch), we shouldn't
1494 actually set anything unless we must, and it's easier just
1495 to set each position to \0 than to keep track of a variable
1497 while ((work >= str) && *work < 33)
1505 \brief Strip leading/trailing whitespace from a string.
1506 \param s The string to be stripped (will be modified).
1507 \return The stripped string.
1509 This functions strips all leading and trailing whitespace
1510 characters from the input string, and returns a pointer to
1511 the resulting string. The string is modified in place.
1514 char *ast_strip(char *s),
1516 s = ast_skip_blanks(s);
1526 struct ast_variable {
1531 int object; /*!< 0 for variable, 1 for object */
1532 int blanklines; /*!< Number of blanklines following entry */
1533 struct ast_comment *precomments;
1534 struct ast_comment *sameline;
1535 struct ast_variable *next;
1539 static const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable);
1540 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);
1542 struct ast_config *localized_config_load_with_comments(const char *filename);
1543 static char *ast_category_browse(struct ast_config *config, const char *prev);
1544 static struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category);
1545 static void ast_variables_destroy(struct ast_variable *v);
1546 static void ast_config_destroy(struct ast_config *cfg);
1547 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);
1548 static struct ast_config_include *ast_include_find(struct ast_config *conf, const char *included_file);
1549 void localized_ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file);
1551 static struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename);
1553 static struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename)
1555 struct ast_variable *variable;
1556 int name_len = strlen(name) + 1;
1558 if ((variable = ast_calloc(1, name_len + strlen(value) + 1 + strlen(filename) + 1 + sizeof(*variable)))) {
1559 variable->name = variable->stuff;
1560 variable->value = variable->stuff + name_len;
1561 variable->file = variable->value + strlen(value) + 1;
1562 strcpy(variable->name,name);
1563 strcpy(variable->value,value);
1564 strcpy(variable->file,filename);
1570 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)
1572 /* a file should be included ONCE. Otherwise, if one of the instances is changed,
1573 then all be changed. -- how do we know to include it? -- Handling modified
1574 instances is possible, I'd have
1575 to create a new master for each instance. */
1576 struct ast_config_include *inc;
1578 inc = ast_include_find(conf, included_file);
1581 inc->inclusion_count++;
1582 snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count);
1583 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);
1585 *real_included_file_name = 0;
1587 inc = ast_calloc(1,sizeof(struct ast_config_include));
1588 inc->include_location_file = ast_strdup(from_file);
1589 inc->include_location_lineno = from_lineno;
1590 if (!ast_strlen_zero(real_included_file_name))
1591 inc->included_file = ast_strdup(real_included_file_name);
1593 inc->included_file = ast_strdup(included_file);
1595 inc->exec = is_exec;
1597 inc->exec_file = ast_strdup(exec_file);
1599 /* attach this new struct to the conf struct */
1600 inc->next = conf->includes;
1601 conf->includes = inc;
1606 void localized_ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
1608 struct ast_config_include *incl;
1609 struct ast_category *cat;
1610 struct ast_variable *v;
1612 int from_len = strlen(from_file);
1613 int to_len = strlen(to_file);
1615 if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */
1618 /* the manager code allows you to read in one config file, then
1619 write it back out under a different name. But, the new arrangement
1620 ties output lines to the file name. So, before you try to write
1621 the config file to disk, better riffle thru the data and make sure
1622 the file names are changed.
1624 /* file names are on categories, includes (of course), and on variables. So,
1625 traverse all this and swap names */
1627 for (incl = conf->includes; incl; incl=incl->next) {
1628 if (strcmp(incl->include_location_file,from_file) == 0) {
1629 if (from_len >= to_len)
1630 strcpy(incl->include_location_file, to_file);
1632 free(incl->include_location_file);
1633 incl->include_location_file = strdup(to_file);
1637 for (cat = conf->root; cat; cat = cat->next) {
1638 if (strcmp(cat->file,from_file) == 0) {
1639 if (from_len >= to_len)
1640 strcpy(cat->file, to_file);
1643 cat->file = strdup(to_file);
1646 for (v = cat->root; v; v = v->next) {
1647 if (strcmp(v->file,from_file) == 0) {
1648 if (from_len >= to_len)
1649 strcpy(v->file, to_file);
1652 v->file = strdup(to_file);
1659 static struct ast_config_include *ast_include_find(struct ast_config *conf, const char *included_file)
1661 struct ast_config_include *x;
1662 for (x=conf->includes;x;x=x->next)
1664 if (strcmp(x->included_file,included_file) == 0)
1671 static void ast_variable_append(struct ast_category *category, struct ast_variable *variable);
1673 static void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
1678 category->last->next = variable;
1680 category->root = variable;
1681 category->last = variable;
1682 while (category->last->next)
1683 category->last = category->last->next;
1686 static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored);
1688 static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored)
1690 struct ast_category *cat;
1692 /* try exact match first, then case-insensitive match */
1693 for (cat = config->root; cat; cat = cat->next) {
1694 if (cat->name == category_name && (ignored || !cat->ignored))
1698 for (cat = config->root; cat; cat = cat->next) {
1699 if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored))
1706 static struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name)
1708 return category_get(config, category_name, 0);
1711 static struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category)
1713 struct ast_category *cat = NULL;
1715 if (category && config->last_browse && (config->last_browse->name == category))
1716 cat = config->last_browse;
1718 cat = ast_category_get(config, category);
1720 return (cat) ? cat->root : NULL;
1723 static const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
1725 struct ast_variable *v;
1728 for (v = ast_variable_browse(config, category); v; v = v->next) {
1729 if (!strcasecmp(variable, v->name))
1733 struct ast_category *cat;
1735 for (cat = config->root; cat; cat = cat->next)
1736 for (v = cat->root; v; v = v->next)
1737 if (!strcasecmp(variable, v->name))
1744 static struct ast_variable *variable_clone(const struct ast_variable *old)
1746 struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
1749 new->lineno = old->lineno;
1750 new->object = old->object;
1751 new->blanklines = old->blanklines;
1752 /* TODO: clone comments? */
1758 static void ast_variables_destroy(struct ast_variable *v)
1760 struct ast_variable *vn;
1769 static void ast_includes_destroy(struct ast_config_include *incls)
1771 struct ast_config_include *incl,*inclnext;
1773 for (incl=incls; incl; incl = inclnext) {
1774 inclnext = incl->next;
1775 if (incl->include_location_file)
1776 free(incl->include_location_file);
1777 if (incl->exec_file)
1778 free(incl->exec_file);
1779 if (incl->included_file)
1780 free(incl->included_file);
1785 static void ast_config_destroy(struct ast_config *cfg)
1787 struct ast_category *cat, *catn;
1792 ast_includes_destroy(cfg->includes);
1796 ast_variables_destroy(cat->root);
1804 enum ast_option_flags {
1805 /*! Allow \#exec in config files */
1806 AST_OPT_FLAG_EXEC_INCLUDES = (1 << 0),
1807 /*! Do not fork() */
1808 AST_OPT_FLAG_NO_FORK = (1 << 1),
1810 AST_OPT_FLAG_QUIET = (1 << 2),
1812 AST_OPT_FLAG_CONSOLE = (1 << 3),
1813 /*! Run in realtime Linux priority */
1814 AST_OPT_FLAG_HIGH_PRIORITY = (1 << 4),
1815 /*! Initialize keys for RSA authentication */
1816 AST_OPT_FLAG_INIT_KEYS = (1 << 5),
1817 /*! Remote console */
1818 AST_OPT_FLAG_REMOTE = (1 << 6),
1819 /*! Execute an asterisk CLI command upon startup */
1820 AST_OPT_FLAG_EXEC = (1 << 7),
1821 /*! Don't use termcap colors */
1822 AST_OPT_FLAG_NO_COLOR = (1 << 8),
1823 /*! Are we fully started yet? */
1824 AST_OPT_FLAG_FULLY_BOOTED = (1 << 9),
1825 /*! Trascode via signed linear */
1826 AST_OPT_FLAG_TRANSCODE_VIA_SLIN = (1 << 10),
1827 /*! Dump core on a seg fault */
1828 AST_OPT_FLAG_DUMP_CORE = (1 << 12),
1829 /*! Cache sound files */
1830 AST_OPT_FLAG_CACHE_RECORD_FILES = (1 << 13),
1831 /*! Display timestamp in CLI verbose output */
1832 AST_OPT_FLAG_TIMESTAMP = (1 << 14),
1833 /*! Override config */
1834 AST_OPT_FLAG_OVERRIDE_CONFIG = (1 << 15),
1836 AST_OPT_FLAG_RECONNECT = (1 << 16),
1837 /*! Transmit Silence during Record() and DTMF Generation */
1838 AST_OPT_FLAG_TRANSMIT_SILENCE = (1 << 17),
1839 /*! Suppress some warnings */
1840 AST_OPT_FLAG_DONT_WARN = (1 << 18),
1841 /*! End CDRs before the 'h' extension */
1842 AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN = (1 << 19),
1843 /*! Use DAHDI Timing for generators if available */
1844 AST_OPT_FLAG_INTERNAL_TIMING = (1 << 20),
1845 /*! Always fork, even if verbose or debug settings are non-zero */
1846 AST_OPT_FLAG_ALWAYS_FORK = (1 << 21),
1847 /*! Disable log/verbose output to remote consoles */
1848 AST_OPT_FLAG_MUTE = (1 << 22),
1849 /*! There is a per-file debug setting */
1850 AST_OPT_FLAG_DEBUG_FILE = (1 << 23),
1851 /*! There is a per-file verbose setting */
1852 AST_OPT_FLAG_VERBOSE_FILE = (1 << 24),
1853 /*! Terminal colors should be adjusted for a light-colored background */
1854 AST_OPT_FLAG_LIGHT_BACKGROUND = (1 << 25),
1855 /*! Count Initiated seconds in CDR's */
1856 AST_OPT_FLAG_INITIATED_SECONDS = (1 << 26),
1857 /*! Force black background */
1858 AST_OPT_FLAG_FORCE_BLACK_BACKGROUND = (1 << 27),
1861 /* options.h declares ast_options extern; I need it static? */
1862 #define AST_CACHE_DIR_LEN 512
1863 #define AST_FILENAME_MAX 80
1865 /*! These are the options that set by default when Asterisk starts */
1866 #define AST_DEFAULT_OPTIONS AST_OPT_FLAG_TRANSCODE_VIA_SLIN
1868 struct ast_flags ast_options = { AST_DEFAULT_OPTIONS };
1870 #define ast_opt_exec_includes ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES)
1871 #define ast_opt_no_fork ast_test_flag(&ast_options, AST_OPT_FLAG_NO_FORK)
1872 #define ast_opt_quiet ast_test_flag(&ast_options, AST_OPT_FLAG_QUIET)
1873 #define ast_opt_console ast_test_flag(&ast_options, AST_OPT_FLAG_CONSOLE)
1874 #define ast_opt_high_priority ast_test_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY)
1875 #define ast_opt_init_keys ast_test_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS)
1876 #define ast_opt_remote ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)
1877 #define ast_opt_exec ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC)
1878 #define ast_opt_no_color ast_test_flag(&ast_options, AST_OPT_FLAG_NO_COLOR)
1879 #define ast_fully_booted ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)
1880 #define ast_opt_transcode_via_slin ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN)
1881 #define ast_opt_priority_jumping ast_test_flag(&ast_options, AST_OPT_FLAG_PRIORITY_JUMPING)
1882 #define ast_opt_dump_core ast_test_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE)
1883 #define ast_opt_cache_record_files ast_test_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES)
1884 #define ast_opt_timestamp ast_test_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP)
1885 #define ast_opt_override_config ast_test_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG)
1886 #define ast_opt_reconnect ast_test_flag(&ast_options, AST_OPT_FLAG_RECONNECT)
1887 #define ast_opt_transmit_silence ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE)
1888 #define ast_opt_dont_warn ast_test_flag(&ast_options, AST_OPT_FLAG_DONT_WARN)
1889 #define ast_opt_end_cdr_before_h_exten ast_test_flag(&ast_options, AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN)
1890 #define ast_opt_internal_timing ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING)
1891 #define ast_opt_always_fork ast_test_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK)
1892 #define ast_opt_mute ast_test_flag(&ast_options, AST_OPT_FLAG_MUTE)
1894 extern int option_verbose;
1895 extern int option_debug; /*!< Debugging */
1896 extern int option_maxcalls; /*!< Maximum number of simultaneous channels */
1897 extern double option_maxload;
1898 extern char defaultlanguage[];
1900 extern pid_t ast_mainpid;
1902 extern char record_cache_dir[AST_CACHE_DIR_LEN];
1903 extern char debug_filename[AST_FILENAME_MAX];
1905 extern int ast_language_is_prefix;
1911 #define AST_LIST_LOCK(head) \
1912 ast_mutex_lock(&(head)->lock)
1915 \brief Write locks a list.
1916 \param head This is a pointer to the list head structure
1918 This macro attempts to place an exclusive write lock in the
1919 list head structure pointed to by head.
1920 Returns non-zero on success, 0 on failure
1922 #define AST_RWLIST_WRLOCK(head) \
1923 ast_rwlock_wrlock(&(head)->lock)
1926 \brief Read locks a list.
1927 \param head This is a pointer to the list head structure
1929 This macro attempts to place a read lock in the
1930 list head structure pointed to by head.
1931 Returns non-zero on success, 0 on failure
1933 #define AST_RWLIST_RDLOCK(head) \
1934 ast_rwlock_rdlock(&(head)->lock)
1937 \brief Locks a list, without blocking if the list is locked.
1938 \param head This is a pointer to the list head structure
1940 This macro attempts to place an exclusive lock in the
1941 list head structure pointed to by head.
1942 Returns non-zero on success, 0 on failure
1944 #define AST_LIST_TRYLOCK(head) \
1945 ast_mutex_trylock(&(head)->lock)
1948 \brief Write locks a list, without blocking if the list is locked.
1949 \param head This is a pointer to the list head structure
1951 This macro attempts to place an exclusive write lock in the
1952 list head structure pointed to by head.
1953 Returns non-zero on success, 0 on failure
1955 #define AST_RWLIST_TRYWRLOCK(head) \
1956 ast_rwlock_trywrlock(&(head)->lock)
1959 \brief Read locks a list, without blocking if the list is locked.
1960 \param head This is a pointer to the list head structure
1962 This macro attempts to place a read lock in the
1963 list head structure pointed to by head.
1964 Returns non-zero on success, 0 on failure
1966 #define AST_RWLIST_TRYRDLOCK(head) \
1967 ast_rwlock_tryrdlock(&(head)->lock)
1970 \brief Attempts to unlock a list.
1971 \param head This is a pointer to the list head structure
1973 This macro attempts to remove an exclusive lock from the
1974 list head structure pointed to by head. If the list
1975 was not locked by this thread, this macro has no effect.
1977 #define AST_LIST_UNLOCK(head) \
1978 ast_mutex_unlock(&(head)->lock)
1981 \brief Attempts to unlock a read/write based list.
1982 \param head This is a pointer to the list head structure
1984 This macro attempts to remove a read or write lock from the
1985 list head structure pointed to by head. If the list
1986 was not locked by this thread, this macro has no effect.
1988 #define AST_RWLIST_UNLOCK(head) \
1989 ast_rwlock_unlock(&(head)->lock)
1992 \brief Defines a structure to be used to hold a list of specified type.
1993 \param name This will be the name of the defined structure.
1994 \param type This is the type of each list entry.
1996 This macro creates a structure definition that can be used
1997 to hold a list of the entries of type \a type. It does not actually
1998 declare (allocate) a structure; to do that, either follow this
1999 macro with the desired name of the instance you wish to declare,
2000 or use the specified \a name to declare instances elsewhere.
2004 static AST_LIST_HEAD(entry_list, entry) entries;
2007 This would define \c struct \c entry_list, and declare an instance of it named
2008 \a entries, all intended to hold a list of type \c struct \c entry.
2010 #define AST_LIST_HEAD(name, type) \
2012 struct type *first; \
2013 struct type *last; \
2018 \brief Defines a structure to be used to hold a read/write list of specified type.
2019 \param name This will be the name of the defined structure.
2020 \param type This is the type of each list entry.
2022 This macro creates a structure definition that can be used
2023 to hold a list of the entries of type \a type. It does not actually
2024 declare (allocate) a structure; to do that, either follow this
2025 macro with the desired name of the instance you wish to declare,
2026 or use the specified \a name to declare instances elsewhere.
2030 static AST_RWLIST_HEAD(entry_list, entry) entries;
2033 This would define \c struct \c entry_list, and declare an instance of it named
2034 \a entries, all intended to hold a list of type \c struct \c entry.
2036 #define AST_RWLIST_HEAD(name, type) \
2038 struct type *first; \
2039 struct type *last; \
2040 ast_rwlock_t lock; \
2044 \brief Defines a structure to be used to hold a list of specified type (with no lock).
2045 \param name This will be the name of the defined structure.
2046 \param type This is the type of each list entry.
2048 This macro creates a structure definition that can be used
2049 to hold a list of the entries of type \a type. It does not actually
2050 declare (allocate) a structure; to do that, either follow this
2051 macro with the desired name of the instance you wish to declare,
2052 or use the specified \a name to declare instances elsewhere.
2056 static AST_LIST_HEAD_NOLOCK(entry_list, entry) entries;
2059 This would define \c struct \c entry_list, and declare an instance of it named
2060 \a entries, all intended to hold a list of type \c struct \c entry.
2062 #define AST_LIST_HEAD_NOLOCK(name, type) \
2064 struct type *first; \
2065 struct type *last; \
2069 \brief Defines initial values for a declaration of AST_LIST_HEAD
2071 #define AST_LIST_HEAD_INIT_VALUE { \
2074 .lock = AST_MUTEX_INIT_VALUE, \
2078 \brief Defines initial values for a declaration of AST_RWLIST_HEAD
2080 #define AST_RWLIST_HEAD_INIT_VALUE { \
2083 .lock = AST_RWLOCK_INIT_VALUE, \
2087 \brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK
2089 #define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \
2095 \brief Defines a structure to be used to hold a list of specified type, statically initialized.
2096 \param name This will be the name of the defined structure.
2097 \param type This is the type of each list entry.
2099 This macro creates a structure definition that can be used
2100 to hold a list of the entries of type \a type, and allocates an instance
2101 of it, initialized to be empty.
2105 static AST_LIST_HEAD_STATIC(entry_list, entry);
2108 This would define \c struct \c entry_list, intended to hold a list of
2109 type \c struct \c entry.
2111 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
2112 #define AST_LIST_HEAD_STATIC(name, type) \
2114 struct type *first; \
2115 struct type *last; \
2118 static void __attribute__((constructor)) init_##name(void) \
2120 AST_LIST_HEAD_INIT(&name); \
2122 static void __attribute__((destructor)) fini_##name(void) \
2124 AST_LIST_HEAD_DESTROY(&name); \
2126 struct __dummy_##name
2128 #define AST_LIST_HEAD_STATIC(name, type) \
2130 struct type *first; \
2131 struct type *last; \
2133 } name = AST_LIST_HEAD_INIT_VALUE
2137 \brief Defines a structure to be used to hold a read/write list of specified type, statically initialized.
2138 \param name This will be the name of the defined structure.
2139 \param type This is the type of each list entry.
2141 This macro creates a structure definition that can be used
2142 to hold a list of the entries of type \a type, and allocates an instance
2143 of it, initialized to be empty.
2147 static AST_RWLIST_HEAD_STATIC(entry_list, entry);
2150 This would define \c struct \c entry_list, intended to hold a list of
2151 type \c struct \c entry.
2153 #ifndef AST_RWLOCK_INIT_VALUE
2154 #define AST_RWLIST_HEAD_STATIC(name, type) \
2156 struct type *first; \
2157 struct type *last; \
2158 ast_rwlock_t lock; \
2160 static void __attribute__((constructor)) init_##name(void) \
2162 AST_RWLIST_HEAD_INIT(&name); \
2164 static void __attribute__((destructor)) fini_##name(void) \
2166 AST_RWLIST_HEAD_DESTROY(&name); \
2168 struct __dummy_##name
2170 #define AST_RWLIST_HEAD_STATIC(name, type) \
2172 struct type *first; \
2173 struct type *last; \
2174 ast_rwlock_t lock; \
2175 } name = AST_RWLIST_HEAD_INIT_VALUE
2179 \brief Defines a structure to be used to hold a list of specified type, statically initialized.
2181 This is the same as AST_LIST_HEAD_STATIC, except without the lock included.
2183 #define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \
2185 struct type *first; \
2186 struct type *last; \
2187 } name = AST_LIST_HEAD_NOLOCK_INIT_VALUE
2190 \brief Initializes a list head structure with a specified first entry.
2191 \param head This is a pointer to the list head structure
2192 \param entry pointer to the list entry that will become the head of the list
2194 This macro initializes a list head structure by setting the head
2195 entry to the supplied value and recreating the embedded lock.
2197 #define AST_LIST_HEAD_SET(head, entry) do { \
2198 (head)->first = (entry); \
2199 (head)->last = (entry); \
2200 ast_mutex_init(&(head)->lock); \
2204 \brief Initializes an rwlist head structure with a specified first entry.
2205 \param head This is a pointer to the list head structure
2206 \param entry pointer to the list entry that will become the head of the list
2208 This macro initializes a list head structure by setting the head
2209 entry to the supplied value and recreating the embedded lock.
2211 #define AST_RWLIST_HEAD_SET(head, entry) do { \
2212 (head)->first = (entry); \
2213 (head)->last = (entry); \
2214 ast_rwlock_init(&(head)->lock); \
2218 \brief Initializes a list head structure with a specified first entry.
2219 \param head This is a pointer to the list head structure
2220 \param entry pointer to the list entry that will become the head of the list
2222 This macro initializes a list head structure by setting the head
2223 entry to the supplied value.
2225 #define AST_LIST_HEAD_SET_NOLOCK(head, entry) do { \
2226 (head)->first = (entry); \
2227 (head)->last = (entry); \
2231 \brief Declare a forward link structure inside a list entry.
2232 \param type This is the type of each list entry.
2234 This macro declares a structure to be used to link list entries together.
2235 It must be used inside the definition of the structure named in
2236 \a type, as follows:
2241 AST_LIST_ENTRY(list_entry) list;
2245 The field name \a list here is arbitrary, and can be anything you wish.
2247 #define AST_LIST_ENTRY(type) \
2249 struct type *next; \
2252 #define AST_RWLIST_ENTRY AST_LIST_ENTRY
2255 \brief Returns the first entry contained in a list.
2256 \param head This is a pointer to the list head structure
2258 #define AST_LIST_FIRST(head) ((head)->first)
2260 #define AST_RWLIST_FIRST AST_LIST_FIRST
2263 \brief Returns the last entry contained in a list.
2264 \param head This is a pointer to the list head structure
2266 #define AST_LIST_LAST(head) ((head)->last)
2268 #define AST_RWLIST_LAST AST_LIST_LAST
2271 \brief Returns the next entry in the list after the given entry.
2272 \param elm This is a pointer to the current entry.
2273 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2274 used to link entries of this list together.
2276 #define AST_LIST_NEXT(elm, field) ((elm)->field.next)
2278 #define AST_RWLIST_NEXT AST_LIST_NEXT
2281 \brief Checks whether the specified list contains any entries.
2282 \param head This is a pointer to the list head structure
2284 Returns non-zero if the list has entries, zero if not.
2286 #define AST_LIST_EMPTY(head) (AST_LIST_FIRST(head) == NULL)
2288 #define AST_RWLIST_EMPTY AST_LIST_EMPTY
2291 \brief Loops over (traverses) the entries in a list.
2292 \param head This is a pointer to the list head structure
2293 \param var This is the name of the variable that will hold a pointer to the
2294 current list entry on each iteration. It must be declared before calling
2296 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2297 used to link entries of this list together.
2299 This macro is use to loop over (traverse) the entries in a list. It uses a
2300 \a for loop, and supplies the enclosed code with a pointer to each list
2301 entry as it loops. It is typically used as follows:
2303 static AST_LIST_HEAD(entry_list, list_entry) entries;
2307 AST_LIST_ENTRY(list_entry) list;
2310 struct list_entry *current;
2312 AST_LIST_TRAVERSE(&entries, current, list) {
2313 (do something with current here)
2316 \warning If you modify the forward-link pointer contained in the \a current entry while
2317 inside the loop, the behavior will be unpredictable. At a minimum, the following
2318 macros will modify the forward-link pointer, and should not be used inside
2319 AST_LIST_TRAVERSE() against the entry pointed to by the \a current pointer without
2320 careful consideration of their consequences:
2321 \li AST_LIST_NEXT() (when used as an lvalue)
2322 \li AST_LIST_INSERT_AFTER()
2323 \li AST_LIST_INSERT_HEAD()
2324 \li AST_LIST_INSERT_TAIL()
2326 #define AST_LIST_TRAVERSE(head,var,field) \
2327 for((var) = (head)->first; (var); (var) = (var)->field.next)
2329 #define AST_RWLIST_TRAVERSE AST_LIST_TRAVERSE
2332 \brief Loops safely over (traverses) the entries in a list.
2333 \param head This is a pointer to the list head structure
2334 \param var This is the name of the variable that will hold a pointer to the
2335 current list entry on each iteration. It must be declared before calling
2337 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2338 used to link entries of this list together.
2340 This macro is used to safely loop over (traverse) the entries in a list. It
2341 uses a \a for loop, and supplies the enclosed code with a pointer to each list
2342 entry as it loops. It is typically used as follows:
2345 static AST_LIST_HEAD(entry_list, list_entry) entries;
2349 AST_LIST_ENTRY(list_entry) list;
2352 struct list_entry *current;
2354 AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
2355 (do something with current here)
2357 AST_LIST_TRAVERSE_SAFE_END;
2360 It differs from AST_LIST_TRAVERSE() in that the code inside the loop can modify
2361 (or even free, after calling AST_LIST_REMOVE_CURRENT()) the entry pointed to by
2362 the \a current pointer without affecting the loop traversal.
2364 #define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) { \
2365 typeof((head)->first) __list_next; \
2366 typeof((head)->first) __list_prev = NULL; \
2367 typeof((head)->first) __new_prev = NULL; \
2368 for ((var) = (head)->first, __new_prev = (var), \
2369 __list_next = (var) ? (var)->field.next : NULL; \
2371 __list_prev = __new_prev, (var) = __list_next, \
2372 __new_prev = (var), \
2373 __list_next = (var) ? (var)->field.next : NULL \
2376 #define AST_RWLIST_TRAVERSE_SAFE_BEGIN AST_LIST_TRAVERSE_SAFE_BEGIN
2379 \brief Removes the \a current entry from a list during a traversal.
2380 \param head This is a pointer to the list head structure
2381 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2382 used to link entries of this list together.
2384 \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
2385 block; it is used to unlink the current entry from the list without affecting
2386 the list traversal (and without having to re-traverse the list to modify the
2387 previous entry, if any).
2389 #define AST_LIST_REMOVE_CURRENT(head, field) \
2390 __new_prev->field.next = NULL; \
2391 __new_prev = __list_prev; \
2393 __list_prev->field.next = __list_next; \
2395 (head)->first = __list_next; \
2397 (head)->last = __list_prev;
2399 #define AST_RWLIST_REMOVE_CURRENT AST_LIST_REMOVE_CURRENT
2402 \brief Inserts a list entry before the current entry during a traversal.
2403 \param head This is a pointer to the list head structure
2404 \param elm This is a pointer to the entry to be inserted.
2405 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2406 used to link entries of this list together.
2408 \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
2411 #define AST_LIST_INSERT_BEFORE_CURRENT(head, elm, field) do { \
2412 if (__list_prev) { \
2413 (elm)->field.next = __list_prev->field.next; \
2414 __list_prev->field.next = elm; \
2416 (elm)->field.next = (head)->first; \
2417 (head)->first = (elm); \
2419 __new_prev = (elm); \
2422 #define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT
2425 \brief Closes a safe loop traversal block.
2427 #define AST_LIST_TRAVERSE_SAFE_END }
2429 #define AST_RWLIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END
2432 \brief Initializes a list head structure.
2433 \param head This is a pointer to the list head structure
2435 This macro initializes a list head structure by setting the head
2436 entry to \a NULL (empty list) and recreating the embedded lock.
2438 #define AST_LIST_HEAD_INIT(head) { \
2439 (head)->first = NULL; \
2440 (head)->last = NULL; \
2441 ast_mutex_init(&(head)->lock); \
2445 \brief Initializes an rwlist head structure.
2446 \param head This is a pointer to the list head structure
2448 This macro initializes a list head structure by setting the head
2449 entry to \a NULL (empty list) and recreating the embedded lock.
2451 #define AST_RWLIST_HEAD_INIT(head) { \
2452 (head)->first = NULL; \
2453 (head)->last = NULL; \
2454 ast_rwlock_init(&(head)->lock); \
2458 \brief Destroys a list head structure.
2459 \param head This is a pointer to the list head structure
2461 This macro destroys a list head structure by setting the head
2462 entry to \a NULL (empty list) and destroying the embedded lock.
2463 It does not free the structure from memory.
2465 #define AST_LIST_HEAD_DESTROY(head) { \
2466 (head)->first = NULL; \
2467 (head)->last = NULL; \
2468 ast_mutex_destroy(&(head)->lock); \
2472 \brief Destroys an rwlist head structure.
2473 \param head This is a pointer to the list head structure
2475 This macro destroys a list head structure by setting the head
2476 entry to \a NULL (empty list) and destroying the embedded lock.
2477 It does not free the structure from memory.
2479 #define AST_RWLIST_HEAD_DESTROY(head) { \
2480 (head)->first = NULL; \
2481 (head)->last = NULL; \
2482 ast_rwlock_destroy(&(head)->lock); \
2486 \brief Initializes a list head structure.
2487 \param head This is a pointer to the list head structure
2489 This macro initializes a list head structure by setting the head
2490 entry to \a NULL (empty list). There is no embedded lock handling
2493 #define AST_LIST_HEAD_INIT_NOLOCK(head) { \
2494 (head)->first = NULL; \
2495 (head)->last = NULL; \
2499 \brief Inserts a list entry after a given entry.
2500 \param head This is a pointer to the list head structure
2501 \param listelm This is a pointer to the entry after which the new entry should
2503 \param elm This is a pointer to the entry to be inserted.
2504 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2505 used to link entries of this list together.
2507 #define AST_LIST_INSERT_AFTER(head, listelm, elm, field) do { \
2508 (elm)->field.next = (listelm)->field.next; \
2509 (listelm)->field.next = (elm); \
2510 if ((head)->last == (listelm)) \
2511 (head)->last = (elm); \
2514 #define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER
2517 \brief Inserts a list entry at the head of a list.
2518 \param head This is a pointer to the list head structure
2519 \param elm This is a pointer to the entry to be inserted.
2520 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2521 used to link entries of this list together.
2523 #define AST_LIST_INSERT_HEAD(head, elm, field) do { \
2524 (elm)->field.next = (head)->first; \
2525 (head)->first = (elm); \
2526 if (!(head)->last) \
2527 (head)->last = (elm); \
2530 #define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD
2533 \brief Appends a list entry to the tail of a list.
2534 \param head This is a pointer to the list head structure
2535 \param elm This is a pointer to the entry to be appended.
2536 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2537 used to link entries of this list together.
2539 Note: The link field in the appended entry is \b not modified, so if it is
2540 actually the head of a list itself, the entire list will be appended
2541 temporarily (until the next AST_LIST_INSERT_TAIL is performed).
2543 #define AST_LIST_INSERT_TAIL(head, elm, field) do { \
2544 if (!(head)->first) { \
2545 (head)->first = (elm); \
2546 (head)->last = (elm); \
2548 (head)->last->field.next = (elm); \
2549 (head)->last = (elm); \
2553 #define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL
2556 \brief Appends a whole list to the tail of a list.
2557 \param head This is a pointer to the list head structure
2558 \param list This is a pointer to the list to be appended.
2559 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2560 used to link entries of this list together.
2562 #define AST_LIST_APPEND_LIST(head, list, field) do { \
2563 if (!(head)->first) { \
2564 (head)->first = (list)->first; \
2565 (head)->last = (list)->last; \
2567 (head)->last->field.next = (list)->first; \
2568 (head)->last = (list)->last; \
2572 #define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST
2575 \brief Removes and returns the head entry from a list.
2576 \param head This is a pointer to the list head structure
2577 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2578 used to link entries of this list together.
2580 Removes the head entry from the list, and returns a pointer to it.
2581 This macro is safe to call on an empty list.
2583 #define AST_LIST_REMOVE_HEAD(head, field) ({ \
2584 typeof((head)->first) cur = (head)->first; \
2586 (head)->first = cur->field.next; \
2587 cur->field.next = NULL; \
2588 if ((head)->last == cur) \
2589 (head)->last = NULL; \
2594 #define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD
2597 \brief Removes a specific entry from a list.
2598 \param head This is a pointer to the list head structure
2599 \param elm This is a pointer to the entry to be removed.
2600 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2601 used to link entries of this list together.
2602 \warning The removed entry is \b not freed nor modified in any way.
2604 #define AST_LIST_REMOVE(head, elm, field) do { \
2605 if ((head)->first == (elm)) { \
2606 (head)->first = (elm)->field.next; \
2607 if ((head)->last == (elm)) \
2608 (head)->last = NULL; \
2610 typeof(elm) curelm = (head)->first; \
2611 while (curelm && (curelm->field.next != (elm))) \
2612 curelm = curelm->field.next; \
2614 curelm->field.next = (elm)->field.next; \
2615 if ((head)->last == (elm)) \
2616 (head)->last = curelm; \
2619 (elm)->field.next = NULL; \
2622 #define AST_RWLIST_REMOVE AST_LIST_REMOVE
2627 AST_LIST_ENTRY(ast_var_t) entries;
2632 AST_LIST_HEAD_NOLOCK(varshead, ast_var_t);
2634 AST_RWLOCK_DEFINE_STATIC(globalslock);
2635 static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
2638 /* IN CONFLICT: struct ast_var_t *ast_var_assign(const char *name, const char *value); */
2640 static struct ast_var_t *ast_var_assign(const char *name, const char *value);
2642 static void ast_var_delete(struct ast_var_t *var);
2645 #define AST_MAX_EXTENSION 80 /*!< Max length of an extension */
2649 #define PRIORITY_HINT -1 /*!< Special Priority for a hint */
2651 enum ast_extension_states {
2652 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */
2653 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */
2654 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */
2655 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */
2656 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */
2657 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */
2658 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */
2659 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */
2662 struct ast_custom_function {
2663 const char *name; /*!< Name */
2664 const char *synopsis; /*!< Short description for "show functions" */
2665 const char *desc; /*!< Help text that explains it all */
2666 const char *syntax; /*!< Syntax description */
2667 int (*read)(struct ast_channel *, const char *, char *, char *, size_t); /*!< Read function, if read is supported */
2668 int (*write)(struct ast_channel *, const char *, char *, const char *); /*!< Write function, if write is supported */
2669 AST_RWLIST_ENTRY(ast_custom_function) acflist;
2672 typedef int (ast_switch_f)(struct ast_channel *chan, const char *context,
2673 const char *exten, int priority, const char *callerid, const char *data);
2676 AST_LIST_ENTRY(ast_switch) list;
2677 const char *name; /*!< Name of the switch */
2678 const char *description; /*!< Description of the switch */
2680 ast_switch_f *exists;
2681 ast_switch_f *canmatch;
2683 ast_switch_f *matchmore;
2687 static char *config_filename = "extensions.conf";
2688 static char *global_registrar = "conf2ael";
2689 static char userscontext[AST_MAX_EXTENSION] = "default";
2690 static int static_config = 0;
2691 static int write_protect_config = 1;
2692 static int autofallthrough_config = 0;
2693 static int clearglobalvars_config = 0;
2694 /*! Go no deeper than this through includes (not counting loops) */
2695 #define AST_PBX_MAX_STACK 128
2696 static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
2699 /* stolen from callerid.c */
2701 /*! \brief Clean up phone string
2702 * remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets.
2703 * Basically, remove anything that could be invalid in a pattern.
2705 static void ast_shrink_phone_number(char *n)
2710 for (x=0; n[x]; x++) {
2729 if (!strchr("()", n[x]))
2737 /* stolen from chanvars.c */
2739 static const char *ast_var_name(const struct ast_var_t *var)
2743 if (var == NULL || (name = var->name) == NULL)
2745 /* Return the name without the initial underscores */
2746 if (name[0] == '_') {
2754 /* experiment 1: see if it's easier just to use existing config code
2755 * to read in the extensions.conf file. In this scenario,
2756 I have to rip/copy code from other modules, because they
2757 are staticly declared as-is. A solution would be to move
2758 the ripped code to another location and make them available
2759 to other modules and standalones */
2761 /* Our own version of ast_log, since the expr parser uses it. -- stolen from utils/check_expr.c */
2763 static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
2768 printf("LOG: lev:%d file:%s line:%d func: %s ",
2769 level, file, line, function);
2775 void __attribute__((format(printf, 1, 2))) ast_verbose(const char *fmt, ...)
2780 printf("VERBOSE: ");
2786 /* stolen from main/utils.c */
2787 static char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
2789 char *dataPut = start;
2793 for (; *start; start++) {
2795 *dataPut++ = *start; /* Always goes verbatim */
2798 if (*start == '\\') {
2799 inEscape = 1; /* Do not copy \ into the data */
2800 } else if (*start == '\'') {
2801 inQuotes = 1 - inQuotes; /* Do not copy ' into the data */
2803 /* Replace , with |, unless in quotes */
2804 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
2808 if (start != dataPut)
2813 static int ast_true(const char *s)
2815 if (ast_strlen_zero(s))
2818 /* Determine if this is a true value */
2819 if (!strcasecmp(s, "yes") ||
2820 !strcasecmp(s, "true") ||
2821 !strcasecmp(s, "y") ||
2822 !strcasecmp(s, "t") ||
2823 !strcasecmp(s, "1") ||
2824 !strcasecmp(s, "on"))
2830 #define ONE_MILLION 1000000
2832 * put timeval in a valid range. usec is 0..999999
2833 * negative values are not allowed and truncated.
2835 static struct timeval tvfix(struct timeval a)
2837 if (a.tv_usec >= ONE_MILLION) {
2838 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
2839 (long)a.tv_sec, (long int) a.tv_usec);
2840 a.tv_sec += a.tv_usec / ONE_MILLION;
2841 a.tv_usec %= ONE_MILLION;
2842 } else if (a.tv_usec < 0) {
2843 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
2844 (long)a.tv_sec, (long int) a.tv_usec);
2850 struct timeval ast_tvadd(struct timeval a, struct timeval b);
2851 struct timeval ast_tvadd(struct timeval a, struct timeval b)
2853 /* consistency checks to guarantee usec in 0..999999 */
2856 a.tv_sec += b.tv_sec;
2857 a.tv_usec += b.tv_usec;
2858 if (a.tv_usec >= ONE_MILLION) {
2860 a.tv_usec -= ONE_MILLION;
2865 struct timeval ast_tvsub(struct timeval a, struct timeval b);
2866 struct timeval ast_tvsub(struct timeval a, struct timeval b)
2868 /* consistency checks to guarantee usec in 0..999999 */
2871 a.tv_sec -= b.tv_sec;
2872 a.tv_usec -= b.tv_usec;
2873 if (a.tv_usec < 0) {
2875 a.tv_usec += ONE_MILLION;
2881 void ast_mark_lock_failed(void *lock_addr);
2882 void ast_mark_lock_failed(void *lock_addr)
2884 /* Pretend to do something. */
2887 /* stolen from pbx.c */
2888 #define VAR_BUF_SIZE 4096
2890 #define VAR_NORMAL 1
2891 #define VAR_SOFTTRAN 2
2892 #define VAR_HARDTRAN 3
2894 #define BACKGROUND_SKIP (1 << 0)
2895 #define BACKGROUND_NOANSWER (1 << 1)
2896 #define BACKGROUND_MATCHEXTEN (1 << 2)
2897 #define BACKGROUND_PLAYBACK (1 << 3)
2900 \brief ast_exten: An extension
2901 The dialplan is saved as a linked list with each context
2902 having it's own linked list of extensions - one item per
2906 char *exten; /*!< Extension name */
2907 int matchcid; /*!< Match caller id ? */
2908 const char *cidmatch; /*!< Caller id to match for this extension */
2909 int priority; /*!< Priority */
2910 const char *label; /*!< Label */
2911 struct ast_context *parent; /*!< The context this extension belongs to */
2912 const char *app; /*!< Application to execute */
2913 struct ast_app *cached_app; /*!< Cached location of application */
2914 void *data; /*!< Data to use (arguments) */
2915 void (*datad)(void *); /*!< Data destructor */
2916 struct ast_exten *peer; /*!< Next higher priority with our extension */
2917 const char *registrar; /*!< Registrar */
2918 struct ast_exten *next; /*!< Extension with a greater ID */
2922 typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data);
2924 int hastime; /*!< If time construct exists */
2925 unsigned int monthmask; /*!< Mask for month */
2926 unsigned int daymask; /*!< Mask for date */
2927 unsigned int dowmask; /*!< Mask for day of week (mon-sun) */
2928 unsigned int minmask[48]; /*!< Mask for minute */
2929 char *timezone; /*!< NULL, or zoneinfo style timezone */
2932 /*! \brief ast_include: include= support in extensions.conf */
2933 struct ast_include {
2935 const char *rname; /*!< Context to include */
2936 const char *registrar; /*!< Registrar */
2937 int hastime; /*!< If time construct exists */
2938 struct ast_timing timing; /*!< time construct */
2939 struct ast_include *next; /*!< Link them together */
2943 /*! \brief ast_sw: Switch statement in extensions.conf */
2946 const char *registrar; /*!< Registrar */
2947 char *data; /*!< Data load */
2949 AST_LIST_ENTRY(ast_sw) list;
2954 /*! \brief ast_ignorepat: Ignore patterns in dial plan */
2955 struct ast_ignorepat {
2956 const char *registrar;
2957 struct ast_ignorepat *next;
2961 /*! \brief ast_context: An extension context */
2962 struct ast_context {
2963 ast_rwlock_t lock; /*!< A lock to prevent multiple threads from clobbering the context */
2964 struct ast_exten *root; /*!< The root of the list of extensions */
2965 struct ast_context *next; /*!< Link them together */
2966 struct ast_include *includes; /*!< Include other contexts */
2967 struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
2968 const char *registrar; /*!< Registrar */
2969 AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
2970 ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
2971 char name[0]; /*!< Name of the context */
2975 /*! \brief ast_app: A registered application */
2977 int (*execute)(struct ast_channel *chan, void *data);
2978 const char *synopsis; /*!< Synopsis text for 'show applications' */
2979 const char *description; /*!< Description (help text) for 'show application <name>' */
2980 AST_RWLIST_ENTRY(ast_app) list; /*!< Next app in list */
2981 void *module; /*!< Module this app belongs to */
2982 char name[0]; /*!< Name of the application */
2986 /*! \brief ast_state_cb: An extension state notify register item */
2987 struct ast_state_cb {
2990 ast_state_cb_type callback;
2991 struct ast_state_cb *next;
2994 /*! \brief Structure for dial plan hints
2996 \note Hints are pointers from an extension in the dialplan to one or
2997 more devices (tech/name)
2998 - See \ref AstExtState
3001 struct ast_exten *exten; /*!< Extension */
3002 int laststate; /*!< Last known state */
3003 struct ast_state_cb *callbacks; /*!< Callback list for this extension */
3004 AST_RWLIST_ENTRY(ast_hint) list;/*!< Pointer to next hint in list */
3010 struct ast_state_cb *callbacks;
3012 AST_LIST_ENTRY(store_hint) list;
3016 AST_LIST_HEAD(store_hints, store_hint);
3018 static const struct cfextension_states {
3019 int extension_state;
3020 const char * const text;
3021 } extension_states[] = {
3022 { AST_EXTENSION_NOT_INUSE, "Idle" },
3023 { AST_EXTENSION_INUSE, "InUse" },
3024 { AST_EXTENSION_BUSY, "Busy" },
3025 { AST_EXTENSION_UNAVAILABLE, "Unavailable" },
3026 { AST_EXTENSION_RINGING, "Ringing" },
3027 { AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
3028 { AST_EXTENSION_ONHOLD, "Hold" },
3029 { AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD, "InUse&Hold" }
3031 #define STATUS_NO_CONTEXT 1
3032 #define STATUS_NO_EXTENSION 2
3033 #define STATUS_NO_PRIORITY 3
3034 #define STATUS_NO_LABEL 4
3035 #define STATUS_SUCCESS 5
3038 #if defined ( __i386__) && (defined(__FreeBSD__) || defined(linux))
3039 #if defined(__FreeBSD__)
3040 #include <machine/cpufunc.h>
3041 #elif defined(linux)
3042 static __inline uint64_t
3047 __asm __volatile(".byte 0x0f, 0x31" : "=A" (rv));
3051 #else /* supply a dummy function on other platforms */
3052 static __inline uint64_t
3060 static struct ast_var_t *ast_var_assign(const char *name, const char *value)
3062 struct ast_var_t *var;
3063 int name_len = strlen(name) + 1;
3064 int value_len = strlen(value) + 1;
3066 if (!(var = ast_calloc(sizeof(*var) + name_len + value_len, sizeof(char)))) {
3070 ast_copy_string(var->name, name, name_len);
3071 var->value = var->name + name_len;
3072 ast_copy_string(var->value, value, value_len);
3077 static void ast_var_delete(struct ast_var_t *var)
3083 /* chopped this one off at the knees! */
3084 static int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
3087 /* ast_log(LOG_ERROR, "Function %s not registered\n", function); we are not interested in the details here */
3092 static unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
3096 int paren = 0, quote = 0;
3098 if (!buf || !array || !arraylen)
3101 memset(array, 0, arraylen * sizeof(*array));
3105 for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
3107 for (; *scan; scan++) {
3110 else if (*scan == ')') {
3113 } else if (*scan == '"' && delim != '"') {
3114 quote = quote ? 0 : 1;
3115 /* Remove quote character from argument */
3116 memmove(scan, scan + 1, strlen(scan));
3118 } else if (*scan == '\\') {
3119 /* Literal character, don't parse */
3120 memmove(scan, scan + 1, strlen(scan));
3121 } else if ((*scan == delim) && !paren && !quote) {
3129 array[argc++] = scan;
3134 static void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
3136 struct ast_var_t *newvariable;
3137 struct varshead *headp;
3138 const char *nametail = name;
3140 /* XXX may need locking on the channel ? */
3141 if (name[strlen(name)-1] == ')') {
3142 char *function = ast_strdupa(name);
3144 ast_func_write(chan, function, value);
3150 /* For comparison purposes, we have to strip leading underscores */
3151 if (*nametail == '_') {
3153 if (*nametail == '_')
3157 AST_LIST_TRAVERSE (headp, newvariable, entries) {
3158 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
3159 /* there is already such a variable, delete it */
3160 AST_LIST_REMOVE(headp, newvariable, entries);
3161 ast_var_delete(newvariable);
3167 if ((option_verbose > 1) && (headp == &globals))
3168 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
3169 newvariable = ast_var_assign(name, value);
3170 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
3175 static int pbx_builtin_setvar(struct ast_channel *chan, const void *data)
3177 char *name, *value, *mydata;
3179 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */
3183 if (ast_strlen_zero(data)) {
3184 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n");
3188 mydata = ast_strdupa(data);
3189 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
3191 /* check for a trailing flags argument */
3192 if ((argc > 1) && !strchr(argv[argc-1], '=')) {
3194 if (strchr(argv[argc], 'g'))
3198 for (x = 0; x < argc; x++) {
3200 if ((value = strchr(name, '='))) {
3202 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value);
3204 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name);
3210 int localized_pbx_builtin_setvar(struct ast_channel *chan, const void *data);
3212 int localized_pbx_builtin_setvar(struct ast_channel *chan, const void *data)
3214 return pbx_builtin_setvar(chan, data);
3218 /*! \brief Helper for get_range.
3219 * return the index of the matching entry, starting from 1.
3220 * If names is not supplied, try numeric values.
3222 static int lookup_name(const char *s, char *const names[], int max)
3226 if (names && *s > '9') {
3227 for (i = 0; names[i]; i++) {
3228 if (!strcasecmp(s, names[i])) {
3234 /* Allow months and weekdays to be specified as numbers, as well */
3235 if (sscanf(s, "%2d", &i) == 1 && i >= 1 && i <= max) {
3236 /* What the array offset would have been: "1" would be at offset 0 */
3239 return -1; /* error return */
3242 /*! \brief helper function to return a range up to max (7, 12, 31 respectively).
3243 * names, if supplied, is an array of names that should be mapped to numbers.
3245 static unsigned get_range(char *src, int max, char *const names[], const char *msg)
3247 int start, end; /* start and ending position */
3248 unsigned int mask = 0;
3251 /* Check for whole range */
3252 if (ast_strlen_zero(src) || !strcmp(src, "*")) {
3253 return (1 << max) - 1;
3256 while ((part = strsep(&src, "&"))) {
3257 /* Get start and ending position */
3258 char *endpart = strchr(part, '-');
3262 /* Find the start */
3263 if ((start = lookup_name(part, names, max)) < 0) {
3264 ast_log(LOG_WARNING, "Invalid %s '%s', skipping element\n", msg, part);
3267 if (endpart) { /* find end of range */
3268 if ((end = lookup_name(endpart, names, max)) < 0) {
3269 ast_log(LOG_WARNING, "Invalid end %s '%s', skipping element\n", msg, endpart);
3275 /* Fill the mask. Remember that ranges are cyclic */
3276 mask |= (1 << end); /* initialize with last element */
3277 while (start != end) {
3281 mask |= (1 << start);
3288 /*! \brief store a bitmask of valid times, one bit each 2 minute */
3289 static void get_timerange(struct ast_timing *i, char *times)
3291 char *endpart, *part;
3295 int minute_start, minute_end;
3297 /* start disabling all times, fill the fields with 0's, as they may contain garbage */
3298 memset(i->minmask, 0, sizeof(i->minmask));
3300 /* 1-minute per bit */
3301 /* Star is all times */
3302 if (ast_strlen_zero(times) || !strcmp(times, "*")) {
3303 /* 48, because each hour takes 2 integers; 30 bits each */
3304 for (x = 0; x < 48; x++) {
3305 i->minmask[x] = 0x3fffffff; /* 30 bits */
3309 /* Otherwise expect a range */
3310 while ((part = strsep(×, "&"))) {
3311 if (!(endpart = strchr(part, '-'))) {
3312 if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
3313 ast_log(LOG_WARNING, "%s isn't a valid time.\n", part);
3316 i->minmask[st_h * 2 + (st_m >= 30 ? 1 : 0)] |= (1 << (st_m % 30));