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 <support_level>extended</support_level>
35 #include "asterisk/compat.h"
36 #include "asterisk/paths.h" /* we use AST_CONFIG_DIR */
41 #include <sys/types.h>
43 #include <sys/resource.h>
49 #if !defined(SOLARIS) && !defined(__CYGWIN__)
56 #include <sys/param.h>
59 static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__((format(printf, 5, 6)));
60 void ast_verbose(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
62 #define ASINCLUDE_GLOB 1
63 #ifdef AST_INCLUDE_GLOB
65 #if !defined(GLOB_ABORTED)
66 #define GLOB_ABORTED GLOB_ABEND
72 #define AST_API_MODULE 1 /* gimme the inline defs! */
75 char x; /* basically empty! */
80 #include "asterisk/inline_api.h"
81 #include "asterisk/endian.h"
82 #include "asterisk/ast_expr.h"
86 #define EVENTLOG "event_log"
87 #define QUEUELOG "queue_log"
89 #define DEBUG_M(a) { \
93 #define VERBOSE_PREFIX_1 " "
94 #define VERBOSE_PREFIX_2 " == "
95 #define VERBOSE_PREFIX_3 " -- "
96 #define VERBOSE_PREFIX_4 " > "
98 void ast_backtrace(void);
100 void ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt, ...)
101 __attribute__((format(printf, 5, 6)));
103 /* IN CONFLICT: void ast_verbose(const char *fmt, ...)
104 __attribute__((format(printf, 1, 2))); */
106 int ast_register_verbose(void (*verboser)(const char *string));
107 int ast_unregister_verbose(void (*verboser)(const char *string));
109 void ast_console_puts(const char *string);
111 #define _A_ __FILE__, __LINE__, __PRETTY_FUNCTION__
116 #define __LOG_DEBUG 0
117 #define LOG_DEBUG __LOG_DEBUG, _A_
122 #define __LOG_EVENT 1
123 #define LOG_EVENT __LOG_EVENT, _A_
128 #define __LOG_NOTICE 2
129 #define LOG_NOTICE __LOG_NOTICE, _A_
134 #define __LOG_WARNING 3
135 #define LOG_WARNING __LOG_WARNING, _A_
140 #define __LOG_ERROR 4
141 #define LOG_ERROR __LOG_ERROR, _A_
146 #define __LOG_VERBOSE 5
147 #define LOG_VERBOSE __LOG_VERBOSE, _A_
153 #define LOG_DTMF __LOG_DTMF, _A_
157 #ifndef HAVE_MTX_PROFILE
158 #define __MTX_PROF(a) return pthread_mutex_lock((a))
162 #define __MTX_PROF(a) do { \
164 /* profile only non-blocking events */ \
165 ast_mark(mtx_prof, 1); \
166 i = pthread_mutex_trylock((a)); \
167 ast_mark(mtx_prof, 0); \
171 return pthread_mutex_lock((a)); \
173 #endif /* HAVE_MTX_PROFILE */
175 #define AST_PTHREADT_NULL (pthread_t) -1
176 #define AST_PTHREADT_STOP (pthread_t) -2
178 #if defined(SOLARIS) || defined(BSD)
179 #define AST_MUTEX_INIT_W_CONSTRUCTORS
180 #endif /* SOLARIS || BSD */
182 /* Asterisk REQUIRES recursive (not error checking) mutexes
183 and will not run without them. */
184 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) && defined(PTHREAD_MUTEX_RECURSIVE_NP)
185 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
186 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
188 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_MUTEX_INITIALIZER
189 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
190 #endif /* PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
194 #define __ast_mutex_logger(...) do { if (canlog) ast_log(LOG_ERROR, __VA_ARGS__); else fprintf(stderr, __VA_ARGS__); } while (0)
197 #define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
199 #define DO_THREAD_CRASH do { } while (0)
202 #define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, { NULL }, { 0 }, 0, { NULL }, { 0 } }
204 #define AST_MAX_REENTRANCY 10
206 struct ast_mutex_info {
207 pthread_mutex_t mutex;
208 /*! Track which thread holds this lock */
209 unsigned int track:1;
210 const char *file[AST_MAX_REENTRANCY];
211 int lineno[AST_MAX_REENTRANCY];
213 const char *func[AST_MAX_REENTRANCY];
214 pthread_t thread[AST_MAX_REENTRANCY];
217 typedef struct ast_mutex_info ast_mutex_t;
219 typedef pthread_cond_t ast_cond_t;
221 static pthread_mutex_t empty_mutex;
223 static void __attribute__((constructor)) init_empty_mutex(void)
225 memset(&empty_mutex, 0, sizeof(empty_mutex));
228 static inline int __ast_pthread_mutex_init_attr(const char *filename, int lineno, const char *func,
229 const char *mutex_name, ast_mutex_t *t,
230 pthread_mutexattr_t *attr)
232 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
233 int canlog = strcmp(filename, "logger.c");
235 if ((t->mutex) != ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
236 if ((t->mutex) != (empty_mutex)) {
237 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is already initialized.\n",
238 filename, lineno, func, mutex_name);
239 __ast_mutex_logger("%s line %d (%s): Error: previously initialization of mutex '%s'.\n",
240 t->file[0], t->lineno[0], t->func[0], mutex_name);
247 t->file[0] = filename;
248 t->lineno[0] = lineno;
253 return pthread_mutex_init(&t->mutex, attr);
256 static inline int __ast_pthread_mutex_init(const char *filename, int lineno, const char *func,
257 const char *mutex_name, ast_mutex_t *t)
259 static pthread_mutexattr_t attr;
261 pthread_mutexattr_init(&attr);
262 pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
264 return __ast_pthread_mutex_init_attr(filename, lineno, func, mutex_name, t, &attr);
266 #define ast_mutex_init(pmutex) __ast_pthread_mutex_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
268 static inline int __ast_pthread_mutex_destroy(const char *filename, int lineno, const char *func,
269 const char *mutex_name, ast_mutex_t *t)
272 int canlog = strcmp(filename, "logger.c");
274 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
275 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
276 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
277 filename, lineno, func, mutex_name);
281 res = pthread_mutex_trylock(&t->mutex);
284 pthread_mutex_unlock(&t->mutex);
287 __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy invalid mutex '%s'.\n",
288 filename, lineno, func, mutex_name);
291 __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy locked mutex '%s'.\n",
292 filename, lineno, func, mutex_name);
293 __ast_mutex_logger("%s line %d (%s): Error: '%s' was locked here.\n",
294 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
298 if ((res = pthread_mutex_destroy(&t->mutex)))
299 __ast_mutex_logger("%s line %d (%s): Error destroying mutex: %s\n",
300 filename, lineno, func, strerror(res));
301 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
303 t->mutex = PTHREAD_MUTEX_INIT_VALUE;
305 t->file[0] = filename;
306 t->lineno[0] = lineno;
312 static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func,
313 const char* mutex_name, ast_mutex_t *t)
316 int canlog = strcmp(filename, "logger.c");
318 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
319 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
320 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
321 filename, lineno, func, mutex_name);
324 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
326 #ifdef DETECT_DEADLOCKS
328 time_t seconds = time(NULL);
331 #ifdef HAVE_MTX_PROFILE
332 ast_mark(mtx_prof, 1);
334 res = pthread_mutex_trylock(&t->mutex);
335 #ifdef HAVE_MTX_PROFILE
336 ast_mark(mtx_prof, 0);
339 current = time(NULL);
340 if ((current - seconds) && (!((current - seconds) % 5))) {
341 __ast_mutex_logger("%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n",
342 filename, lineno, func, (int)(current - seconds), mutex_name);
343 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
344 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
345 t->func[t->reentrancy-1], mutex_name);
349 } while (res == EBUSY);
352 #ifdef HAVE_MTX_PROFILE
353 ast_mark(mtx_prof, 1);
354 res = pthread_mutex_trylock(&t->mutex);
355 ast_mark(mtx_prof, 0);
358 res = pthread_mutex_lock(&t->mutex);
359 #endif /* DETECT_DEADLOCKS */
362 if (t->reentrancy < AST_MAX_REENTRANCY) {
363 t->file[t->reentrancy] = filename;
364 t->lineno[t->reentrancy] = lineno;
365 t->func[t->reentrancy] = func;
366 t->thread[t->reentrancy] = pthread_self();
369 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
370 filename, lineno, func, mutex_name);
373 __ast_mutex_logger("%s line %d (%s): Error obtaining mutex: %s\n",
374 filename, lineno, func, strerror(errno));
381 static inline int __ast_pthread_mutex_trylock(const char *filename, int lineno, const char *func,
382 const char* mutex_name, ast_mutex_t *t)
385 int canlog = strcmp(filename, "logger.c");
387 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
388 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
389 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
390 filename, lineno, func, mutex_name);
393 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
395 if (!(res = pthread_mutex_trylock(&t->mutex))) {
396 if (t->reentrancy < AST_MAX_REENTRANCY) {
397 t->file[t->reentrancy] = filename;
398 t->lineno[t->reentrancy] = lineno;
399 t->func[t->reentrancy] = func;
400 t->thread[t->reentrancy] = pthread_self();
403 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
404 filename, lineno, func, mutex_name);
407 __ast_mutex_logger("%s line %d (%s): Warning: '%s' was locked here.\n",
408 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
414 static inline int __ast_pthread_mutex_unlock(const char *filename, int lineno, const char *func,
415 const char *mutex_name, ast_mutex_t *t)
418 int canlog = strcmp(filename, "logger.c");
420 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
421 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
422 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
423 filename, lineno, func, mutex_name);
427 if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
428 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
429 filename, lineno, func, mutex_name);
430 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
431 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
435 if (--t->reentrancy < 0) {
436 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
437 filename, lineno, func, mutex_name);
441 if (t->reentrancy < AST_MAX_REENTRANCY) {
442 t->file[t->reentrancy] = NULL;
443 t->lineno[t->reentrancy] = 0;
444 t->func[t->reentrancy] = NULL;
445 t->thread[t->reentrancy] = 0;
448 if ((res = pthread_mutex_unlock(&t->mutex))) {
449 __ast_mutex_logger("%s line %d (%s): Error releasing mutex: %s\n",
450 filename, lineno, func, strerror(res));
457 static inline int __ast_cond_init(const char *filename, int lineno, const char *func,
458 const char *cond_name, ast_cond_t *cond, pthread_condattr_t *cond_attr)
460 return pthread_cond_init(cond, cond_attr);
463 static inline int __ast_cond_signal(const char *filename, int lineno, const char *func,
464 const char *cond_name, ast_cond_t *cond)
466 return pthread_cond_signal(cond);
469 static inline int __ast_cond_broadcast(const char *filename, int lineno, const char *func,
470 const char *cond_name, ast_cond_t *cond)
472 return pthread_cond_broadcast(cond);
475 static inline int __ast_cond_destroy(const char *filename, int lineno, const char *func,
476 const char *cond_name, ast_cond_t *cond)
478 return pthread_cond_destroy(cond);
481 static inline int __ast_cond_wait(const char *filename, int lineno, const char *func,
482 const char *cond_name, const char *mutex_name,
483 ast_cond_t *cond, ast_mutex_t *t)
486 int canlog = strcmp(filename, "logger.c");
488 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
489 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
490 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
491 filename, lineno, func, mutex_name);
495 if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
496 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
497 filename, lineno, func, mutex_name);
498 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
499 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
503 if (--t->reentrancy < 0) {
504 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
505 filename, lineno, func, mutex_name);
509 if (t->reentrancy < AST_MAX_REENTRANCY) {
510 t->file[t->reentrancy] = NULL;
511 t->lineno[t->reentrancy] = 0;
512 t->func[t->reentrancy] = NULL;
513 t->thread[t->reentrancy] = 0;
516 if ((res = pthread_cond_wait(cond, &t->mutex))) {
517 __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n",
518 filename, lineno, func, strerror(res));
521 if (t->reentrancy < AST_MAX_REENTRANCY) {
522 t->file[t->reentrancy] = filename;
523 t->lineno[t->reentrancy] = lineno;
524 t->func[t->reentrancy] = func;
525 t->thread[t->reentrancy] = pthread_self();
528 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
529 filename, lineno, func, mutex_name);
536 static inline int __ast_cond_timedwait(const char *filename, int lineno, const char *func,
537 const char *cond_name, const char *mutex_name, ast_cond_t *cond,
538 ast_mutex_t *t, const struct timespec *abstime)
541 int canlog = strcmp(filename, "logger.c");
543 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
544 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
545 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
546 filename, lineno, func, mutex_name);
550 if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
551 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
552 filename, lineno, func, mutex_name);
553 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
554 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
558 if (--t->reentrancy < 0) {
559 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
560 filename, lineno, func, mutex_name);
564 if (t->reentrancy < AST_MAX_REENTRANCY) {
565 t->file[t->reentrancy] = NULL;
566 t->lineno[t->reentrancy] = 0;
567 t->func[t->reentrancy] = NULL;
568 t->thread[t->reentrancy] = 0;
571 if ((res = pthread_cond_timedwait(cond, &t->mutex, abstime)) && (res != ETIMEDOUT)) {
572 __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n",
573 filename, lineno, func, strerror(res));
576 if (t->reentrancy < AST_MAX_REENTRANCY) {
577 t->file[t->reentrancy] = filename;
578 t->lineno[t->reentrancy] = lineno;
579 t->func[t->reentrancy] = func;
580 t->thread[t->reentrancy] = pthread_self();
583 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
584 filename, lineno, func, mutex_name);
591 #define ast_mutex_destroy(a) __ast_pthread_mutex_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
592 #define ast_mutex_lock(a) __ast_pthread_mutex_lock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
593 #define ast_mutex_unlock(a) __ast_pthread_mutex_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
594 #define ast_mutex_trylock(a) __ast_pthread_mutex_trylock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
595 #define ast_cond_init(cond, attr) __ast_cond_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond, attr)
596 #define ast_cond_destroy(cond) __ast_cond_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
597 #define ast_cond_signal(cond) __ast_cond_signal(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
598 #define ast_cond_broadcast(cond) __ast_cond_broadcast(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
599 #define ast_cond_wait(cond, mutex) __ast_cond_wait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex)
600 #define ast_cond_timedwait(cond, mutex, time) __ast_cond_timedwait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex, time)
602 #else /* !DEBUG_THREADS */
605 typedef pthread_mutex_t ast_mutex_t;
607 #define AST_MUTEX_INIT_VALUE ((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
609 static inline int ast_mutex_init(ast_mutex_t *pmutex)
611 pthread_mutexattr_t attr;
613 pthread_mutexattr_init(&attr);
614 pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
616 return pthread_mutex_init(pmutex, &attr);
619 #define ast_pthread_mutex_init(pmutex,a) pthread_mutex_init(pmutex,a)
621 static inline int ast_mutex_unlock(ast_mutex_t *pmutex)
623 return pthread_mutex_unlock(pmutex);
626 static inline int ast_mutex_destroy(ast_mutex_t *pmutex)
628 return pthread_mutex_destroy(pmutex);
631 static inline int ast_mutex_lock(ast_mutex_t *pmutex)
636 static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
638 return pthread_mutex_trylock(pmutex);
641 typedef pthread_cond_t ast_cond_t;
643 static inline int ast_cond_init(ast_cond_t *cond, pthread_condattr_t *cond_attr)
645 return pthread_cond_init(cond, cond_attr);
648 static inline int ast_cond_signal(ast_cond_t *cond)
650 return pthread_cond_signal(cond);
653 static inline int ast_cond_broadcast(ast_cond_t *cond)
655 return pthread_cond_broadcast(cond);
658 static inline int ast_cond_destroy(ast_cond_t *cond)
660 return pthread_cond_destroy(cond);
663 static inline int ast_cond_wait(ast_cond_t *cond, ast_mutex_t *t)
665 return pthread_cond_wait(cond, t);
668 static inline int ast_cond_timedwait(ast_cond_t *cond, ast_mutex_t *t, const struct timespec *abstime)
670 return pthread_cond_timedwait(cond, t, abstime);
673 #endif /* !DEBUG_THREADS */
675 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
676 /* If AST_MUTEX_INIT_W_CONSTRUCTORS is defined, use file scope
677 constructors/destructors to create/destroy mutexes. */
678 #define __AST_MUTEX_DEFINE(scope, mutex) \
679 scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE; \
680 static void __attribute__((constructor)) init_##mutex(void) \
682 ast_mutex_init(&mutex); \
684 static void __attribute__((destructor)) fini_##mutex(void) \
686 ast_mutex_destroy(&mutex); \
688 #else /* !AST_MUTEX_INIT_W_CONSTRUCTORS */
689 /* By default, use static initialization of mutexes. */
690 #define __AST_MUTEX_DEFINE(scope, mutex) \
691 scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE
692 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
694 #define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
695 #define pthread_mutex_lock use_ast_mutex_lock_instead_of_pthread_mutex_lock
696 #define pthread_mutex_unlock use_ast_mutex_unlock_instead_of_pthread_mutex_unlock
697 #define pthread_mutex_trylock use_ast_mutex_trylock_instead_of_pthread_mutex_trylock
698 #define pthread_mutex_init use_ast_mutex_init_instead_of_pthread_mutex_init
699 #define pthread_mutex_destroy use_ast_mutex_destroy_instead_of_pthread_mutex_destroy
700 #define pthread_cond_t use_ast_cond_t_instead_of_pthread_cond_t
701 #define pthread_cond_init use_ast_cond_init_instead_of_pthread_cond_init
702 #define pthread_cond_destroy use_ast_cond_destroy_instead_of_pthread_cond_destroy
703 #define pthread_cond_signal use_ast_cond_signal_instead_of_pthread_cond_signal
704 #define pthread_cond_broadcast use_ast_cond_broadcast_instead_of_pthread_cond_broadcast
705 #define pthread_cond_wait use_ast_cond_wait_instead_of_pthread_cond_wait
706 #define pthread_cond_timedwait use_ast_cond_timedwait_instead_of_pthread_cond_timedwait
708 #define AST_MUTEX_DEFINE_STATIC(mutex) __AST_MUTEX_DEFINE(static, mutex)
710 #define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
712 #define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
715 #define pthread_create __use_ast_pthread_create_instead__
718 typedef pthread_rwlock_t ast_rwlock_t;
720 static inline int ast_rwlock_init(ast_rwlock_t *prwlock)
722 pthread_rwlockattr_t attr;
724 pthread_rwlockattr_init(&attr);
726 #ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
727 pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP);
730 return pthread_rwlock_init(prwlock, &attr);
733 static inline int ast_rwlock_destroy(ast_rwlock_t *prwlock)
735 return pthread_rwlock_destroy(prwlock);
738 static inline int ast_rwlock_unlock(ast_rwlock_t *prwlock)
740 return pthread_rwlock_unlock(prwlock);
743 static inline int ast_rwlock_rdlock(ast_rwlock_t *prwlock)
745 return pthread_rwlock_rdlock(prwlock);
748 static inline int ast_rwlock_tryrdlock(ast_rwlock_t *prwlock)
750 return pthread_rwlock_tryrdlock(prwlock);
753 static inline int ast_rwlock_wrlock(ast_rwlock_t *prwlock)
755 return pthread_rwlock_wrlock(prwlock);
758 static inline int ast_rwlock_trywrlock(ast_rwlock_t *prwlock)
760 return pthread_rwlock_trywrlock(prwlock);
763 /* Statically declared read/write locks */
765 #ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER
766 #define __AST_RWLOCK_DEFINE(scope, rwlock) \
767 scope ast_rwlock_t rwlock; \
768 static void __attribute__((constructor)) init_##rwlock(void) \
770 ast_rwlock_init(&rwlock); \
772 static void __attribute__((destructor)) fini_##rwlock(void) \
774 ast_rwlock_destroy(&rwlock); \
777 #define AST_RWLOCK_INIT_VALUE PTHREAD_RWLOCK_INITIALIZER
778 #define __AST_RWLOCK_DEFINE(scope, rwlock) \
779 scope ast_rwlock_t rwlock = AST_RWLOCK_INIT_VALUE
782 #define AST_RWLOCK_DEFINE_STATIC(rwlock) __AST_RWLOCK_DEFINE(static, rwlock)
785 * Initial support for atomic instructions.
786 * For platforms that have it, use the native cpu instruction to
787 * implement them. For other platforms, resort to a 'slow' version
788 * (defined in utils.c) that protects the atomic instruction with
790 * The slow versions is always available, for testing purposes,
791 * as ast_atomic_fetchadd_int_slow()
794 #if defined(HAVE_OSX_ATOMICS)
795 #include "libkern/OSAtomic.h"
798 /*! \brief Atomically add v to *p and return * the previous value of *p.
799 * This can be used to handle reference counts, and the return value
800 * can be used to generate unique identifiers.
803 #if defined(HAVE_GCC_ATOMICS)
804 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
806 return __sync_fetch_and_add(p, v);
808 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
809 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
811 return OSAtomicAdd32(v, (int32_t *) p);
813 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
814 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
816 return OSAtomicAdd64(v, (int64_t *) p);
817 #elif defined (__i386__) || defined(__x86_64__)
818 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
821 " lock xaddl %0, %1 ; "
822 : "+r" (v), /* 0 (result) */
828 static int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
835 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
837 return ast_atomic_fetchadd_int_slow(p, v);
841 /*! \brief decrement *p by 1 and return true if the variable has reached 0.
842 * Useful e.g. to check if a refcount has reached 0.
844 #if defined(HAVE_GCC_ATOMICS)
845 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
847 return __sync_sub_and_fetch(p, 1) == 0;
849 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
850 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
852 return OSAtomicAdd32( -1, (int32_t *) p) == 0;
854 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
855 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
857 return OSAtomicAdd64( -1, (int64_t *) p) == 0;
859 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
861 int a = ast_atomic_fetchadd_int(p, -1);
862 return a == 1; /* true if the value is 0 now (so it was 1 previously) */
866 #ifndef DEBUG_CHANNEL_LOCKS
867 /*! \brief Lock a channel. If DEBUG_CHANNEL_LOCKS is defined
868 in the Makefile, print relevant output for debugging */
869 #define ast_channel_lock(x) ast_mutex_lock(&x->lock)
870 /*! \brief Unlock a channel. If DEBUG_CHANNEL_LOCKS is defined
871 in the Makefile, print relevant output for debugging */
872 #define ast_channel_unlock(x) ast_mutex_unlock(&x->lock)
873 /*! \brief Try locking a channel. If DEBUG_CHANNEL_LOCKS is defined
874 in the Makefile, print relevant output for debugging */
875 #define ast_channel_trylock(x) ast_mutex_trylock(&x->lock)
878 /*! \brief Lock AST channel (and print debugging output)
879 \note You need to enable DEBUG_CHANNEL_LOCKS for this function */
880 int ast_channel_lock(struct ast_channel *chan);
882 /*! \brief Unlock AST channel (and print debugging output)
883 \note You need to enable DEBUG_CHANNEL_LOCKS for this function
885 int ast_channel_unlock(struct ast_channel *chan);
887 /*! \brief Lock AST channel (and print debugging output)
888 \note You need to enable DEBUG_CHANNEL_LOCKS for this function */
889 int ast_channel_trylock(struct ast_channel *chan);
893 #include "asterisk/hashtab.h"
894 #include "asterisk/ael_structs.h"
895 #include "asterisk/pval.h"
899 #define ast_free free
900 #define ast_free_ptr free
902 #define MALLOC_FAILURE_MSG \
903 ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
906 * \brief A wrapper for malloc()
908 * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
909 * message in the case that the allocation fails.
911 * The argument and return value are the same as malloc()
913 #define ast_malloc(len) \
914 _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
916 #define ast_calloc(num, len) \
917 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
919 #define ast_calloc_cache(num, len) \
920 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
922 #define ast_realloc(p, len) \
923 _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
925 #define ast_strdup(str) \
926 _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
928 #define ast_strndup(str, len) \
929 _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
931 #define ast_asprintf(ret, fmt, ...) \
932 _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
934 #define ast_vasprintf(ret, fmt, ap) \
935 _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
938 static unsigned int __unsigned_int_flags_dummy;
940 struct ast_flags { /* stolen from utils.h */
943 #define ast_test_flag(p,flag) ({ \
944 typeof ((p)->flags) __p = (p)->flags; \
945 typeof (__unsigned_int_flags_dummy) __x = 0; \
946 (void) (&__p == &__x); \
947 ((p)->flags & (flag)); \
950 #define ast_set2_flag(p,value,flag) do { \
951 typeof ((p)->flags) __p = (p)->flags; \
952 typeof (__unsigned_int_flags_dummy) __x = 0; \
953 (void) (&__p == &__x); \
955 (p)->flags |= (flag); \
957 (p)->flags &= ~(flag); \
962 #define MALLOC_FAILURE_MSG \
963 ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
965 * \brief A wrapper for malloc()
967 * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
968 * message in the case that the allocation fails.
970 * The argument and return value are the same as malloc()
972 #define ast_malloc(len) \
973 _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
976 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
980 if (!(p = malloc(len)))
988 * \brief A wrapper for calloc()
990 * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
991 * message in the case that the allocation fails.
993 * The arguments and return value are the same as calloc()
995 #define ast_calloc(num, len) \
996 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
999 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
1003 if (!(p = calloc(num, len)))
1011 * \brief A wrapper for calloc() for use in cache pools
1013 * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
1014 * message in the case that the allocation fails. When memory debugging is in use,
1015 * the memory allocated by this function will be marked as 'cache' so it can be
1016 * distinguished from normal memory allocations.
1018 * The arguments and return value are the same as calloc()
1020 #define ast_calloc_cache(num, len) \
1021 _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1024 * \brief A wrapper for realloc()
1026 * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
1027 * message in the case that the allocation fails.
1029 * The arguments and return value are the same as realloc()
1031 #define ast_realloc(p, len) \
1032 _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1035 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
1039 if (!(newp = realloc(p, len)))
1047 * \brief A wrapper for strdup()
1049 * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
1050 * message in the case that the allocation fails.
1052 * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
1053 * argument is provided, ast_strdup will return NULL without generating any
1054 * kind of error log message.
1056 * The argument and return value are the same as strdup()
1058 #define ast_strdup(str) \
1059 _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1062 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
1064 char *newstr = NULL;
1067 if (!(newstr = strdup(str)))
1076 * \brief A wrapper for strndup()
1078 * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
1079 * message in the case that the allocation fails.
1081 * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
1082 * string to duplicate. If a NULL argument is provided, ast_strdup will return
1083 * NULL without generating any kind of error log message.
1085 * The arguments and return value are the same as strndup()
1087 #define ast_strndup(str, len) \
1088 _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1091 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
1093 char *newstr = NULL;
1096 if (!(newstr = strndup(str, len)))
1105 * \brief A wrapper for asprintf()
1107 * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
1108 * message in the case that the allocation fails.
1110 * The arguments and return value are the same as asprintf()
1112 #define ast_asprintf(ret, fmt, ...) \
1113 _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
1116 __attribute__((format(printf, 5, 6)))
1117 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...),
1123 if ((res = vasprintf(ret, fmt, ap)) == -1)
1132 * \brief A wrapper for vasprintf()
1134 * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
1135 * message in the case that the allocation fails.
1137 * The arguments and return value are the same as vasprintf()
1139 #define ast_vasprintf(ret, fmt, ap) \
1140 _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
1143 __attribute__((format(printf, 5, 0)))
1144 int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
1148 if ((res = vasprintf(ret, fmt, ap)) == -1)
1155 #if !defined(ast_strdupa) && defined(__GNUC__)
1157 \brief duplicate a string in memory from the stack
1158 \param s The string to duplicate
1160 This macro will duplicate the given string. It returns a pointer to the stack
1161 allocatted memory for the new string.
1163 #define ast_strdupa(s) \
1166 const char *__old = (s); \
1167 size_t __len = strlen(__old) + 1; \
1168 char *__new = __builtin_alloca(__len); \
1169 memcpy (__new, __old, __len); \
1177 #define MAX_NESTED_COMMENTS 128
1178 #define COMMENT_START ";--"
1179 #define COMMENT_END "--;"
1180 #define COMMENT_META ';'
1181 #define COMMENT_TAG '-'
1183 static char *extconfig_conf = "extconfig.conf";
1185 /*! Growable string buffer */
1186 static char *comment_buffer; /*!< this will be a comment collector.*/
1187 static int comment_buffer_size; /*!< the amount of storage so far alloc'd for the comment_buffer */
1189 static char *lline_buffer; /*!< A buffer for stuff behind the ; */
1190 static int lline_buffer_size;
1194 struct ast_comment {
1195 struct ast_comment *next;
1199 static void CB_INIT(void)
1201 if (!comment_buffer) {
1202 comment_buffer = ast_malloc(CB_INCR);
1203 if (!comment_buffer)
1205 comment_buffer[0] = 0;
1206 comment_buffer_size = CB_INCR;
1207 lline_buffer = ast_malloc(CB_INCR);
1210 lline_buffer[0] = 0;
1211 lline_buffer_size = CB_INCR;
1213 comment_buffer[0] = 0;
1214 lline_buffer[0] = 0;
1218 static void CB_ADD(char *str)
1220 int rem = comment_buffer_size - strlen(comment_buffer) - 1;
1221 int siz = strlen(str);
1223 comment_buffer = ast_realloc(comment_buffer, comment_buffer_size + CB_INCR + siz + 1);
1224 if (!comment_buffer)
1226 comment_buffer_size += CB_INCR+siz+1;
1228 strcat(comment_buffer,str);
1231 static void CB_ADD_LEN(char *str, int len)
1233 int cbl = strlen(comment_buffer) + 1;
1234 int rem = comment_buffer_size - cbl;
1236 comment_buffer = ast_realloc(comment_buffer, comment_buffer_size + CB_INCR + len + 1);
1237 if (!comment_buffer)
1239 comment_buffer_size += CB_INCR+len+1;
1241 strncat(comment_buffer,str,len); /* safe */
1242 comment_buffer[cbl+len-1] = 0;
1245 static void LLB_ADD(char *str)
1247 int rem = lline_buffer_size - strlen(lline_buffer) - 1;
1248 int siz = strlen(str);
1250 lline_buffer = ast_realloc(lline_buffer, lline_buffer_size + CB_INCR + siz + 1);
1253 lline_buffer_size += CB_INCR + siz + 1;
1255 strcat(lline_buffer,str);
1258 static void CB_RESET(void )
1260 comment_buffer[0] = 0;
1261 lline_buffer[0] = 0;
1264 /*! \brief Keep track of how many threads are currently trying to wait*() on
1265 * a child process */
1266 static unsigned int safe_system_level = 0;
1267 static struct sigaction safe_system_prev_handler;
1269 /*! \brief NULL handler so we can collect the child exit status */
1270 static void _null_sig_handler(int sig)
1275 static struct sigaction null_sig_handler = {
1276 .sa_handler = _null_sig_handler,
1277 .sa_flags = SA_RESTART,
1280 void ast_replace_sigchld(void);
1282 void ast_replace_sigchld(void)
1286 level = safe_system_level++;
1288 /* only replace the handler if it has not already been done */
1290 sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
1294 void ast_unreplace_sigchld(void);
1296 void ast_unreplace_sigchld(void)
1300 level = --safe_system_level;
1302 /* only restore the handler if we are the last one */
1304 sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
1308 int ast_safe_system(const char *s);
1310 int ast_safe_system(const char *s)
1313 #ifdef HAVE_WORKING_FORK
1317 struct rusage rusage;
1320 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
1321 ast_replace_sigchld();
1323 #ifdef HAVE_WORKING_FORK
1330 #ifdef HAVE_WORKING_FORK
1331 /* Close file descriptors and launch system command */
1332 for (x = STDERR_FILENO + 1; x < 4096; x++)
1335 execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
1337 } else if (pid > 0) {
1339 res = wait4(pid, &status, 0, &rusage);
1341 res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
1343 } else if (errno != EINTR)
1347 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
1351 ast_unreplace_sigchld();
1359 static struct ast_comment *ALLOC_COMMENT(const char *buffer)
1361 struct ast_comment *x = ast_calloc(1,sizeof(struct ast_comment)+strlen(buffer)+1);
1362 strcpy(x->cmt, buffer);
1366 static struct ast_config_map {
1367 struct ast_config_map *next;
1373 } *config_maps = NULL;
1375 static struct ast_config_engine *config_engine_list;
1377 #define MAX_INCLUDE_LEVEL 10
1380 struct ast_category {
1382 int ignored; /*!< do not let user of the config see this category */
1384 char *file; /*!< the file name from whence this declaration was read */
1386 struct ast_comment *precomments;
1387 struct ast_comment *sameline;
1388 struct ast_variable *root;
1389 struct ast_variable *last;
1390 struct ast_category *next;
1394 struct ast_category *root;
1395 struct ast_category *last;
1396 struct ast_category *current;
1397 struct ast_category *last_browse; /*!< used to cache the last category supplied via category_browse */
1399 int max_include_level;
1400 struct ast_config_include *includes; /*!< a list of inclusions, which should describe the entire tree */
1403 struct ast_config_include {
1404 char *include_location_file; /*!< file name in which the include occurs */
1405 int include_location_lineno; /*!< lineno where include occurred */
1406 int exec; /*!< set to non-zero if itsa #exec statement */
1407 char *exec_file; /*!< if it's an exec, you'll have both the /var/tmp to read, and the original script */
1408 char *included_file; /*!< file name included */
1409 int inclusion_count; /*!< if the file is included more than once, a running count thereof -- but, worry not,
1410 we explode the instances and will include those-- so all entries will be unique */
1411 int output; /*!< a flag to indicate if the inclusion has been output */
1412 struct ast_config_include *next; /*!< ptr to next inclusion in the list */
1415 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);
1416 typedef struct ast_variable *realtime_var_get(const char *database, const char *table, va_list ap);
1417 typedef struct ast_config *realtime_multi_get(const char *database, const char *table, va_list ap);
1418 typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
1420 /*! \brief Configuration engine structure, used to define realtime drivers */
1421 struct ast_config_engine {
1423 config_load_func *load_func;
1424 realtime_var_get *realtime_func;
1425 realtime_multi_get *realtime_multi_func;
1426 realtime_update *update_func;
1427 struct ast_config_engine *next;
1430 static struct ast_config_engine *config_engine_list;
1432 /* taken from strings.h */
1434 static force_inline int ast_strlen_zero(const char *s)
1436 return (!s || (*s == '\0'));
1439 #define S_OR(a, b) (!ast_strlen_zero(a) ? (a) : (b))
1442 void ast_copy_string(char *dst, const char *src, size_t size),
1444 while (*src && size) {
1448 if (__builtin_expect(!size, 0))
1455 char *ast_skip_blanks(const char *str),
1457 while (*str && *str < 33)
1464 \brief Trims trailing whitespace characters from a string.
1465 \param ast_trim_blanks function being used
1466 \param str the input string
1467 \return a pointer to the modified string
1470 char *ast_trim_blanks(char *str),
1475 work += strlen(work) - 1;
1476 /* It's tempting to only want to erase after we exit this loop,
1477 but since ast_trim_blanks *could* receive a constant string
1478 (which we presumably wouldn't have to touch), we shouldn't
1479 actually set anything unless we must, and it's easier just
1480 to set each position to \0 than to keep track of a variable
1482 while ((work >= str) && *work < 33)
1490 \brief Strip leading/trailing whitespace from a string.
1491 \param s The string to be stripped (will be modified).
1492 \return The stripped string.
1494 This functions strips all leading and trailing whitespace
1495 characters from the input string, and returns a pointer to
1496 the resulting string. The string is modified in place.
1499 char *ast_strip(char *s),
1501 s = ast_skip_blanks(s);
1511 struct ast_variable {
1516 int object; /*!< 0 for variable, 1 for object */
1517 int blanklines; /*!< Number of blanklines following entry */
1518 struct ast_comment *precomments;
1519 struct ast_comment *sameline;
1520 struct ast_variable *next;
1524 static const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable);
1525 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);
1527 struct ast_config *localized_config_load_with_comments(const char *filename);
1528 static char *ast_category_browse(struct ast_config *config, const char *prev);
1529 static struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category);
1530 static void ast_variables_destroy(struct ast_variable *v);
1531 static void ast_config_destroy(struct ast_config *cfg);
1532 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);
1533 static struct ast_config_include *ast_include_find(struct ast_config *conf, const char *included_file);
1534 void localized_ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file);
1536 static struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename);
1538 static struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename)
1540 struct ast_variable *variable;
1541 int name_len = strlen(name) + 1;
1543 if ((variable = ast_calloc(1, name_len + strlen(value) + 1 + strlen(filename) + 1 + sizeof(*variable)))) {
1544 variable->name = variable->stuff;
1545 variable->value = variable->stuff + name_len;
1546 variable->file = variable->value + strlen(value) + 1;
1547 strcpy(variable->name,name);
1548 strcpy(variable->value,value);
1549 strcpy(variable->file,filename);
1555 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)
1557 /* a file should be included ONCE. Otherwise, if one of the instances is changed,
1558 then all be changed. -- how do we know to include it? -- Handling modified
1559 instances is possible, I'd have
1560 to create a new master for each instance. */
1561 struct ast_config_include *inc;
1563 inc = ast_include_find(conf, included_file);
1566 inc->inclusion_count++;
1567 snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count);
1568 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);
1570 *real_included_file_name = 0;
1572 inc = ast_calloc(1,sizeof(struct ast_config_include));
1573 inc->include_location_file = ast_strdup(from_file);
1574 inc->include_location_lineno = from_lineno;
1575 if (!ast_strlen_zero(real_included_file_name))
1576 inc->included_file = ast_strdup(real_included_file_name);
1578 inc->included_file = ast_strdup(included_file);
1580 inc->exec = is_exec;
1582 inc->exec_file = ast_strdup(exec_file);
1584 /* attach this new struct to the conf struct */
1585 inc->next = conf->includes;
1586 conf->includes = inc;
1591 void localized_ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
1593 struct ast_config_include *incl;
1594 struct ast_category *cat;
1595 struct ast_variable *v;
1597 int from_len = strlen(from_file);
1598 int to_len = strlen(to_file);
1600 if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */
1603 /* the manager code allows you to read in one config file, then
1604 write it back out under a different name. But, the new arrangement
1605 ties output lines to the file name. So, before you try to write
1606 the config file to disk, better riffle thru the data and make sure
1607 the file names are changed.
1609 /* file names are on categories, includes (of course), and on variables. So,
1610 traverse all this and swap names */
1612 for (incl = conf->includes; incl; incl=incl->next) {
1613 if (strcmp(incl->include_location_file,from_file) == 0) {
1614 if (from_len >= to_len)
1615 strcpy(incl->include_location_file, to_file);
1617 free(incl->include_location_file);
1618 incl->include_location_file = strdup(to_file);
1622 for (cat = conf->root; cat; cat = cat->next) {
1623 if (strcmp(cat->file,from_file) == 0) {
1624 if (from_len >= to_len)
1625 strcpy(cat->file, to_file);
1628 cat->file = strdup(to_file);
1631 for (v = cat->root; v; v = v->next) {
1632 if (strcmp(v->file,from_file) == 0) {
1633 if (from_len >= to_len)
1634 strcpy(v->file, to_file);
1637 v->file = strdup(to_file);
1644 static struct ast_config_include *ast_include_find(struct ast_config *conf, const char *included_file)
1646 struct ast_config_include *x;
1647 for (x=conf->includes;x;x=x->next)
1649 if (strcmp(x->included_file,included_file) == 0)
1656 static void ast_variable_append(struct ast_category *category, struct ast_variable *variable);
1658 static void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
1663 category->last->next = variable;
1665 category->root = variable;
1666 category->last = variable;
1667 while (category->last->next)
1668 category->last = category->last->next;
1671 static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored);
1673 static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored)
1675 struct ast_category *cat;
1677 /* try exact match first, then case-insensitive match */
1678 for (cat = config->root; cat; cat = cat->next) {
1679 if (cat->name == category_name && (ignored || !cat->ignored))
1683 for (cat = config->root; cat; cat = cat->next) {
1684 if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored))
1691 static struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name)
1693 return category_get(config, category_name, 0);
1696 static struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category)
1698 struct ast_category *cat = NULL;
1700 if (category && config->last_browse && (config->last_browse->name == category))
1701 cat = config->last_browse;
1703 cat = ast_category_get(config, category);
1705 return (cat) ? cat->root : NULL;
1708 static const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
1710 struct ast_variable *v;
1713 for (v = ast_variable_browse(config, category); v; v = v->next) {
1714 if (!strcasecmp(variable, v->name))
1718 struct ast_category *cat;
1720 for (cat = config->root; cat; cat = cat->next)
1721 for (v = cat->root; v; v = v->next)
1722 if (!strcasecmp(variable, v->name))
1729 static struct ast_variable *variable_clone(const struct ast_variable *old)
1731 struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
1734 new->lineno = old->lineno;
1735 new->object = old->object;
1736 new->blanklines = old->blanklines;
1737 /* TODO: clone comments? */
1743 static void ast_variables_destroy(struct ast_variable *v)
1745 struct ast_variable *vn;
1754 static void ast_includes_destroy(struct ast_config_include *incls)
1756 struct ast_config_include *incl,*inclnext;
1758 for (incl=incls; incl; incl = inclnext) {
1759 inclnext = incl->next;
1760 if (incl->include_location_file)
1761 free(incl->include_location_file);
1762 if (incl->exec_file)
1763 free(incl->exec_file);
1764 if (incl->included_file)
1765 free(incl->included_file);
1770 static void ast_config_destroy(struct ast_config *cfg)
1772 struct ast_category *cat, *catn;
1777 ast_includes_destroy(cfg->includes);
1781 ast_variables_destroy(cat->root);
1789 enum ast_option_flags {
1790 /*! Allow \#exec in config files */
1791 AST_OPT_FLAG_EXEC_INCLUDES = (1 << 0),
1792 /*! Do not fork() */
1793 AST_OPT_FLAG_NO_FORK = (1 << 1),
1795 AST_OPT_FLAG_QUIET = (1 << 2),
1797 AST_OPT_FLAG_CONSOLE = (1 << 3),
1798 /*! Run in realtime Linux priority */
1799 AST_OPT_FLAG_HIGH_PRIORITY = (1 << 4),
1800 /*! Initialize keys for RSA authentication */
1801 AST_OPT_FLAG_INIT_KEYS = (1 << 5),
1802 /*! Remote console */
1803 AST_OPT_FLAG_REMOTE = (1 << 6),
1804 /*! Execute an asterisk CLI command upon startup */
1805 AST_OPT_FLAG_EXEC = (1 << 7),
1806 /*! Don't use termcap colors */
1807 AST_OPT_FLAG_NO_COLOR = (1 << 8),
1808 /*! Are we fully started yet? */
1809 AST_OPT_FLAG_FULLY_BOOTED = (1 << 9),
1810 /*! Trascode via signed linear */
1811 AST_OPT_FLAG_TRANSCODE_VIA_SLIN = (1 << 10),
1812 /*! Dump core on a seg fault */
1813 AST_OPT_FLAG_DUMP_CORE = (1 << 12),
1814 /*! Cache sound files */
1815 AST_OPT_FLAG_CACHE_RECORD_FILES = (1 << 13),
1816 /*! Display timestamp in CLI verbose output */
1817 AST_OPT_FLAG_TIMESTAMP = (1 << 14),
1818 /*! Override config */
1819 AST_OPT_FLAG_OVERRIDE_CONFIG = (1 << 15),
1821 AST_OPT_FLAG_RECONNECT = (1 << 16),
1822 /*! Transmit Silence during Record() and DTMF Generation */
1823 AST_OPT_FLAG_TRANSMIT_SILENCE = (1 << 17),
1824 /*! Suppress some warnings */
1825 AST_OPT_FLAG_DONT_WARN = (1 << 18),
1826 /*! End CDRs before the 'h' extension */
1827 AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN = (1 << 19),
1828 /*! Use DAHDI Timing for generators if available */
1829 AST_OPT_FLAG_INTERNAL_TIMING = (1 << 20),
1830 /*! Always fork, even if verbose or debug settings are non-zero */
1831 AST_OPT_FLAG_ALWAYS_FORK = (1 << 21),
1832 /*! Disable log/verbose output to remote consoles */
1833 AST_OPT_FLAG_MUTE = (1 << 22),
1834 /*! There is a per-file debug setting */
1835 AST_OPT_FLAG_DEBUG_FILE = (1 << 23),
1836 /*! There is a per-file verbose setting */
1837 AST_OPT_FLAG_VERBOSE_FILE = (1 << 24),
1838 /*! Terminal colors should be adjusted for a light-colored background */
1839 AST_OPT_FLAG_LIGHT_BACKGROUND = (1 << 25),
1840 /*! Count Initiated seconds in CDR's */
1841 AST_OPT_FLAG_INITIATED_SECONDS = (1 << 26),
1842 /*! Force black background */
1843 AST_OPT_FLAG_FORCE_BLACK_BACKGROUND = (1 << 27),
1846 /* options.h declares ast_options extern; I need it static? */
1847 #define AST_CACHE_DIR_LEN 512
1848 #define AST_FILENAME_MAX 80
1850 /*! These are the options that set by default when Asterisk starts */
1851 #define AST_DEFAULT_OPTIONS AST_OPT_FLAG_TRANSCODE_VIA_SLIN
1853 struct ast_flags ast_options = { AST_DEFAULT_OPTIONS };
1855 #define ast_opt_exec_includes ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES)
1856 #define ast_opt_no_fork ast_test_flag(&ast_options, AST_OPT_FLAG_NO_FORK)
1857 #define ast_opt_quiet ast_test_flag(&ast_options, AST_OPT_FLAG_QUIET)
1858 #define ast_opt_console ast_test_flag(&ast_options, AST_OPT_FLAG_CONSOLE)
1859 #define ast_opt_high_priority ast_test_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY)
1860 #define ast_opt_init_keys ast_test_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS)
1861 #define ast_opt_remote ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)
1862 #define ast_opt_exec ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC)
1863 #define ast_opt_no_color ast_test_flag(&ast_options, AST_OPT_FLAG_NO_COLOR)
1864 #define ast_fully_booted ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)
1865 #define ast_opt_transcode_via_slin ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN)
1866 #define ast_opt_priority_jumping ast_test_flag(&ast_options, AST_OPT_FLAG_PRIORITY_JUMPING)
1867 #define ast_opt_dump_core ast_test_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE)
1868 #define ast_opt_cache_record_files ast_test_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES)
1869 #define ast_opt_timestamp ast_test_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP)
1870 #define ast_opt_override_config ast_test_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG)
1871 #define ast_opt_reconnect ast_test_flag(&ast_options, AST_OPT_FLAG_RECONNECT)
1872 #define ast_opt_transmit_silence ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE)
1873 #define ast_opt_dont_warn ast_test_flag(&ast_options, AST_OPT_FLAG_DONT_WARN)
1874 #define ast_opt_end_cdr_before_h_exten ast_test_flag(&ast_options, AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN)
1875 #define ast_opt_internal_timing ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING)
1876 #define ast_opt_always_fork ast_test_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK)
1877 #define ast_opt_mute ast_test_flag(&ast_options, AST_OPT_FLAG_MUTE)
1879 extern int option_verbose;
1880 extern int option_debug; /*!< Debugging */
1881 extern int option_maxcalls; /*!< Maximum number of simultaneous channels */
1882 extern double option_maxload;
1883 extern char defaultlanguage[];
1885 extern pid_t ast_mainpid;
1887 extern char record_cache_dir[AST_CACHE_DIR_LEN];
1888 extern char debug_filename[AST_FILENAME_MAX];
1890 extern int ast_language_is_prefix;
1896 #define AST_LIST_LOCK(head) \
1897 ast_mutex_lock(&(head)->lock)
1900 \brief Write locks a list.
1901 \param head This is a pointer to the list head structure
1903 This macro attempts to place an exclusive write lock in the
1904 list head structure pointed to by head.
1905 Returns non-zero on success, 0 on failure
1907 #define AST_RWLIST_WRLOCK(head) \
1908 ast_rwlock_wrlock(&(head)->lock)
1911 \brief Read locks a list.
1912 \param head This is a pointer to the list head structure
1914 This macro attempts to place a read lock in the
1915 list head structure pointed to by head.
1916 Returns non-zero on success, 0 on failure
1918 #define AST_RWLIST_RDLOCK(head) \
1919 ast_rwlock_rdlock(&(head)->lock)
1922 \brief Locks a list, without blocking if the list is locked.
1923 \param head This is a pointer to the list head structure
1925 This macro attempts to place an exclusive lock in the
1926 list head structure pointed to by head.
1927 Returns non-zero on success, 0 on failure
1929 #define AST_LIST_TRYLOCK(head) \
1930 ast_mutex_trylock(&(head)->lock)
1933 \brief Write locks a list, without blocking if the list is locked.
1934 \param head This is a pointer to the list head structure
1936 This macro attempts to place an exclusive write lock in the
1937 list head structure pointed to by head.
1938 Returns non-zero on success, 0 on failure
1940 #define AST_RWLIST_TRYWRLOCK(head) \
1941 ast_rwlock_trywrlock(&(head)->lock)
1944 \brief Read locks a list, without blocking if the list is locked.
1945 \param head This is a pointer to the list head structure
1947 This macro attempts to place a read lock in the
1948 list head structure pointed to by head.
1949 Returns non-zero on success, 0 on failure
1951 #define AST_RWLIST_TRYRDLOCK(head) \
1952 ast_rwlock_tryrdlock(&(head)->lock)
1955 \brief Attempts to unlock a list.
1956 \param head This is a pointer to the list head structure
1958 This macro attempts to remove an exclusive lock from the
1959 list head structure pointed to by head. If the list
1960 was not locked by this thread, this macro has no effect.
1962 #define AST_LIST_UNLOCK(head) \
1963 ast_mutex_unlock(&(head)->lock)
1966 \brief Attempts to unlock a read/write based list.
1967 \param head This is a pointer to the list head structure
1969 This macro attempts to remove a read or write lock from the
1970 list head structure pointed to by head. If the list
1971 was not locked by this thread, this macro has no effect.
1973 #define AST_RWLIST_UNLOCK(head) \
1974 ast_rwlock_unlock(&(head)->lock)
1977 \brief Defines a structure to be used to hold a list of specified type.
1978 \param name This will be the name of the defined structure.
1979 \param type This is the type of each list entry.
1981 This macro creates a structure definition that can be used
1982 to hold a list of the entries of type \a type. It does not actually
1983 declare (allocate) a structure; to do that, either follow this
1984 macro with the desired name of the instance you wish to declare,
1985 or use the specified \a name to declare instances elsewhere.
1989 static AST_LIST_HEAD(entry_list, entry) entries;
1992 This would define \c struct \c entry_list, and declare an instance of it named
1993 \a entries, all intended to hold a list of type \c struct \c entry.
1995 #define AST_LIST_HEAD(name, type) \
1997 struct type *first; \
1998 struct type *last; \
2003 \brief Defines a structure to be used to hold a read/write list of specified type.
2004 \param name This will be the name of the defined structure.
2005 \param type This is the type of each list entry.
2007 This macro creates a structure definition that can be used
2008 to hold a list of the entries of type \a type. It does not actually
2009 declare (allocate) a structure; to do that, either follow this
2010 macro with the desired name of the instance you wish to declare,
2011 or use the specified \a name to declare instances elsewhere.
2015 static AST_RWLIST_HEAD(entry_list, entry) entries;
2018 This would define \c struct \c entry_list, and declare an instance of it named
2019 \a entries, all intended to hold a list of type \c struct \c entry.
2021 #define AST_RWLIST_HEAD(name, type) \
2023 struct type *first; \
2024 struct type *last; \
2025 ast_rwlock_t lock; \
2029 \brief Defines a structure to be used to hold a list of specified type (with no lock).
2030 \param name This will be the name of the defined structure.
2031 \param type This is the type of each list entry.
2033 This macro creates a structure definition that can be used
2034 to hold a list of the entries of type \a type. It does not actually
2035 declare (allocate) a structure; to do that, either follow this
2036 macro with the desired name of the instance you wish to declare,
2037 or use the specified \a name to declare instances elsewhere.
2041 static AST_LIST_HEAD_NOLOCK(entry_list, entry) entries;
2044 This would define \c struct \c entry_list, and declare an instance of it named
2045 \a entries, all intended to hold a list of type \c struct \c entry.
2047 #define AST_LIST_HEAD_NOLOCK(name, type) \
2049 struct type *first; \
2050 struct type *last; \
2054 \brief Defines initial values for a declaration of AST_LIST_HEAD
2056 #define AST_LIST_HEAD_INIT_VALUE { \
2059 .lock = AST_MUTEX_INIT_VALUE, \
2063 \brief Defines initial values for a declaration of AST_RWLIST_HEAD
2065 #define AST_RWLIST_HEAD_INIT_VALUE { \
2068 .lock = AST_RWLOCK_INIT_VALUE, \
2072 \brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK
2074 #define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \
2080 \brief Defines a structure to be used to hold a list of specified type, statically initialized.
2081 \param name This will be the name of the defined structure.
2082 \param type This is the type of each list entry.
2084 This macro creates a structure definition that can be used
2085 to hold a list of the entries of type \a type, and allocates an instance
2086 of it, initialized to be empty.
2090 static AST_LIST_HEAD_STATIC(entry_list, entry);
2093 This would define \c struct \c entry_list, intended to hold a list of
2094 type \c struct \c entry.
2096 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
2097 #define AST_LIST_HEAD_STATIC(name, type) \
2099 struct type *first; \
2100 struct type *last; \
2103 static void __attribute__((constructor)) init_##name(void) \
2105 AST_LIST_HEAD_INIT(&name); \
2107 static void __attribute__((destructor)) fini_##name(void) \
2109 AST_LIST_HEAD_DESTROY(&name); \
2111 struct __dummy_##name
2113 #define AST_LIST_HEAD_STATIC(name, type) \
2115 struct type *first; \
2116 struct type *last; \
2118 } name = AST_LIST_HEAD_INIT_VALUE
2122 \brief Defines a structure to be used to hold a read/write list of specified type, statically initialized.
2123 \param name This will be the name of the defined structure.
2124 \param type This is the type of each list entry.
2126 This macro creates a structure definition that can be used
2127 to hold a list of the entries of type \a type, and allocates an instance
2128 of it, initialized to be empty.
2132 static AST_RWLIST_HEAD_STATIC(entry_list, entry);
2135 This would define \c struct \c entry_list, intended to hold a list of
2136 type \c struct \c entry.
2138 #ifndef AST_RWLOCK_INIT_VALUE
2139 #define AST_RWLIST_HEAD_STATIC(name, type) \
2141 struct type *first; \
2142 struct type *last; \
2143 ast_rwlock_t lock; \
2145 static void __attribute__((constructor)) init_##name(void) \
2147 AST_RWLIST_HEAD_INIT(&name); \
2149 static void __attribute__((destructor)) fini_##name(void) \
2151 AST_RWLIST_HEAD_DESTROY(&name); \
2153 struct __dummy_##name
2155 #define AST_RWLIST_HEAD_STATIC(name, type) \
2157 struct type *first; \
2158 struct type *last; \
2159 ast_rwlock_t lock; \
2160 } name = AST_RWLIST_HEAD_INIT_VALUE
2164 \brief Defines a structure to be used to hold a list of specified type, statically initialized.
2166 This is the same as AST_LIST_HEAD_STATIC, except without the lock included.
2168 #define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \
2170 struct type *first; \
2171 struct type *last; \
2172 } name = AST_LIST_HEAD_NOLOCK_INIT_VALUE
2175 \brief Initializes a list head structure with a specified first entry.
2176 \param head This is a pointer to the list head structure
2177 \param entry pointer to the list entry that will become the head of the list
2179 This macro initializes a list head structure by setting the head
2180 entry to the supplied value and recreating the embedded lock.
2182 #define AST_LIST_HEAD_SET(head, entry) do { \
2183 (head)->first = (entry); \
2184 (head)->last = (entry); \
2185 ast_mutex_init(&(head)->lock); \
2189 \brief Initializes an rwlist head structure with a specified first entry.
2190 \param head This is a pointer to the list head structure
2191 \param entry pointer to the list entry that will become the head of the list
2193 This macro initializes a list head structure by setting the head
2194 entry to the supplied value and recreating the embedded lock.
2196 #define AST_RWLIST_HEAD_SET(head, entry) do { \
2197 (head)->first = (entry); \
2198 (head)->last = (entry); \
2199 ast_rwlock_init(&(head)->lock); \
2203 \brief Initializes a list head structure with a specified first entry.
2204 \param head This is a pointer to the list head structure
2205 \param entry pointer to the list entry that will become the head of the list
2207 This macro initializes a list head structure by setting the head
2208 entry to the supplied value.
2210 #define AST_LIST_HEAD_SET_NOLOCK(head, entry) do { \
2211 (head)->first = (entry); \
2212 (head)->last = (entry); \
2216 \brief Declare a forward link structure inside a list entry.
2217 \param type This is the type of each list entry.
2219 This macro declares a structure to be used to link list entries together.
2220 It must be used inside the definition of the structure named in
2221 \a type, as follows:
2226 AST_LIST_ENTRY(list_entry) list;
2230 The field name \a list here is arbitrary, and can be anything you wish.
2232 #define AST_LIST_ENTRY(type) \
2234 struct type *next; \
2237 #define AST_RWLIST_ENTRY AST_LIST_ENTRY
2240 \brief Returns the first entry contained in a list.
2241 \param head This is a pointer to the list head structure
2243 #define AST_LIST_FIRST(head) ((head)->first)
2245 #define AST_RWLIST_FIRST AST_LIST_FIRST
2248 \brief Returns the last entry contained in a list.
2249 \param head This is a pointer to the list head structure
2251 #define AST_LIST_LAST(head) ((head)->last)
2253 #define AST_RWLIST_LAST AST_LIST_LAST
2256 \brief Returns the next entry in the list after the given entry.
2257 \param elm This is a pointer to the current entry.
2258 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2259 used to link entries of this list together.
2261 #define AST_LIST_NEXT(elm, field) ((elm)->field.next)
2263 #define AST_RWLIST_NEXT AST_LIST_NEXT
2266 \brief Checks whether the specified list contains any entries.
2267 \param head This is a pointer to the list head structure
2269 Returns non-zero if the list has entries, zero if not.
2271 #define AST_LIST_EMPTY(head) (AST_LIST_FIRST(head) == NULL)
2273 #define AST_RWLIST_EMPTY AST_LIST_EMPTY
2276 \brief Loops over (traverses) the entries in a list.
2277 \param head This is a pointer to the list head structure
2278 \param var This is the name of the variable that will hold a pointer to the
2279 current list entry on each iteration. It must be declared before calling
2281 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2282 used to link entries of this list together.
2284 This macro is use to loop over (traverse) the entries in a list. It uses a
2285 \a for loop, and supplies the enclosed code with a pointer to each list
2286 entry as it loops. It is typically used as follows:
2288 static AST_LIST_HEAD(entry_list, list_entry) entries;
2292 AST_LIST_ENTRY(list_entry) list;
2295 struct list_entry *current;
2297 AST_LIST_TRAVERSE(&entries, current, list) {
2298 (do something with current here)
2301 \warning If you modify the forward-link pointer contained in the \a current entry while
2302 inside the loop, the behavior will be unpredictable. At a minimum, the following
2303 macros will modify the forward-link pointer, and should not be used inside
2304 AST_LIST_TRAVERSE() against the entry pointed to by the \a current pointer without
2305 careful consideration of their consequences:
2306 \li AST_LIST_NEXT() (when used as an lvalue)
2307 \li AST_LIST_INSERT_AFTER()
2308 \li AST_LIST_INSERT_HEAD()
2309 \li AST_LIST_INSERT_TAIL()
2311 #define AST_LIST_TRAVERSE(head,var,field) \
2312 for((var) = (head)->first; (var); (var) = (var)->field.next)
2314 #define AST_RWLIST_TRAVERSE AST_LIST_TRAVERSE
2317 \brief Loops safely over (traverses) the entries in a list.
2318 \param head This is a pointer to the list head structure
2319 \param var This is the name of the variable that will hold a pointer to the
2320 current list entry on each iteration. It must be declared before calling
2322 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2323 used to link entries of this list together.
2325 This macro is used to safely loop over (traverse) the entries in a list. It
2326 uses a \a for loop, and supplies the enclosed code with a pointer to each list
2327 entry as it loops. It is typically used as follows:
2330 static AST_LIST_HEAD(entry_list, list_entry) entries;
2334 AST_LIST_ENTRY(list_entry) list;
2337 struct list_entry *current;
2339 AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
2340 (do something with current here)
2342 AST_LIST_TRAVERSE_SAFE_END;
2345 It differs from AST_LIST_TRAVERSE() in that the code inside the loop can modify
2346 (or even free, after calling AST_LIST_REMOVE_CURRENT()) the entry pointed to by
2347 the \a current pointer without affecting the loop traversal.
2349 #define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) { \
2350 typeof((head)->first) __list_next; \
2351 typeof((head)->first) __list_prev = NULL; \
2352 typeof((head)->first) __new_prev = NULL; \
2353 for ((var) = (head)->first, __new_prev = (var), \
2354 __list_next = (var) ? (var)->field.next : NULL; \
2356 __list_prev = __new_prev, (var) = __list_next, \
2357 __new_prev = (var), \
2358 __list_next = (var) ? (var)->field.next : NULL \
2361 #define AST_RWLIST_TRAVERSE_SAFE_BEGIN AST_LIST_TRAVERSE_SAFE_BEGIN
2364 \brief Removes the \a current entry from a list during a traversal.
2365 \param head This is a pointer to the list head structure
2366 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2367 used to link entries of this list together.
2369 \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
2370 block; it is used to unlink the current entry from the list without affecting
2371 the list traversal (and without having to re-traverse the list to modify the
2372 previous entry, if any).
2374 #define AST_LIST_REMOVE_CURRENT(head, field) \
2375 __new_prev->field.next = NULL; \
2376 __new_prev = __list_prev; \
2378 __list_prev->field.next = __list_next; \
2380 (head)->first = __list_next; \
2382 (head)->last = __list_prev;
2384 #define AST_RWLIST_REMOVE_CURRENT AST_LIST_REMOVE_CURRENT
2387 \brief Inserts a list entry before the current entry during a traversal.
2388 \param head This is a pointer to the list head structure
2389 \param elm This is a pointer to the entry to be inserted.
2390 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2391 used to link entries of this list together.
2393 \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
2396 #define AST_LIST_INSERT_BEFORE_CURRENT(head, elm, field) do { \
2397 if (__list_prev) { \
2398 (elm)->field.next = __list_prev->field.next; \
2399 __list_prev->field.next = elm; \
2401 (elm)->field.next = (head)->first; \
2402 (head)->first = (elm); \
2404 __new_prev = (elm); \
2407 #define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT
2410 \brief Closes a safe loop traversal block.
2412 #define AST_LIST_TRAVERSE_SAFE_END }
2414 #define AST_RWLIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END
2417 \brief Initializes a list head structure.
2418 \param head This is a pointer to the list head structure
2420 This macro initializes a list head structure by setting the head
2421 entry to \a NULL (empty list) and recreating the embedded lock.
2423 #define AST_LIST_HEAD_INIT(head) { \
2424 (head)->first = NULL; \
2425 (head)->last = NULL; \
2426 ast_mutex_init(&(head)->lock); \
2430 \brief Initializes an rwlist head structure.
2431 \param head This is a pointer to the list head structure
2433 This macro initializes a list head structure by setting the head
2434 entry to \a NULL (empty list) and recreating the embedded lock.
2436 #define AST_RWLIST_HEAD_INIT(head) { \
2437 (head)->first = NULL; \
2438 (head)->last = NULL; \
2439 ast_rwlock_init(&(head)->lock); \
2443 \brief Destroys a list head structure.
2444 \param head This is a pointer to the list head structure
2446 This macro destroys a list head structure by setting the head
2447 entry to \a NULL (empty list) and destroying the embedded lock.
2448 It does not free the structure from memory.
2450 #define AST_LIST_HEAD_DESTROY(head) { \
2451 (head)->first = NULL; \
2452 (head)->last = NULL; \
2453 ast_mutex_destroy(&(head)->lock); \
2457 \brief Destroys an rwlist head structure.
2458 \param head This is a pointer to the list head structure
2460 This macro destroys a list head structure by setting the head
2461 entry to \a NULL (empty list) and destroying the embedded lock.
2462 It does not free the structure from memory.
2464 #define AST_RWLIST_HEAD_DESTROY(head) { \
2465 (head)->first = NULL; \
2466 (head)->last = NULL; \
2467 ast_rwlock_destroy(&(head)->lock); \
2471 \brief Initializes a list head structure.
2472 \param head This is a pointer to the list head structure
2474 This macro initializes a list head structure by setting the head
2475 entry to \a NULL (empty list). There is no embedded lock handling
2478 #define AST_LIST_HEAD_INIT_NOLOCK(head) { \
2479 (head)->first = NULL; \
2480 (head)->last = NULL; \
2484 \brief Inserts a list entry after a given entry.
2485 \param head This is a pointer to the list head structure
2486 \param listelm This is a pointer to the entry after which the new entry should
2488 \param elm This is a pointer to the entry to be inserted.
2489 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2490 used to link entries of this list together.
2492 #define AST_LIST_INSERT_AFTER(head, listelm, elm, field) do { \
2493 (elm)->field.next = (listelm)->field.next; \
2494 (listelm)->field.next = (elm); \
2495 if ((head)->last == (listelm)) \
2496 (head)->last = (elm); \
2499 #define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER
2502 \brief Inserts a list entry at the head of a list.
2503 \param head This is a pointer to the list head structure
2504 \param elm This is a pointer to the entry to be inserted.
2505 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2506 used to link entries of this list together.
2508 #define AST_LIST_INSERT_HEAD(head, elm, field) do { \
2509 (elm)->field.next = (head)->first; \
2510 (head)->first = (elm); \
2511 if (!(head)->last) \
2512 (head)->last = (elm); \
2515 #define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD
2518 \brief Appends a list entry to the tail of a list.
2519 \param head This is a pointer to the list head structure
2520 \param elm This is a pointer to the entry to be appended.
2521 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2522 used to link entries of this list together.
2524 Note: The link field in the appended entry is \b not modified, so if it is
2525 actually the head of a list itself, the entire list will be appended
2526 temporarily (until the next AST_LIST_INSERT_TAIL is performed).
2528 #define AST_LIST_INSERT_TAIL(head, elm, field) do { \
2529 if (!(head)->first) { \
2530 (head)->first = (elm); \
2531 (head)->last = (elm); \
2533 (head)->last->field.next = (elm); \
2534 (head)->last = (elm); \
2538 #define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL
2541 \brief Appends a whole list to the tail of a list.
2542 \param head This is a pointer to the list head structure
2543 \param list This is a pointer to the list to be appended.
2544 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2545 used to link entries of this list together.
2547 #define AST_LIST_APPEND_LIST(head, list, field) do { \
2548 if (!(head)->first) { \
2549 (head)->first = (list)->first; \
2550 (head)->last = (list)->last; \
2552 (head)->last->field.next = (list)->first; \
2553 (head)->last = (list)->last; \
2557 #define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST
2560 \brief Removes and returns the head entry from a list.
2561 \param head This is a pointer to the list head structure
2562 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2563 used to link entries of this list together.
2565 Removes the head entry from the list, and returns a pointer to it.
2566 This macro is safe to call on an empty list.
2568 #define AST_LIST_REMOVE_HEAD(head, field) ({ \
2569 typeof((head)->first) cur = (head)->first; \
2571 (head)->first = cur->field.next; \
2572 cur->field.next = NULL; \
2573 if ((head)->last == cur) \
2574 (head)->last = NULL; \
2579 #define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD
2582 \brief Removes a specific entry from a list.
2583 \param head This is a pointer to the list head structure
2584 \param elm This is a pointer to the entry to be removed.
2585 \param field This is the name of the field (declared using AST_LIST_ENTRY())
2586 used to link entries of this list together.
2587 \warning The removed entry is \b not freed nor modified in any way.
2589 #define AST_LIST_REMOVE(head, elm, field) do { \
2590 if ((head)->first == (elm)) { \
2591 (head)->first = (elm)->field.next; \
2592 if ((head)->last == (elm)) \
2593 (head)->last = NULL; \
2595 typeof(elm) curelm = (head)->first; \
2596 while (curelm && (curelm->field.next != (elm))) \
2597 curelm = curelm->field.next; \
2599 curelm->field.next = (elm)->field.next; \
2600 if ((head)->last == (elm)) \
2601 (head)->last = curelm; \
2604 (elm)->field.next = NULL; \
2607 #define AST_RWLIST_REMOVE AST_LIST_REMOVE
2612 AST_LIST_ENTRY(ast_var_t) entries;
2617 AST_LIST_HEAD_NOLOCK(varshead, ast_var_t);
2619 AST_RWLOCK_DEFINE_STATIC(globalslock);
2620 static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
2623 /* IN CONFLICT: struct ast_var_t *ast_var_assign(const char *name, const char *value); */
2625 static struct ast_var_t *ast_var_assign(const char *name, const char *value);
2627 static void ast_var_delete(struct ast_var_t *var);
2630 #define AST_MAX_EXTENSION 80 /*!< Max length of an extension */
2634 #define PRIORITY_HINT -1 /*!< Special Priority for a hint */
2636 enum ast_extension_states {
2637 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */
2638 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */
2639 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */
2640 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */
2641 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */
2642 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */
2643 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */
2644 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */
2647 struct ast_custom_function {
2648 const char *name; /*!< Name */
2649 const char *synopsis; /*!< Short description for "show functions" */
2650 const char *desc; /*!< Help text that explains it all */
2651 const char *syntax; /*!< Syntax description */
2652 int (*read)(struct ast_channel *, const char *, char *, char *, size_t); /*!< Read function, if read is supported */
2653 int (*write)(struct ast_channel *, const char *, char *, const char *); /*!< Write function, if write is supported */
2654 AST_RWLIST_ENTRY(ast_custom_function) acflist;
2657 typedef int (ast_switch_f)(struct ast_channel *chan, const char *context,
2658 const char *exten, int priority, const char *callerid, const char *data);
2661 AST_LIST_ENTRY(ast_switch) list;
2662 const char *name; /*!< Name of the switch */
2663 const char *description; /*!< Description of the switch */
2665 ast_switch_f *exists;
2666 ast_switch_f *canmatch;
2668 ast_switch_f *matchmore;
2672 static char *config_filename = "extensions.conf";
2673 static char *global_registrar = "conf2ael";
2674 static char userscontext[AST_MAX_EXTENSION] = "default";
2675 static int static_config = 0;
2676 static int write_protect_config = 1;
2677 static int autofallthrough_config = 0;
2678 static int clearglobalvars_config = 0;
2679 /*! Go no deeper than this through includes (not counting loops) */
2680 #define AST_PBX_MAX_STACK 128
2681 static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
2684 /* stolen from callerid.c */
2686 /*! \brief Clean up phone string
2687 * remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets.
2688 * Basically, remove anything that could be invalid in a pattern.
2690 static void ast_shrink_phone_number(char *n)
2695 for (x=0; n[x]; x++) {
2714 if (!strchr("()", n[x]))
2722 /* stolen from chanvars.c */
2724 static const char *ast_var_name(const struct ast_var_t *var)
2728 if (var == NULL || (name = var->name) == NULL)
2730 /* Return the name without the initial underscores */
2731 if (name[0] == '_') {
2739 /* experiment 1: see if it's easier just to use existing config code
2740 * to read in the extensions.conf file. In this scenario,
2741 I have to rip/copy code from other modules, because they
2742 are staticly declared as-is. A solution would be to move
2743 the ripped code to another location and make them available
2744 to other modules and standalones */
2746 /* Our own version of ast_log, since the expr parser uses it. -- stolen from utils/check_expr.c */
2748 static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
2753 printf("LOG: lev:%d file:%s line:%d func: %s ",
2754 level, file, line, function);
2760 void __attribute__((format(printf, 1, 2))) ast_verbose(const char *fmt, ...)
2765 printf("VERBOSE: ");
2771 /* stolen from main/utils.c */
2772 static char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
2774 char *dataPut = start;
2778 for (; *start; start++) {
2780 *dataPut++ = *start; /* Always goes verbatim */
2783 if (*start == '\\') {
2784 inEscape = 1; /* Do not copy \ into the data */
2785 } else if (*start == '\'') {
2786 inQuotes = 1 - inQuotes; /* Do not copy ' into the data */
2788 /* Replace , with |, unless in quotes */
2789 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
2793 if (start != dataPut)
2798 static int ast_true(const char *s)
2800 if (ast_strlen_zero(s))
2803 /* Determine if this is a true value */
2804 if (!strcasecmp(s, "yes") ||
2805 !strcasecmp(s, "true") ||
2806 !strcasecmp(s, "y") ||
2807 !strcasecmp(s, "t") ||
2808 !strcasecmp(s, "1") ||
2809 !strcasecmp(s, "on"))
2815 #define ONE_MILLION 1000000
2817 * put timeval in a valid range. usec is 0..999999
2818 * negative values are not allowed and truncated.
2820 static struct timeval tvfix(struct timeval a)
2822 if (a.tv_usec >= ONE_MILLION) {
2823 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
2824 (long)a.tv_sec, (long int) a.tv_usec);
2825 a.tv_sec += a.tv_usec / ONE_MILLION;
2826 a.tv_usec %= ONE_MILLION;
2827 } else if (a.tv_usec < 0) {
2828 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
2829 (long)a.tv_sec, (long int) a.tv_usec);
2835 struct timeval ast_tvadd(struct timeval a, struct timeval b);
2836 struct timeval ast_tvadd(struct timeval a, struct timeval b)
2838 /* consistency checks to guarantee usec in 0..999999 */
2841 a.tv_sec += b.tv_sec;
2842 a.tv_usec += b.tv_usec;
2843 if (a.tv_usec >= ONE_MILLION) {
2845 a.tv_usec -= ONE_MILLION;
2850 struct timeval ast_tvsub(struct timeval a, struct timeval b);
2851 struct timeval ast_tvsub(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 < 0) {
2860 a.tv_usec += ONE_MILLION;
2866 void ast_mark_lock_failed(void *lock_addr);
2867 void ast_mark_lock_failed(void *lock_addr)
2869 /* Pretend to do something. */
2872 /* stolen from pbx.c */
2873 #define VAR_BUF_SIZE 4096
2875 #define VAR_NORMAL 1
2876 #define VAR_SOFTTRAN 2
2877 #define VAR_HARDTRAN 3
2879 #define BACKGROUND_SKIP (1 << 0)
2880 #define BACKGROUND_NOANSWER (1 << 1)
2881 #define BACKGROUND_MATCHEXTEN (1 << 2)
2882 #define BACKGROUND_PLAYBACK (1 << 3)
2885 \brief ast_exten: An extension
2886 The dialplan is saved as a linked list with each context
2887 having it's own linked list of extensions - one item per
2891 char *exten; /*!< Extension name */
2892 int matchcid; /*!< Match caller id ? */
2893 const char *cidmatch; /*!< Caller id to match for this extension */
2894 int priority; /*!< Priority */
2895 const char *label; /*!< Label */
2896 struct ast_context *parent; /*!< The context this extension belongs to */
2897 const char *app; /*!< Application to execute */
2898 struct ast_app *cached_app; /*!< Cached location of application */
2899 void *data; /*!< Data to use (arguments) */
2900 void (*datad)(void *); /*!< Data destructor */
2901 struct ast_exten *peer; /*!< Next higher priority with our extension */
2902 const char *registrar; /*!< Registrar */
2903 struct ast_exten *next; /*!< Extension with a greater ID */
2907 typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data);
2909 int hastime; /*!< If time construct exists */
2910 unsigned int monthmask; /*!< Mask for month */
2911 unsigned int daymask; /*!< Mask for date */
2912 unsigned int dowmask; /*!< Mask for day of week (mon-sun) */
2913 unsigned int minmask[48]; /*!< Mask for minute */
2914 char *timezone; /*!< NULL, or zoneinfo style timezone */
2917 /*! \brief ast_include: include= support in extensions.conf */
2918 struct ast_include {
2920 const char *rname; /*!< Context to include */
2921 const char *registrar; /*!< Registrar */
2922 int hastime; /*!< If time construct exists */
2923 struct ast_timing timing; /*!< time construct */
2924 struct ast_include *next; /*!< Link them together */
2928 /*! \brief ast_sw: Switch statement in extensions.conf */
2931 const char *registrar; /*!< Registrar */
2932 char *data; /*!< Data load */
2934 AST_LIST_ENTRY(ast_sw) list;
2939 /*! \brief ast_ignorepat: Ignore patterns in dial plan */
2940 struct ast_ignorepat {
2941 const char *registrar;
2942 struct ast_ignorepat *next;
2946 /*! \brief ast_context: An extension context */
2947 struct ast_context {
2948 ast_rwlock_t lock; /*!< A lock to prevent multiple threads from clobbering the context */
2949 struct ast_exten *root; /*!< The root of the list of extensions */
2950 struct ast_context *next; /*!< Link them together */
2951 struct ast_include *includes; /*!< Include other contexts */
2952 struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
2953 const char *registrar; /*!< Registrar */
2954 AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
2955 ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
2956 char name[0]; /*!< Name of the context */
2960 /*! \brief ast_app: A registered application */
2962 int (*execute)(struct ast_channel *chan, void *data);
2963 const char *synopsis; /*!< Synopsis text for 'show applications' */
2964 const char *description; /*!< Description (help text) for 'show application <name>' */
2965 AST_RWLIST_ENTRY(ast_app) list; /*!< Next app in list */
2966 void *module; /*!< Module this app belongs to */
2967 char name[0]; /*!< Name of the application */
2971 /*! \brief ast_state_cb: An extension state notify register item */
2972 struct ast_state_cb {
2975 ast_state_cb_type callback;
2976 struct ast_state_cb *next;
2979 /*! \brief Structure for dial plan hints
2981 \note Hints are pointers from an extension in the dialplan to one or
2982 more devices (tech/name)
2983 - See \ref AstExtState
2986 struct ast_exten *exten; /*!< Extension */
2987 int laststate; /*!< Last known state */
2988 struct ast_state_cb *callbacks; /*!< Callback list for this extension */
2989 AST_RWLIST_ENTRY(ast_hint) list;/*!< Pointer to next hint in list */
2995 struct ast_state_cb *callbacks;
2997 AST_LIST_ENTRY(store_hint) list;
3001 AST_LIST_HEAD(store_hints, store_hint);
3003 static const struct cfextension_states {
3004 int extension_state;
3005 const char * const text;
3006 } extension_states[] = {
3007 { AST_EXTENSION_NOT_INUSE, "Idle" },
3008 { AST_EXTENSION_INUSE, "InUse" },
3009 { AST_EXTENSION_BUSY, "Busy" },
3010 { AST_EXTENSION_UNAVAILABLE, "Unavailable" },
3011 { AST_EXTENSION_RINGING, "Ringing" },
3012 { AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
3013 { AST_EXTENSION_ONHOLD, "Hold" },
3014 { AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD, "InUse&Hold" }
3016 #define STATUS_NO_CONTEXT 1
3017 #define STATUS_NO_EXTENSION 2
3018 #define STATUS_NO_PRIORITY 3
3019 #define STATUS_NO_LABEL 4
3020 #define STATUS_SUCCESS 5
3023 #if defined ( __i386__) && (defined(__FreeBSD__) || defined(linux))
3024 #if defined(__FreeBSD__)
3025 #include <machine/cpufunc.h>
3026 #elif defined(linux)
3027 static __inline uint64_t
3032 __asm __volatile(".byte 0x0f, 0x31" : "=A" (rv));
3036 #else /* supply a dummy function on other platforms */
3037 static __inline uint64_t
3045 static struct ast_var_t *ast_var_assign(const char *name, const char *value)
3047 struct ast_var_t *var;
3048 int name_len = strlen(name) + 1;
3049 int value_len = strlen(value) + 1;
3051 if (!(var = ast_calloc(sizeof(*var) + name_len + value_len, sizeof(char)))) {
3055 ast_copy_string(var->name, name, name_len);
3056 var->value = var->name + name_len;
3057 ast_copy_string(var->value, value, value_len);
3062 static void ast_var_delete(struct ast_var_t *var)
3068 /* chopped this one off at the knees! */
3069 static int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
3072 /* ast_log(LOG_ERROR, "Function %s not registered\n", function); we are not interested in the details here */
3077 static unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
3081 int paren = 0, quote = 0;
3083 if (!buf || !array || !arraylen)
3086 memset(array, 0, arraylen * sizeof(*array));
3090 for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
3092 for (; *scan; scan++) {
3095 else if (*scan == ')') {
3098 } else if (*scan == '"' && delim != '"') {
3099 quote = quote ? 0 : 1;
3100 /* Remove quote character from argument */
3101 memmove(scan, scan + 1, strlen(scan));
3103 } else if (*scan == '\\') {
3104 /* Literal character, don't parse */
3105 memmove(scan, scan + 1, strlen(scan));
3106 } else if ((*scan == delim) && !paren && !quote) {
3114 array[argc++] = scan;
3119 static void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
3121 struct ast_var_t *newvariable;
3122 struct varshead *headp;
3123 const char *nametail = name;
3125 /* XXX may need locking on the channel ? */
3126 if (name[strlen(name)-1] == ')') {
3127 char *function = ast_strdupa(name);
3129 ast_func_write(chan, function, value);
3135 /* For comparison purposes, we have to strip leading underscores */
3136 if (*nametail == '_') {
3138 if (*nametail == '_')
3142 AST_LIST_TRAVERSE (headp, newvariable, entries) {
3143 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
3144 /* there is already such a variable, delete it */
3145 AST_LIST_REMOVE(headp, newvariable, entries);
3146 ast_var_delete(newvariable);
3152 if ((option_verbose > 1) && (headp == &globals))
3153 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
3154 newvariable = ast_var_assign(name, value);
3155 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
3160 static int pbx_builtin_setvar(struct ast_channel *chan, const void *data)
3162 char *name, *value, *mydata;
3164 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */
3168 if (ast_strlen_zero(data)) {
3169 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n");
3173 mydata = ast_strdupa(data);
3174 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
3176 /* check for a trailing flags argument */
3177 if ((argc > 1) && !strchr(argv[argc-1], '=')) {
3179 if (strchr(argv[argc], 'g'))
3183 for (x = 0; x < argc; x++) {
3185 if ((value = strchr(name, '='))) {
3187 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value);
3189 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name);
3195 int localized_pbx_builtin_setvar(struct ast_channel *chan, const void *data);
3197 int localized_pbx_builtin_setvar(struct ast_channel *chan, const void *data)
3199 return pbx_builtin_setvar(chan, data);
3203 /*! \brief Helper for get_range.
3204 * return the index of the matching entry, starting from 1.
3205 * If names is not supplied, try numeric values.
3207 static int lookup_name(const char *s, char *const names[], int max)
3211 if (names && *s > '9') {
3212 for (i = 0; names[i]; i++) {
3213 if (!strcasecmp(s, names[i])) {
3219 /* Allow months and weekdays to be specified as numbers, as well */
3220 if (sscanf(s, "%2d", &i) == 1 && i >= 1 && i <= max) {
3221 /* What the array offset would have been: "1" would be at offset 0 */
3224 return -1; /* error return */
3227 /*! \brief helper function to return a range up to max (7, 12, 31 respectively).
3228 * names, if supplied, is an array of names that should be mapped to numbers.
3230 static unsigned get_range(char *src, int max, char *const names[], const char *msg)
3232 int start, end; /* start and ending position */
3233 unsigned int mask = 0;
3236 /* Check for whole range */
3237 if (ast_strlen_zero(src) || !strcmp(src, "*")) {
3238 return (1 << max) - 1;
3241 while ((part = strsep(&src, "&"))) {
3242 /* Get start and ending position */
3243 char *endpart = strchr(part, '-');
3247 /* Find the start */
3248 if ((start = lookup_name(part, names, max)) < 0) {
3249 ast_log(LOG_WARNING, "Invalid %s '%s', skipping element\n", msg, part);
3252 if (endpart) { /* find end of range */
3253 if ((end = lookup_name(endpart, names, max)) < 0) {
3254 ast_log(LOG_WARNING, "Invalid end %s '%s', skipping element\n", msg, endpart);
3260 /* Fill the mask. Remember that ranges are cyclic */
3261 mask |= (1 << end); /* initialize with last element */
3262 while (start != end) {
3266 mask |= (1 << start);
3273 /*! \brief store a bitmask of valid times, one bit each 2 minute */
3274 static void get_timerange(struct ast_timing *i, char *times)
3276 char *endpart, *part;
3280 int minute_start, minute_end;
3282 /* start disabling all times, fill the fields with 0's, as they may contain garbage */
3283 memset(i->minmask, 0, sizeof(i->minmask));
3285 /* 1-minute per bit */
3286 /* Star is all times */
3287 if (ast_strlen_zero(times) || !strcmp(times, "*")) {
3288 /* 48, because each hour takes 2 integers; 30 bits each */
3289 for (x = 0; x < 48; x++) {
3290 i->minmask[x] = 0x3fffffff; /* 30 bits */
3294 /* Otherwise expect a range */
3295 while ((part = strsep(×, "&"))) {
3296 if (!(endpart = strchr(part, '-'))) {
3297 if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
3298 ast_log(LOG_WARNING, "%s isn't a valid time.\n", part);
3301 i->minmask[st_h * 2 + (st_m >= 30 ? 1 : 0)] |= (1 << (st_m % 30));
3305 /* why skip non digits? Mostly to skip spaces */
3306 while (*endpart && !isdigit(*endpart)) {
3310 ast_log(LOG_WARNING, "Invalid time range starting with '%s-'.\n", part);