46 #define ASTMM_LIBC ASTMM_IGNORE 57 #include <sys/types.h> 59 #include <sys/resource.h> 65 #if !defined(SOLARIS) && !defined(__CYGWIN__) 72 #include <sys/param.h> 75 static void ast_log(
int level,
const char *
file,
int line,
const char *
function,
const char *fmt, ...) __attribute__((
format(printf, 5, 6)));
78 #define AST_API_MODULE 1 93 #define EVENTLOG "event_log" 94 #define QUEUELOG "queue_log" 96 #define DEBUG_M(a) { \ 100 #define VERBOSE_PREFIX_1 " " 101 #define VERBOSE_PREFIX_2 " == " 102 #define VERBOSE_PREFIX_3 " -- " 103 #define VERBOSE_PREFIX_4 " > " 107 void ast_queue_log(
const char *queuename,
const char *
callid,
const char *agent,
const char *
event,
const char *fmt, ...)
108 __attribute__((
format(printf, 5, 6)));
115 #define _A_ __FILE__, __LINE__, __PRETTY_FUNCTION__ 120 #define __LOG_DEBUG 0 121 #define LOG_DEBUG __LOG_DEBUG, _A_ 126 #define __LOG_EVENT 1 127 #define LOG_EVENT __LOG_EVENT, _A_ 132 #define __LOG_NOTICE 2 133 #define LOG_NOTICE __LOG_NOTICE, _A_ 138 #define __LOG_WARNING 3 139 #define LOG_WARNING __LOG_WARNING, _A_ 144 #define __LOG_ERROR 4 145 #define LOG_ERROR __LOG_ERROR, _A_ 150 #define __LOG_VERBOSE 5 151 #define LOG_VERBOSE __LOG_VERBOSE, _A_ 157 #define LOG_DTMF __LOG_DTMF, _A_ 160 #define _ASTERISK_LOCK_H 162 #ifndef HAVE_MTX_PROFILE 163 #define __MTX_PROF(a) return pthread_mutex_lock((a)) 167 #define __MTX_PROF(a) do { \ 170 ast_mark(mtx_prof, 1); \ 171 i = pthread_mutex_trylock((a)); \ 172 ast_mark(mtx_prof, 0); \ 176 return pthread_mutex_lock((a)); \ 180 #define AST_PTHREADT_NULL (pthread_t) -1 181 #define AST_PTHREADT_STOP (pthread_t) -2 183 #if defined(SOLARIS) || defined(BSD) 184 #define AST_MUTEX_INIT_W_CONSTRUCTORS 189 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) && defined(PTHREAD_MUTEX_RECURSIVE_NP) 190 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 191 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP 193 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_MUTEX_INITIALIZER 194 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE 199 #define log_mutex_error(canlog, ...) do { if (canlog) ast_log(LOG_ERROR, __VA_ARGS__); else fprintf(stderr, __VA_ARGS__); } while (0) 202 #define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0) 204 #define DO_THREAD_CRASH do { } while (0) 207 #define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, { NULL }, { 0 }, 0, { NULL }, { 0 } } 209 #define AST_MAX_REENTRANCY 10 214 unsigned int track:1;
228 static void __attribute__((constructor)) init_empty_mutex(
void)
230 memset(&empty_mutex, 0,
sizeof(empty_mutex));
233 static inline int __ast_pthread_mutex_init_attr(
const char *filename,
int lineno,
const char *func,
234 const char *mutex_name, ast_mutex_t *t,
235 pthread_mutexattr_t *attr)
237 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS 238 int canlog = strcmp(filename,
"logger.c");
241 if ((t->
mutex) != (empty_mutex)) {
242 log_mutex_error(canlog,
"%s line %d (%s): Error: mutex '%s' is already initialized.\n",
243 filename, lineno, func, mutex_name);
244 log_mutex_error(canlog,
"%s line %d (%s): Error: previously initialization of mutex '%s'.\n",
245 t->file[0], t->lineno[0], t->func[0], mutex_name);
252 t->file[0] = filename;
253 t->lineno[0] = lineno;
262 const char *mutex_name, ast_mutex_t *t)
264 static pthread_mutexattr_t attr;
266 pthread_mutexattr_init(&attr);
269 return __ast_pthread_mutex_init_attr(filename, lineno, func, mutex_name, t, &attr);
271 #define ast_mutex_init(pmutex) __ast_pthread_mutex_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex) 274 const char *mutex_name, ast_mutex_t *t)
277 int canlog = strcmp(filename,
"logger.c");
279 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS 281 log_mutex_error(canlog,
"%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
282 filename, lineno, func, mutex_name);
292 log_mutex_error(canlog,
"%s line %d (%s): Error: attempt to destroy invalid mutex '%s'.\n",
293 filename, lineno, func, mutex_name);
296 log_mutex_error(canlog,
"%s line %d (%s): Error: attempt to destroy locked mutex '%s'.\n",
297 filename, lineno, func, mutex_name);
298 log_mutex_error(canlog,
"%s line %d (%s): Error: '%s' was locked here.\n",
299 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
304 log_mutex_error(canlog,
"%s line %d (%s): Error destroying mutex: %s\n",
305 filename, lineno, func, strerror(res));
306 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 310 t->file[0] = filename;
311 t->lineno[0] = lineno;
318 const char* mutex_name, ast_mutex_t *t)
321 int canlog = strcmp(filename,
"logger.c");
323 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) 325 log_mutex_error(canlog,
"%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
326 filename, lineno, func, mutex_name);
331 #ifdef DETECT_DEADLOCKS 333 time_t seconds = time(
NULL);
336 #ifdef HAVE_MTX_PROFILE 340 #ifdef HAVE_MTX_PROFILE 344 current = time(
NULL);
345 if ((current - seconds) && (!((current - seconds) % 5))) {
346 log_mutex_error(canlog,
"%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n",
347 filename, lineno, func, (
int)(current - seconds), mutex_name);
349 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
350 t->func[t->reentrancy-1], mutex_name);
354 }
while (res == EBUSY);
357 #ifdef HAVE_MTX_PROFILE 368 t->file[t->reentrancy] = filename;
369 t->lineno[t->reentrancy] = lineno;
370 t->func[t->reentrancy] = func;
371 t->thread[t->reentrancy] = pthread_self();
374 log_mutex_error(canlog,
"%s line %d (%s): '%s' really deep reentrancy!\n",
375 filename, lineno, func, mutex_name);
378 log_mutex_error(canlog,
"%s line %d (%s): Error obtaining mutex: %s\n",
379 filename, lineno, func, strerror(
errno));
387 const char* mutex_name, ast_mutex_t *t)
390 int canlog = strcmp(filename,
"logger.c");
392 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) 394 log_mutex_error(canlog,
"%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
395 filename, lineno, func, mutex_name);
402 t->file[t->reentrancy] = filename;
403 t->lineno[t->reentrancy] = lineno;
404 t->func[t->reentrancy] = func;
405 t->thread[t->reentrancy] = pthread_self();
408 log_mutex_error(canlog,
"%s line %d (%s): '%s' really deep reentrancy!\n",
409 filename, lineno, func, mutex_name);
412 log_mutex_error(canlog,
"%s line %d (%s): Warning: '%s' was locked here.\n",
413 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
420 const char *mutex_name, ast_mutex_t *t)
423 int canlog = strcmp(filename,
"logger.c");
425 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS 427 log_mutex_error(canlog,
"%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
428 filename, lineno, func, mutex_name);
432 if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
433 log_mutex_error(canlog,
"%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
434 filename, lineno, func, mutex_name);
436 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
440 if (--t->reentrancy < 0) {
441 log_mutex_error(canlog,
"%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
442 filename, lineno, func, mutex_name);
447 t->file[t->reentrancy] =
NULL;
448 t->lineno[t->reentrancy] = 0;
449 t->func[t->reentrancy] =
NULL;
450 t->thread[t->reentrancy] = 0;
454 log_mutex_error(canlog,
"%s line %d (%s): Error releasing mutex: %s\n",
455 filename, lineno, func, strerror(res));
467 #define AST_MUTEX_INIT_VALUE ((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE) 471 pthread_mutexattr_t attr;
473 pthread_mutexattr_init(&attr);
479 #define ast_pthread_mutex_init(pmutex,a) pthread_mutex_init(pmutex,a) 485 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) 488 #define __AST_MUTEX_DEFINE(scope, mutex) \ 489 scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE; \ 490 static void __attribute__((constructor)) init_##mutex(void) \ 492 ast_mutex_init(&mutex); \ 496 #define __AST_MUTEX_DEFINE(scope, mutex) \ 497 scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE 500 #define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t 501 #define pthread_mutex_init use_ast_mutex_init_instead_of_pthread_mutex_init 502 #define pthread_cond_t use_ast_cond_t_instead_of_pthread_cond_t 504 #define AST_MUTEX_DEFINE_STATIC(mutex) __AST_MUTEX_DEFINE(static, mutex) 506 #define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__ 508 #define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__ 511 #define pthread_create __use_ast_pthread_create_instead__ 518 pthread_rwlockattr_t attr;
520 pthread_rwlockattr_init(&attr);
522 #ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP 523 pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP);
526 return pthread_rwlock_init(prwlock, &attr);
531 return pthread_rwlock_destroy(prwlock);
536 return pthread_rwlock_unlock(prwlock);
541 return pthread_rwlock_rdlock(prwlock);
546 return pthread_rwlock_wrlock(prwlock);
551 #ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER 552 #define __AST_RWLOCK_DEFINE(scope, rwlock) \ 553 scope ast_rwlock_t rwlock; \ 554 static void __attribute__((constructor)) init_##rwlock(void) \ 556 ast_rwlock_init(&rwlock); \ 558 static void __attribute__((destructor)) fini_##rwlock(void) \ 560 ast_rwlock_destroy(&rwlock); \ 563 #define AST_RWLOCK_INIT_VALUE PTHREAD_RWLOCK_INITIALIZER 564 #define __AST_RWLOCK_DEFINE(scope, rwlock) \ 565 scope ast_rwlock_t rwlock = AST_RWLOCK_INIT_VALUE 568 #define AST_RWLOCK_DEFINE_STATIC(rwlock) __AST_RWLOCK_DEFINE(static, rwlock) 580 #if defined(HAVE_OSX_ATOMICS) 581 #include "libkern/OSAtomic.h" 589 #if defined(HAVE_GCC_ATOMICS) 592 return __sync_fetch_and_add(p, v);
594 #elif defined(HAVE_OSX_ATOMICS) && (
SIZEOF_INT == 4)
597 return OSAtomicAdd32(v, (
int32_t *) p);
599 #elif defined(HAVE_OSX_ATOMICS) && (
SIZEOF_INT == 8)
602 return OSAtomicAdd64(v, (int64_t *) p);
603 #elif defined (__i386__) || defined(__x86_64__) 607 " lock xaddl %0, %1 ; " 614 static int ast_atomic_fetchadd_int_slow(
volatile int *p,
int v)
623 return ast_atomic_fetchadd_int_slow(p, v);
633 return __sync_sub_and_fetch(p, 1) == 0;
635 #elif defined(HAVE_OSX_ATOMICS) && (
SIZEOF_INT == 4)
638 return OSAtomicAdd32( -1, (
int32_t *) p) == 0;
640 #elif defined(HAVE_OSX_ATOMICS) && (
SIZEOF_INT == 8)
643 return OSAtomicAdd64( -1, (int64_t *) p) == 0;
652 #ifdef DEBUG_CHANNEL_LOCKS
677 #define ast_test_flag(p,flag) ({ \ 678 typeof ((p)->flags) __p = (p)->flags; \ 679 unsigned int __x = 0; \ 680 (void) (&__p == &__x); \ 681 ((p)->flags & (flag)); \ 684 #define ast_set2_flag(p,value,flag) do { \ 685 typeof ((p)->flags) __p = (p)->flags; \ 686 unsigned int __x = 0; \ 687 (void) (&__p == &__x); \ 689 (p)->flags |= (flag); \ 691 (p)->flags &= ~(flag); \ 696 #define MAX_NESTED_COMMENTS 128 697 #define COMMENT_START ";--" 698 #define COMMENT_END "--;" 699 #define COMMENT_META ';' 700 #define COMMENT_TAG '-' 720 if (!comment_buffer) {
724 comment_buffer[0] = 0;
732 comment_buffer[0] = 0;
739 int rem = comment_buffer_size - strlen(comment_buffer) - 1;
740 int siz = strlen(str);
742 comment_buffer =
ast_realloc(comment_buffer, comment_buffer_size +
CB_INCR + siz + 1);
745 comment_buffer_size +=
CB_INCR+siz+1;
747 strcat(comment_buffer,str);
752 int cbl = strlen(comment_buffer) + 1;
753 int rem = comment_buffer_size - cbl;
755 comment_buffer =
ast_realloc(comment_buffer, comment_buffer_size +
CB_INCR + len + 1);
758 comment_buffer_size +=
CB_INCR+len+1;
760 strncat(comment_buffer,str,len);
761 comment_buffer[cbl+len-1] = 0;
766 int rem = lline_buffer_size - strlen(lline_buffer) - 1;
767 int siz = strlen(str);
772 lline_buffer_size +=
CB_INCR + siz + 1;
774 strcat(lline_buffer,str);
779 comment_buffer[0] = 0;
796 .sa_flags = SA_RESTART,
805 level = safe_system_level++;
832 #ifdef HAVE_WORKING_FORK 838 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK) 841 #ifdef HAVE_WORKING_FORK 848 #ifdef HAVE_WORKING_FORK 850 for (x = STDERR_FILENO + 1; x < 4096; x++)
853 execl(
"/bin/sh",
"/bin/sh",
"-c", s, (
char *)
NULL);
855 }
else if (pid > 0) {
857 res = waitpid(pid, &status, 0);
861 }
else if (
errno != EINTR)
880 strcpy(x->
cmt, buffer);
895 #define MAX_INCLUDE_LEVEL 10 917 int max_include_level;
922 char *include_location_file;
923 int include_location_lineno;
954 return (!s || (*s ==
'\0'));
957 #define S_OR(a, b) (!ast_strlen_zero(a) ? (a) : (b)) 962 while (*src && size) {
966 if (__builtin_expect(!size, 0))
975 while (*str && *str < 33)
993 work += strlen(work) - 1;
1000 while ((work >= str) && *work < 33)
1059 int name_len = strlen(name) + 1;
1060 size_t value_len = strlen(value) + 1;
1061 size_t filename_len = strlen(filename) + 1;
1063 if ((variable =
ast_calloc(1, name_len + value_len + filename_len +
sizeof(*variable)))) {
1065 variable->
value = variable->
stuff + name_len;
1066 variable->
file = variable->
value + value_len;
1067 strcpy(variable->
name,name);
1087 snprintf(real_included_file_name, real_included_file_name_size,
"%s~~%d", included_file, inc->
inclusion_count);
1088 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);
1090 *real_included_file_name = 0;
1100 inc->
exec = is_exec;
1117 int from_len = strlen(from_file);
1118 int to_len = strlen(to_file);
1120 if (strcmp(from_file, to_file) == 0)
1134 if (from_len >= to_len)
1142 for (cat = conf->
root; cat; cat = cat->
next) {
1143 if (strcmp(cat->
file,from_file) == 0) {
1144 if (from_len >= to_len)
1145 strcpy(cat->
file, to_file);
1151 for (v = cat->
root; v; v = v->
next) {
1152 if (strcmp(v->
file,from_file) == 0) {
1153 if (from_len >= to_len)
1154 strcpy(v->
file, to_file);
1185 category->
root = variable;
1186 category->
last = variable;
1198 for (cat = config->
root; cat; cat = cat->
next) {
1199 if (cat->
name == category_name && (ignored || !cat->
ignored))
1203 for (cat = config->
root; cat; cat = cat->
next) {
1204 if (!strcasecmp(cat->
name, category_name) && (ignored || !cat->
ignored))
1234 if (!strcasecmp(variable, v->
name))
1240 for (cat = config->
root; cat; cat = cat->
next)
1241 for (v = cat->
root; v; v = v->
next)
1242 if (!strcasecmp(variable, v->
name))
1254 new->lineno = old->
lineno;
1255 new->object = old->
object;
1278 for (incl=incls; incl; incl = inclnext) {
1279 inclnext = incl->
next;
1359 #define AST_CACHE_DIR_LEN 512 1360 #define AST_FILENAME_MAX 80 1363 #define AST_DEFAULT_OPTIONS AST_OPT_FLAG_TRANSCODE_VIA_SLIN 1367 #define ast_opt_exec_includes ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) 1368 #define ast_opt_no_fork ast_test_flag(&ast_options, AST_OPT_FLAG_NO_FORK) 1369 #define ast_opt_quiet ast_test_flag(&ast_options, AST_OPT_FLAG_QUIET) 1370 #define ast_opt_console ast_test_flag(&ast_options, AST_OPT_FLAG_CONSOLE) 1371 #define ast_opt_high_priority ast_test_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY) 1372 #define ast_opt_init_keys ast_test_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS) 1373 #define ast_opt_remote ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE) 1374 #define ast_opt_exec ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC) 1375 #define ast_opt_no_color ast_test_flag(&ast_options, AST_OPT_FLAG_NO_COLOR) 1376 #define ast_fully_booted ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED) 1377 #define ast_opt_transcode_via_slin ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) 1378 #define ast_opt_priority_jumping ast_test_flag(&ast_options, AST_OPT_FLAG_PRIORITY_JUMPING) 1379 #define ast_opt_dump_core ast_test_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE) 1380 #define ast_opt_cache_record_files ast_test_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES) 1381 #define ast_opt_timestamp ast_test_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP) 1382 #define ast_opt_override_config ast_test_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG) 1383 #define ast_opt_reconnect ast_test_flag(&ast_options, AST_OPT_FLAG_RECONNECT) 1384 #define ast_opt_transmit_silence ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) 1385 #define ast_opt_dont_warn ast_test_flag(&ast_options, AST_OPT_FLAG_DONT_WARN) 1386 #define ast_opt_always_fork ast_test_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK) 1387 #define ast_opt_mute ast_test_flag(&ast_options, AST_OPT_FLAG_MUTE) 1414 #define AST_RWLIST_WRLOCK(head) \ 1415 ast_rwlock_wrlock(&(head)->lock) 1425 #define AST_RWLIST_RDLOCK(head) \ 1426 ast_rwlock_rdlock(&(head)->lock) 1436 #define AST_RWLIST_UNLOCK(head) \ 1437 ast_rwlock_unlock(&(head)->lock) 1458 #define AST_LIST_HEAD(name, type) \ 1460 struct type *first; \ 1461 struct type *last; \ 1484 #define AST_RWLIST_HEAD(name, type) \ 1486 struct type *first; \ 1487 struct type *last; \ 1488 ast_rwlock_t lock; \ 1510 #define AST_LIST_HEAD_NOLOCK(name, type) \ 1512 struct type *first; \ 1513 struct type *last; \ 1519 #define AST_LIST_HEAD_INIT_VALUE { \ 1522 .lock = AST_MUTEX_INIT_VALUE, \ 1528 #define AST_RWLIST_HEAD_INIT_VALUE { \ 1531 .lock = AST_RWLOCK_INIT_VALUE, \ 1537 #define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \ 1559 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) 1560 #define AST_LIST_HEAD_STATIC(name, type) \ 1562 struct type *first; \ 1563 struct type *last; \ 1566 static void __attribute__((constructor)) init_##name(void) \ 1568 AST_LIST_HEAD_INIT(&name); \ 1570 static void __attribute__((destructor)) fini_##name(void) \ 1572 AST_LIST_HEAD_DESTROY(&name); \ 1574 struct __dummy_##name 1576 #define AST_LIST_HEAD_STATIC(name, type) \ 1578 struct type *first; \ 1579 struct type *last; \ 1581 } name = AST_LIST_HEAD_INIT_VALUE 1601 #ifndef AST_RWLOCK_INIT_VALUE 1602 #define AST_RWLIST_HEAD_STATIC(name, type) \ 1604 struct type *first; \ 1605 struct type *last; \ 1606 ast_rwlock_t lock; \ 1608 static void __attribute__((constructor)) init_##name(void) \ 1610 AST_RWLIST_HEAD_INIT(&name); \ 1612 static void __attribute__((destructor)) fini_##name(void) \ 1614 AST_RWLIST_HEAD_DESTROY(&name); \ 1616 struct __dummy_##name 1618 #define AST_RWLIST_HEAD_STATIC(name, type) \ 1620 struct type *first; \ 1621 struct type *last; \ 1622 ast_rwlock_t lock; \ 1623 } name = AST_RWLIST_HEAD_INIT_VALUE 1631 #define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \ 1633 struct type *first; \ 1634 struct type *last; \ 1635 } name = AST_LIST_HEAD_NOLOCK_INIT_VALUE 1645 #define AST_LIST_HEAD_SET(head, entry) do { \ 1646 (head)->first = (entry); \ 1647 (head)->last = (entry); \ 1648 ast_mutex_init(&(head)->lock); \ 1659 #define AST_RWLIST_HEAD_SET(head, entry) do { \ 1660 (head)->first = (entry); \ 1661 (head)->last = (entry); \ 1662 ast_rwlock_init(&(head)->lock); \ 1673 #define AST_LIST_HEAD_SET_NOLOCK(head, entry) do { \ 1674 (head)->first = (entry); \ 1675 (head)->last = (entry); \ 1695 #define AST_LIST_ENTRY(type) \ 1697 struct type *next; \ 1700 #define AST_RWLIST_ENTRY AST_LIST_ENTRY 1706 #define AST_LIST_FIRST(head) ((head)->first) 1708 #define AST_RWLIST_FIRST AST_LIST_FIRST 1714 #define AST_LIST_LAST(head) ((head)->last) 1716 #define AST_RWLIST_LAST AST_LIST_LAST 1724 #define AST_LIST_NEXT(elm, field) ((elm)->field.next) 1726 #define AST_RWLIST_NEXT AST_LIST_NEXT 1734 #define AST_LIST_EMPTY(head) (AST_LIST_FIRST(head) == NULL) 1736 #define AST_RWLIST_EMPTY AST_LIST_EMPTY 1774 #define AST_LIST_TRAVERSE(head,var,field) \ 1775 for((var) = (head)->first; (var); (var) = (var)->field.next) 1777 #define AST_RWLIST_TRAVERSE AST_LIST_TRAVERSE 1812 #define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) { \ 1813 typeof((head)->first) __list_next; \ 1814 typeof((head)->first) __list_prev = NULL; \ 1815 typeof((head)->first) __new_prev = NULL; \ 1816 for ((var) = (head)->first, __new_prev = (var), \ 1817 __list_next = (var) ? (var)->field.next : NULL; \ 1819 __list_prev = __new_prev, (var) = __list_next, \ 1820 __new_prev = (var), \ 1821 __list_next = (var) ? (var)->field.next : NULL \ 1824 #define AST_RWLIST_TRAVERSE_SAFE_BEGIN AST_LIST_TRAVERSE_SAFE_BEGIN 1837 #define AST_LIST_REMOVE_CURRENT(head, field) \ 1838 __new_prev->field.next = NULL; \ 1839 __new_prev = __list_prev; \ 1841 __list_prev->field.next = __list_next; \ 1843 (head)->first = __list_next; \ 1845 (head)->last = __list_prev; 1847 #define AST_RWLIST_REMOVE_CURRENT AST_LIST_REMOVE_CURRENT 1859 #define AST_LIST_INSERT_BEFORE_CURRENT(head, elm, field) do { \ 1860 if (__list_prev) { \ 1861 (elm)->field.next = __list_prev->field.next; \ 1862 __list_prev->field.next = elm; \ 1864 (elm)->field.next = (head)->first; \ 1865 (head)->first = (elm); \ 1867 __new_prev = (elm); \ 1870 #define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT 1875 #define AST_LIST_TRAVERSE_SAFE_END } 1877 #define AST_RWLIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END 1886 #define AST_LIST_HEAD_INIT(head) { \ 1887 (head)->first = NULL; \ 1888 (head)->last = NULL; \ 1889 ast_mutex_init(&(head)->lock); \ 1899 #define AST_RWLIST_HEAD_INIT(head) { \ 1900 (head)->first = NULL; \ 1901 (head)->last = NULL; \ 1902 ast_rwlock_init(&(head)->lock); \ 1913 #define AST_RWLIST_HEAD_DESTROY(head) { \ 1914 (head)->first = NULL; \ 1915 (head)->last = NULL; \ 1916 ast_rwlock_destroy(&(head)->lock); \ 1927 #define AST_LIST_HEAD_INIT_NOLOCK(head) { \ 1928 (head)->first = NULL; \ 1929 (head)->last = NULL; \ 1941 #define AST_LIST_INSERT_AFTER(head, listelm, elm, field) do { \ 1942 (elm)->field.next = (listelm)->field.next; \ 1943 (listelm)->field.next = (elm); \ 1944 if ((head)->last == (listelm)) \ 1945 (head)->last = (elm); \ 1948 #define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER 1957 #define AST_LIST_INSERT_HEAD(head, elm, field) do { \ 1958 (elm)->field.next = (head)->first; \ 1959 (head)->first = (elm); \ 1960 if (!(head)->last) \ 1961 (head)->last = (elm); \ 1964 #define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD 1977 #define AST_LIST_INSERT_TAIL(head, elm, field) do { \ 1978 if (!(head)->first) { \ 1979 (head)->first = (elm); \ 1980 (head)->last = (elm); \ 1982 (head)->last->field.next = (elm); \ 1983 (head)->last = (elm); \ 1987 #define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL 1996 #define AST_LIST_APPEND_LIST(head, list, field) do { \ 1997 if (!(head)->first) { \ 1998 (head)->first = (list)->first; \ 1999 (head)->last = (list)->last; \ 2001 (head)->last->field.next = (list)->first; \ 2002 (head)->last = (list)->last; \ 2006 #define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST 2017 #define AST_LIST_REMOVE_HEAD(head, field) ({ \ 2018 typeof((head)->first) cur = (head)->first; \ 2020 (head)->first = cur->field.next; \ 2021 cur->field.next = NULL; \ 2022 if ((head)->last == cur) \ 2023 (head)->last = NULL; \ 2028 #define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD 2038 #define AST_LIST_REMOVE(head, elm, field) do { \ 2039 if ((head)->first == (elm)) { \ 2040 (head)->first = (elm)->field.next; \ 2041 if ((head)->last == (elm)) \ 2042 (head)->last = NULL; \ 2044 typeof(elm) curelm = (head)->first; \ 2045 while (curelm && (curelm->field.next != (elm))) \ 2046 curelm = curelm->field.next; \ 2048 curelm->field.next = (elm)->field.next; \ 2049 if ((head)->last == (elm)) \ 2050 (head)->last = curelm; \ 2053 (elm)->field.next = NULL; \ 2056 #define AST_RWLIST_REMOVE AST_LIST_REMOVE 2079 #define AST_MAX_EXTENSION 80 2083 #define PRIORITY_HINT -1 2101 int (*read)(
struct ast_channel *,
const char *,
char *,
char *, size_t);
2102 int (*write)(
struct ast_channel *,
const char *,
char *,
const char *);
2112 const char *description;
2142 for (x=0; n[
x]; x++) {
2161 if (!strchr(
"()", n[x]))
2178 if (name[0] ==
'_') {
2195 static void ast_log(
int level,
const char *file,
int line,
const char *
function,
const char *fmt, ...)
2200 printf(
"LOG: lev:%d file:%s line:%d func: %s ",
2201 level, file, line,
function);
2212 printf(
"VERBOSE: ");
2221 char *dataPut = start;
2225 for (; *start; start++) {
2227 *dataPut++ = *start;
2230 if (*start ==
'\\') {
2232 }
else if (*start ==
'\'') {
2233 inQuotes = 1 - inQuotes;
2236 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
2240 if (start != dataPut)
2251 if (!strcasecmp(s,
"yes") ||
2252 !strcasecmp(s,
"true") ||
2253 !strcasecmp(s,
"y") ||
2254 !strcasecmp(s,
"t") ||
2255 !strcasecmp(s,
"1") ||
2256 !strcasecmp(s,
"on"))
2262 #define ONE_MILLION 1000000 2267 static struct timeval
tvfix(struct timeval
a)
2271 (
long)
a.tv_sec, (
long int)
a.tv_usec);
2274 }
else if (
a.tv_usec < 0) {
2276 (
long)
a.tv_sec, (
long int)
a.tv_usec);
2282 struct timeval ast_tvadd(struct timeval a, struct timeval b);
2283 struct timeval ast_tvadd(struct timeval a, struct timeval b)
2288 a.tv_sec += b.tv_sec;
2289 a.tv_usec += b.tv_usec;
2297 struct timeval ast_tvsub(struct timeval a, struct timeval b);
2298 struct timeval ast_tvsub(struct timeval a, struct timeval b)
2303 a.tv_sec -= b.tv_sec;
2304 a.tv_usec -= b.tv_usec;
2305 if (a.tv_usec < 0) {
2320 #define VAR_BUF_SIZE 4096 2322 #define VAR_NORMAL 1 2323 #define VAR_SOFTTRAN 2 2324 #define VAR_HARDTRAN 3 2326 #define BACKGROUND_SKIP (1 << 0) 2327 #define BACKGROUND_NOANSWER (1 << 1) 2328 #define BACKGROUND_MATCHEXTEN (1 << 2) 2329 #define BACKGROUND_PLAYBACK (1 << 3) 2340 const char *cidmatch;
2347 void (*datad)(
void *);
2357 unsigned int monthmask;
2358 unsigned int daymask;
2359 unsigned int dowmask;
2360 unsigned int minmask[48];
2402 ast_mutex_t macrolock;
2411 const char *description;
2450 #define STATUS_NO_CONTEXT 1 2451 #define STATUS_NO_EXTENSION 2 2452 #define STATUS_NO_PRIORITY 3 2453 #define STATUS_NO_LABEL 4 2454 #define STATUS_SUCCESS 5 2459 int name_len = strlen(name) + 1;
2460 int value_len = strlen(value) + 1;
2462 if (!(var =
ast_calloc(
sizeof(*var) + name_len + value_len,
sizeof(
char)))) {
2494 if (!buf || !array || !arraylen)
2497 memset(array, 0, arraylen *
sizeof(*array));
2501 for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
2503 for (; *scan; scan++) {
2506 else if (*scan ==
')') {
2509 }
else if (*scan ==
'"' && delim !=
'"') {
2512 memmove(scan, scan + 1, strlen(scan));
2514 }
else if (*scan ==
'\\') {
2516 memmove(scan, scan + 1, strlen(scan));
2517 }
else if ((*scan == delim) && !paren && !
quote) {
2525 array[argc++] = scan;
2534 const char *nametail =
name;
2537 if (name[strlen(name)-1] ==
')') {
2547 if (*nametail ==
'_') {
2549 if (*nametail ==
'_')
2554 if (strcasecmp(
ast_var_name(newvariable), nametail) == 0) {
2563 if ((option_verbose > 1) && (headp == &globals))
2587 if ((argc > 1) && !strchr(argv[argc-1],
'=')) {
2589 if (strchr(argv[argc],
'g'))
2593 for (x = 0; x < argc; x++) {
2595 if ((value = strchr(name,
'='))) {
2599 ast_log(
LOG_WARNING,
"Ignoring entry '%s' with no = (and not last 'options' entry)\n", name);
2621 if (names && *s >
'9') {
2622 for (i = 0; names[i]; i++) {
2623 if (!strcasecmp(s, names[i])) {
2630 if (sscanf(s,
"%2d", &i) == 1 && i >= 1 && i <= max) {
2640 static unsigned get_range(
char *src,
int max,
char *
const names[],
const char *msg)
2643 unsigned int mask = 0;
2648 return (1 << max) - 1;
2651 while ((part =
strsep(&src,
"&"))) {
2653 char *endpart = strchr(part,
'-');
2658 if ((start =
lookup_name(part, names, max)) < 0) {
2663 if ((end =
lookup_name(endpart, names, max)) < 0) {
2672 while (start != end) {
2676 mask |= (1 << start);
2686 char *endpart, *part;
2690 int minute_start, minute_end;
2699 for (x = 0; x < 48; x++) {
2705 while ((part =
strsep(×,
"&"))) {
2706 if (!(endpart = strchr(part,
'-'))) {
2707 if (sscanf(part,
"%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
2711 i->
minmask[st_h * 2 + (st_m >= 30 ? 1 : 0)] |= (1 << (st_m % 30));
2716 while (*endpart && !isdigit(*endpart)) {
2723 if (sscanf(part,
"%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
2727 if (sscanf(endpart,
"%2d:%2d", &endh, &endm) != 2 || endh < 0 || endh > 23 || endm < 0 || endm > 59) {
2731 minute_start = st_h * 60 + st_m;
2732 minute_end = endh * 60 + endm;
2734 for (x = minute_start; x != minute_end; x = (x + 1) % (24 * 60)) {
2735 i->
minmask[x / 30] |= (1 << (x % 30));
2738 i->
minmask[x / 30] |= (1 << (x % 30));
2756 if (!strcasecmp(family, map->
name)) {
2767 for (eng = config_engine_list; !ret && eng; eng = eng->
next) {
2768 if (!strcasecmp(eng->name, map->
driver))
2794 if ((category =
ast_calloc(1,
sizeof(*category))))
2829 for (var = base->
root; var; var = var->
next)
2840 config->
root = category;
2841 config->
last = category;
2881 if (strcmp(filename, extconfig_conf) && strcmp(filename,
"asterisk.conf") && config_engine_list) {
2884 eng =
find_engine(filename, db,
sizeof(db), table,
sizeof(table));
2890 eng =
find_engine(
"global", db,
sizeof(db), table,
sizeof(table));
2896 result = loader->
load_func(db, table, filename, cfg, withcomments, suggested_incl_file);
2913 char exec_file[512];
2914 int object, do_exec, do_include;
2917 if (cur[0] ==
'[') {
2922 c = strchr(cur,
']');
2924 ast_log(
LOG_WARNING,
"parse error: no closing ']', line %d of %s\n", lineno, configfile);
2938 if (withcomments && comment_buffer && comment_buffer[0] ) {
2941 if (withcomments && lline_buffer && lline_buffer[0] ) {
2949 if (!(cur = strchr(c,
')'))) {
2950 ast_log(
LOG_WARNING,
"parse error: no closing ')', line %d of %s\n", lineno, configfile);
2954 while ((cur =
strsep(&c,
","))) {
2955 if (!strcasecmp(cur,
"!")) {
2956 (*cat)->ignored = 1;
2957 }
else if (!strcasecmp(cur,
"+")) {
2963 ast_log(
LOG_WARNING,
"Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
2976 ast_log(
LOG_WARNING,
"Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
2985 }
else if (cur[0] ==
'#') {
2989 while(*c && (*c > 32)) c++;
2998 do_include = !strcasecmp(cur,
"include");
3000 do_exec = !strcasecmp(cur,
"exec");
3004 ast_log(
LOG_WARNING,
"Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
3007 if (do_include || do_exec) {
3010 char real_inclusion_name[525];
3013 while((*c ==
'<') || (*c ==
'>') || (*c ==
'\"')) c++;
3018 c = cur + strlen(cur) - 1;
3019 if ((*c ==
'>') || (*c ==
'<') || (*c ==
'\"'))
3029 snprintf(exec_file,
sizeof(exec_file),
"/var/tmp/exec.%d.%ld", (
int)time(
NULL), (
long)pthread_self());
3030 if (snprintf(cmd,
sizeof(cmd),
"%s > %s 2>&1", cur, exec_file) >=
sizeof(cmd)) {
3031 ast_log(
LOG_ERROR,
"Failed to construct command string to execute %s.\n", cur);
3038 exec_file[0] =
'\0';
3043 ast_include_new(cfg, configfile, cur, do_exec, cur2, lineno, real_inclusion_name,
sizeof(real_inclusion_name));
3054 do_exec ?
"exec" :
"include",
3055 do_exec ?
"/path/to/executable" :
"filename",
3061 ast_log(
LOG_WARNING,
"Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile);
3066 "parse error: No category context for line %d of %s\n", lineno, configfile);
3069 c = strchr(cur,
'=');
3086 if (withcomments && comment_buffer && comment_buffer[0] ) {
3089 if (withcomments && lline_buffer && lline_buffer[0] ) {
3099 ast_log(
LOG_WARNING,
"EXTENSIONS.CONF: No '=' (equal sign) in line %d of %s\n", lineno, configfile);
3125 char *new_buf, *comment_p, *process_buf;
3131 struct stat statbuf;
3135 if (filename[0] ==
'/') {
3139 snprintf(fn,
sizeof(fn),
"./%s", filename);
3149 if (stat(fn, &statbuf))
3152 if (!S_ISREG(statbuf.st_mode)) {
3156 if (option_verbose > 1) {
3160 if (!(f = fopen(fn,
"r"))) {
3163 if (option_verbose > 1)
3170 if (option_verbose > 1)
3174 if (fgets(buf,
sizeof(buf), f)) {
3175 if ( withcomments ) {
3177 lline_buffer[0] = 0;
3187 if ((comment_p > new_buf) && (*(comment_p-1) ==
'\\')) {
3189 memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
3190 new_buf = comment_p;
3195 new_buf = comment_p + 3;
3197 nest[comment-1] = lineno;
3201 }
else if ((comment_p >= new_buf + 2) &&
3206 new_buf = comment_p + 1;
3212 oldptr = process_buf + strlen(process_buf);
3213 if ( withcomments ) {
3218 memmove(oldptr, new_buf, strlen(new_buf) + 1);
3221 process_buf = new_buf;
3227 if ( withcomments ) {
3231 new_buf = comment_p;
3233 new_buf = comment_p + 1;
3236 if( withcomments && comment && !process_buf )
3242 char *stripped_process_buf =
ast_strip(process_buf);
3244 if (
process_text_line(cfg, &cat, stripped_process_buf, lineno, filename, withcomments, suggested_include_file)) {
3255 ast_log(
LOG_WARNING,
"Unterminated comment detected beginning on line %d\n", nest[comment]);
3257 if (cfg && cfg->
include_level == 1 && withcomments && comment_buffer) {
3258 if (comment_buffer) {
3259 free(comment_buffer);
3263 comment_buffer_size=0;
3264 lline_buffer_size=0;
3280 if ((config =
ast_calloc(1,
sizeof(*config))))
3334 else if (!prev && config->
root)
3337 for (cat = config->
root; cat; cat = cat->
next) {
3338 if (cat->
name == prev) {
3344 for (cat = config->
root; cat; cat = cat->
next) {
3345 if (!strcasecmp(cat->
name, prev)) {
3397 fprintf(f1,
";!\n");
3398 fprintf(f1,
";! Automatically generated configuration file\n");
3399 if (strcmp(configfile, fn))
3400 fprintf(f1,
";! Filename: %s (%s)\n", configfile, fn);
3402 fprintf(f1,
";! Filename: %s\n", configfile);
3403 fprintf(f1,
";! Generator: %s\n", generator);
3404 fprintf(f1,
";! Creation Date: %s", date);
3405 fprintf(f1,
";!\n");
3408 static void set_fn(
char *fn,
int fn_size,
const char *file,
const char *configfile)
3410 if (!file || file[0] == 0) {
3411 if (configfile[0] ==
'/')
3415 }
else if (file[0] ==
'/')
3457 set_fn(fn,
sizeof(fn), 0, configfile);
3459 if ((f = fopen(fn,
"w+"))) {
3461 if ((f = fopen(fn,
"w"))) {
3463 if (option_verbose > 1)
3475 set_fn(fn,
sizeof(fn), cat->
file, configfile);
3488 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
3498 if (cmt->
cmt[0] !=
';' || cmt->
cmt[1] !=
'!')
3499 fprintf(f,
"%s", cmt->
cmt);
3503 fprintf(f,
"[%s]", cat->
name);
3505 fprintf(f,
"%s", cmt->
cmt);
3513 set_fn(fn,
sizeof(fn), var->
file, configfile);
3526 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
3535 if (cmt->
cmt[0] !=
';' || cmt->
cmt[1] !=
'!')
3536 fprintf(f,
"%s", cmt->
cmt);
3541 fprintf(f,
"%s %s %s\n", var->
name, (var->
object ?
"=>" :
"="), var->
value);
3544 while (blanklines--)
3555 if ((option_verbose > 1) && !option_debug)
3560 if (option_verbose > 1)
3581 fprintf(f,
"#exec \"%s\"\n", incl->
exec_file);
3603 #define EXT_DATA_SIZE 256 3605 #define EXT_DATA_SIZE 8192 3612 #define SWITCH_DATA_LENGTH 256 3633 if (hint->
exten == oe) {
3654 if (hint->
exten == e) {
3655 if (option_debug > 1)
3661 if (option_debug > 1)
3664 if (!(hint =
ast_calloc(1,
sizeof(*hint)))) {
3682 for (ep =
NULL; e ; ep = e, e = e->
peer) {
3690 if (e->priority == tmp->
priority) {
3746 if (hint->
exten == e) {
3752 cblist = cblist->
next;
3811 int j, num_fields, last_sep = -1;
3824 for (j = 0, num_fields = 1; info[j] !=
'\0'; j++) {
3825 if (info[j] ==
',') {
3832 if (num_fields == 5) {
3877 int c, cmin = 0xff, count = 0;
3883 while ( (c = *(*p)++) && (c ==
' ' || c ==
'-') )
3889 return 0x0000 | (c & 0xff);
3892 return 0x0700 |
'2' ;
3895 return 0x0900 |
'0';
3898 return 0x0800 |
'1';
3914 end = strchr(*p,
']');
3921 memset(chars,
'\0',
sizeof(chars));
3922 for (; *p <
end ; (*p)++) {
3923 unsigned char c1, c2;
3924 c1 = (
unsigned char)((*p)[0]);
3925 if (*p + 2 < end && (*p)[1] ==
'-') {
3926 c2 = (
unsigned char)((*p)[2]);
3932 for (; c1 <= c2; c1++) {
3933 uint32_t mask = 1 << (c1 % 32);
3934 if ( (chars[ c1 / 32 ] & mask) == 0)
3936 chars[ c1 / 32 ] |= mask;
3940 return count == 0 ? 0x30000 : (count | cmin);
3955 return (b[0] ==
'_') ? -1 : strcmp(a, b);
3961 return strcmp(a, b);
3964 while (!ret && a && b)
3969 return (ret > 0) ? 1 : -1;
3977 while (*src && (count < len - 1)) {
4015 if (!strcasecmp(asw->
name, sw))
4066 return priority ? priority->
peer :
exten;
4178 if (!name || !strcasecmp(name, tmp->
name))
4197 if ( (mode ==
E_MATCH) && (pattern[0] ==
'_') && (strcasecmp(pattern,data)==0) )
4200 if (pattern[0] !=
'_') {
4201 int ld = strlen(data), lp = strlen(pattern);
4207 return !strcmp(pattern, data);
4208 if (ld == 0 || !strncasecmp(pattern, data, ld))
4218 while (*data && *pattern && *pattern !=
'/') {
4225 switch (toupper(*pattern)) {
4227 end = strchr(pattern+1,
']');
4232 for (pattern++; pattern !=
end; pattern++) {
4233 if (pattern+2 < end && pattern[1] ==
'-') {
4234 if (*data >= pattern[0] && *data <= pattern[2])
4240 }
else if (*data == pattern[0])
4248 if (*data < '2' || *data >
'9')
4252 if (*data < '0' || *data >
'9')
4256 if (*data < '1' || *data >
'9')
4268 if (*data != *pattern)
4280 if (*pattern ==
'\0' || *pattern ==
'/')
4282 else if (*pattern ==
'!')
4285 return (mode ==
E_MATCH) ? 0 : 1;
4302 static int matchcid(
const char *cidpattern,
const char *callerid)
4326 const char *context,
4330 const char *callerid,
4337 const char *context,
4341 const char *callerid,
4364 for (x = 0; x < q->
stacklen; x++) {
4365 if (!strcasecmp(q->
incstack[x], context))
4373 if (!strcmp(tmp->
name, context))
4405 if (label && e->
label && !strcmp(label, e->
label))
4407 }
else if (e->
priority == priority) {
4417 #ifdef NOT_RIGHT_NOW 4438 res = !aswf ? 0 : aswf(chan, context, exten, priority, callerid, datap);
4463 const char *context,
4467 const char *callerid,
4472 const char *context,
4476 const char *callerid,
4504 const char *registrar)
4513 length += 2 * (strlen(value) + 1);
4521 p = new_include->
stuff;
4522 new_include->
name = p;
4524 p += strlen(value) + 1;
4525 new_include->
rname = p;
4528 if ( (c = strchr(p,
'|')) ) {
4538 if (!strcasecmp(i->
name, new_include->
name)) {
4548 il->
next = new_include;
4551 if (option_verbose > 2)
4558 const char *registrar);
4560 const char *registrar)
4574 length += strlen(value) + 1;
4580 strcpy((
char *)ignorepat->
pattern, value);
4583 for (ignorepatc = con->
ignorepats; ignorepatc; ignorepatc = ignorepatc->
next) {
4584 ignorepatl = ignorepatc;
4585 if (!strcasecmp(ignorepatc->
pattern, value)) {
4592 ignorepatl->
next = ignorepat;
4639 const char *data,
int eval,
const char *registrar);
4642 const char *data,
int eval,
const char *registrar)
4649 length =
sizeof(
struct ast_sw);
4650 length += strlen(value) + 1;
4652 length += strlen(data);
4666 strcpy(new_sw->
name, value);
4667 p += strlen(value) + 1;
4670 strcpy(new_sw->
data, data);
4671 p += strlen(data) + 1;
4673 strcpy(new_sw->
data,
"");
4683 if (!strcasecmp(i->
name, new_sw->
name) && !strcasecmp(i->
data, new_sw->
data)) {
4693 if (option_verbose > 2)
4700 const char *data,
int eval,
const char *registrar);
4703 const char *data,
int eval,
const char *registrar)
4711 int length =
sizeof(
struct ast_context) + strlen(name) + 1;
4717 loc_contexts = extcontexts;
4719 for (tmp = *loc_contexts;
tmp; tmp = tmp->
next) {
4720 if (!strcasecmp(tmp->
name, name)) {
4733 strcpy(tmp->
name, name);
4736 tmp->
next = *loc_contexts;
4739 *loc_contexts =
tmp;
4742 if (option_verbose > 2)
4777 int replace,
const char *
extension,
int priority,
const char *label,
const char *callerid,
4778 const char *application,
void *data,
void (*datad)(
void *),
4779 const char *registrar)
4797 length += strlen(extension) + 1;
4798 length += strlen(application) + 1;
4800 length += strlen(label) + 1;
4802 length += strlen(callerid) + 1;
4817 p += strlen(label) + 1;
4820 p +=
ext_strncpy(p, extension, strlen(extension) + 1) + 1;
4824 p +=
ext_strncpy(p, callerid, strlen(callerid) + 1) + 1;
4831 strcpy(p, application);
4838 for (e = con->
root; e; el = e, e = e->
next) {
4853 if (e && res == 0) {
4854 res =
add_pri(con, tmp, el, e, replace);
4874 ast_log(
LOG_DEBUG,
"Added extension '%s' priority %d (CID match '%s') to %s\n",
4881 if (option_verbose > 2) {
4894 int replace,
const char *extension,
int priority,
const char *label,
const char *callerid,
4895 const char *application,
void *data,
void (*
datad)(
void *),
4896 const char *registrar);
4899 int replace,
const char *extension,
int priority,
const char *label,
const char *callerid,
4900 const char *application,
void *data,
void (*
datad)(
void *),
4901 const char *registrar)
4903 return ast_add_extension2(con, replace, extension, priority, label, callerid, application, data,
datad, registrar);
4918 const char *context,
const char *exten,
int priority,
4919 const char *label,
const char *callerid,
enum ext_match_t action)
4929 if (matching_action) {
4940 if (matching_action)
4952 if (!matching_action)
4956 if (!matching_action)
4957 ast_log(
LOG_NOTICE,
"Cannot find extension '%s' in context '%s'\n", exten, context);
4960 if (!matching_action)
4961 ast_log(
LOG_NOTICE,
"No such priority %d in extension '%s' in context '%s'\n", priority, exten, context);
4965 ast_log(
LOG_NOTICE,
"No such label '%s' in extension '%s' in context '%s'\n", label, exten, context);
4972 return (matching_action) ? 0 : -1;
5013 for (; *
var; var++) {
5017 }
else if (*var ==
')') {
5019 }
else if (*var ==
':' && parens == 0) {
5021 sscanf(var,
"%30d:%30d", offset, length);
5041 static char *
substring(
const char *value,
int offset,
int length,
char *workspace,
size_t workspace_len)
5043 char *ret = workspace;
5051 if (offset == 0 && length >= lr)
5055 offset = lr + offset;
5065 if (length >= 0 && length < lr - offset)
5067 else if (length < 0) {
5068 if (lr > offset - length)
5069 ret[lr + length - offset] =
'\0';
5084 const char not_found =
'\0';
5088 int i, need_substring;
5089 struct varshead *places[2] = { headp, &globals };
5115 if (s == ¬_found) {
5116 if (!strcmp(var,
"EPOCH")) {
5117 snprintf(workspace, workspacelen,
"%u",(
int)time(
NULL));
5123 for (i = 0; s == ¬_found && i < (
sizeof(places) /
sizeof(places[0])); i++) {
5127 if (places[i] == &globals)
5135 if (places[i] == &globals)
5138 if (s == ¬_found || s ==
NULL)
5145 *ret =
substring(*ret, offset, length, workspace, workspacelen);
5154 const char *
tmp, *whereweare;
5155 int length, offset, offset2, isfunction;
5156 char *workspace =
NULL;
5158 char *nextvar, *nextexp, *nextthing;
5160 int pos, brackets, needsub,
len;
5166 pos = strlen(whereweare);
5169 nextthing = strchr(whereweare,
'$');
5171 switch (nextthing[1]) {
5173 nextvar = nextthing;
5174 pos = nextvar - whereweare;
5177 nextexp = nextthing;
5178 pos = nextexp - whereweare;
5189 memcpy(cp2, whereweare, pos);
5201 vars = vare = nextvar + 2;
5206 while (brackets && *vare) {
5207 if ((vare[0] ==
'$') && (vare[1] ==
'{')) {
5209 }
else if (vare[0] ==
'{') {
5211 }
else if (vare[0] ==
'}') {
5213 }
else if ((vare[0] ==
'$') && (vare[1] ==
'['))
5219 len = vare - vars - 1;
5222 whereweare += (len + 3);
5245 workspace[0] =
'\0';
5260 length = strlen(cp4);
5263 memcpy(cp2, cp4, length);
5268 }
else if (nextexp) {
5272 vars = vare = nextexp + 2;
5277 while (brackets && *vare) {
5278 if ((vare[0] ==
'$') && (vare[1] ==
'[')) {
5282 }
else if (vare[0] ==
'[') {
5284 }
else if (vare[0] ==
']') {
5286 }
else if ((vare[0] ==
'$') && (vare[1] ==
'{')) {
5294 len = vare - vars - 1;
5297 whereweare += (len + 3);
5344 char realvalue[256];
5359 autofallthrough_config =
ast_true(aft);
5368 memset(realvalue, 0,
sizeof(realvalue));
5374 if (!strcasecmp(cxt,
"general") || !strcasecmp(cxt,
"globals"))
5381 if (!strcasecmp(v->
name,
"exten")) {
5385 char realext[256]=
"";
5386 char *plus, *firstp, *firstc;
5387 char *pri, *
appl, *
data, *cidmatch;
5393 cidmatch = strchr(realext,
'/');
5398 pri =
strsep(&stringp,
",");
5401 label = strchr(pri,
'(');
5404 end = strchr(label,
')');
5410 plus = strchr(pri,
'+');
5413 if (!strcmp(pri,
"hint"))
5415 else if (!strcmp(pri,
"next") || !strcmp(pri,
"n")) {
5420 }
else if (!strcmp(pri,
"same") || !strcmp(pri,
"s")) {
5425 }
else if (sscanf(pri,
"%30d", &ipri) != 1 &&
5430 appl =
S_OR(stringp,
"");
5432 firstc = strchr(appl,
',');
5433 firstp = strchr(appl,
'(');
5434 if (firstc && (!firstp || firstc < firstp)) {
5437 appl =
strsep(&stringp,
",");
5439 }
else if (!firstc && !firstp) {
5444 appl =
strsep(&stringp,
"(");
5446 end = strrchr(data,
')');
5447 if ((end = strrchr(data,
')'))) {
5463 ast_log(
LOG_WARNING,
"The use of '_.' for an extension is strongly discouraged and can have unexpected behavior. Please use '_X.' instead at line %d\n", v->
lineno);
5470 }
else if (!strcasecmp(v->
name,
"include")) {
5471 memset(realvalue, 0,
sizeof(realvalue));
5475 }
else if (!strcasecmp(v->
name,
"ignorepat")) {
5476 memset(realvalue, 0,
sizeof(realvalue));
5480 }
else if (!strcasecmp(v->
name,
"switch") || !strcasecmp(v->
name,
"lswitch") || !strcasecmp(v->
name,
"eswitch")) {
5481 char *stringp= realvalue;
5484 memset(realvalue, 0,
sizeof(realvalue));
5485 if (!strcasecmp(v->
name,
"switch"))
5489 appl =
strsep(&stringp,
"/");
5490 data =
strsep(&stringp,
"");
5512 for (tmp = contexts;
tmp; ) {
5517 if ( (!registrar || !strcasecmp(registrar, tmp->registrar)) &&
5518 (!con || !strcasecmp(tmp->name, con->
name)) )
5534 for (tmpi = tmp->includes; tmpi; ) {
5539 for (ipi = tmp->ignorepats; ipi; ) {
5546 for (e = tmp->root; e;) {
5547 for (en = e->
peer; en;) {
5608 contexts = *extcontexts;
5609 *extcontexts =
NULL;
5631 if (strcasecmp(inc->
rname,
"parkedcalls")!=0)
5661 printf(
"=== Loading extensions.conf ===\n");
5664 printf(
"Context: %s\n", con->
name);
5666 printf(
"=========\n");
5672 struct timeval ast_tvnow(void);
5674 struct timeval ast_tvnow(void)
5677 gettimeofday(&t,
NULL);
static void gen_header(FILE *f1, const char *configfile, const char *fn, const char *generator)
struct ast_state_cb * next
ast_include: include= support in extensions.conf
static struct ast_exten * ast_walk_extension_priorities(struct ast_exten *exten, struct ast_exten *priority)
static const char synopsis[]
struct ast_variable * next
struct ast_category * next
struct ast_comment * sameline
enum sip_cc_notify_state state
static int process_text_line(struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, int withcomments, const char *suggested_include_file)
static struct ast_variable * variable_clone(const struct ast_variable *old)
#define ast_channel_lock(chan)
int64_t ast_mark(int, int start1_stop0)
static char exten[AST_MAX_EXTENSION]
static void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
Support for Asterisk built-in variables in the dialplan.
Main Channel structure associated with a channel.
struct ast_ignorepats ignorepats
static int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
static void ast_config_destroy(struct ast_config *cfg)
static int ast_rwlock_rdlock(ast_rwlock_t *prwlock)
ast_extension_states
Extension states.
Asterisk main include file. File version handling, generic pbx functions.
struct ast_config_map * next
ast_exten: An extension The dialplan is saved as a linked list with each context having it's own link...
struct ast_sw * localized_walk_context_switches(struct ast_context *con, struct ast_sw *sw)
static const char config_file[]
#define ast_realloc(p, len)
A wrapper for realloc()
#define MAX_INCLUDE_LEVEL
static SQLHSTMT execute(struct odbc_obj *obj, void *data, int silent)
Common execution function for SQL queries.
#define STATUS_NO_EXTENSION
void ast_unreplace_sigchld(void)
Restore the SIGCHLD handler.
char * file
The file name from whence this declaration was read.
static void CB_ADD_LEN(char *str, int len)
static struct ast_include * ast_walk_context_includes(struct ast_context *con, struct ast_include *inc)
static char * substring(const char *value, int offset, int length, char *workspace, size_t workspace_len)
takes a substring. It is ok to call with value == workspace.
static struct varshead globals
static struct timeval tvfix(struct timeval a)
static struct aco_type global
struct ast_include * localized_walk_context_includes(struct ast_context *con, struct ast_include *inc)
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
static struct ast_context * __ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar, int existsokay)
int __ast_pthread_mutex_destroy(const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t)
struct ast_context * localized_walk_contexts(struct ast_context *con)
static int lookup_name(const char *s, char *const names[], int max)
Helper for get_range. return the index of the matching entry, starting from 1. If names is not suppli...
static struct ast_ignorepat * ast_walk_context_ignorepats(struct ast_context *con, struct ast_ignorepat *ip)
static void CB_RESET(void)
static int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
static int exists(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
char * include_location_file
file name in which the include occurs
static void set_fn(char *fn, int fn_size, const char *file, const char *configfile)
Time-related functions and macros.
int localized_context_add_switch2(struct ast_context *con, const char *value, const char *data, int eval, const char *registrar)
static struct ast_context * contexts
static struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
static void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
struct ast_exten * localized_find_extension(struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
struct ast_config_include * includes
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
int ast_build_timing(struct ast_timing *i, const char *info_in)
Construct a timing bitmap, for use in time-based conditionals.
struct ast_category * localized_category_get(const struct ast_config *config, const char *category_name)
static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
The return value depends on the action:
int localized_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
void localized_context_destroy(struct ast_context *con, const char *registrar)
ast_state_cb: An extension state notify register item
Generic (perhaps overly so) hashtable implementation Hash Table support in Asterisk.
void ast_copy_string(char *dst, const char *src, size_t size)
Structure for variables, used for configurations and for channel variables.
struct ast_generator * generator
struct ast_comment * sameline
void ast_replace_sigchld(void)
Replace the SIGCHLD handler.
static unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
static int ast_remove_hint(struct ast_exten *e)
ast_remove_hint: Remove hint from extension
static struct ast_category * next_available_category(struct ast_category *cat)
static int ast_unlock_context(struct ast_context *con)
struct ast_ignorepat * next
static int comment_buffer_size
static int clearglobalvars_config
static char * global_registrar
struct ast_category * prev
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
pthread_rwlock_t ast_rwlock_t
#define AST_RWLIST_TRAVERSE_SAFE_END
static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
static struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
static int ext_cmp1(const char **p)
helper functions to sort extensions and patterns in the desired way, so that more specific patterns a...
static int _extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
double ast_option_maxload
static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count)
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
void ast_verbose(const char *fmt,...)
#define ast_strdup(str)
A wrapper for strdup()
#define pthread_mutex_init
struct ast_include * next
int __ast_pthread_mutex_init(int tracking, const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t)
static const char * ast_get_extension_app(struct ast_exten *e)
char * incstack[AST_PBX_MAX_STACK]
void localized_ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
static int ast_rwlock_init(ast_rwlock_t *prwlock)
#define SWITCH_DATA_LENGTH
#define log_mutex_error(canlog,...)
static int lline_buffer_size
static struct ast_context * ast_walk_contexts(struct ast_context *con)
static unsigned get_range(char *src, int max, char *const names[], const char *msg)
helper function to return a range up to max (7, 12, 31 respectively). names, if supplied, is an array of names that should be mapped to numbers.
char * exec_file
if it's an exec, you'll have both the /var/tmp to read, and the original script
static struct ast_config_map * config_maps
void ast_free_ptr(void *ptr)
free() wrapper
int localized_config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator)
static ast_rwlock_t conlock
char ast_defaultlanguage[]
int localized_context_verify_includes(struct ast_context *con)
static char * ast_category_browse(struct ast_config *config, const char *prev)
static void ast_shrink_phone_number(char *n)
Clean up phone string remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets...
static const char * ast_get_context_name(struct ast_context *con)
#define MAX_NESTED_COMMENTS
char * ast_skip_blanks(const char *str)
Configuration engine structure, used to define realtime drivers.
static const char * ast_get_extension_name(struct ast_exten *exten)
struct ast_config_engine * next
static struct ast_category * category_get(const struct ast_config *config, const char *category_name, int ignored)
static int ast_mutex_init(ast_mutex_t *pmutex)
static struct ast_comment * ALLOC_COMMENT(const char *buffer)
struct ast_context * next
static int add_pri(struct ast_context *con, struct ast_exten *tmp, struct ast_exten *el, struct ast_exten *e, int replace)
add the extension in the priority chain. returns 0 on success, -1 on failure
int ast_check_timing(const struct ast_timing *i)
Evaluate a pre-constructed bitmap as to whether the current time falls within the range specified...
struct ast_category * last
All configuration options for statsd client.
struct ast_category * current
static void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
static int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
static char * lline_buffer
static int include_valid(struct ast_include *i)
struct ast_exten * localized_walk_context_extensions(struct ast_context *con, struct ast_exten *exten)
int localized_pbx_load_module(void)
#define pthread_mutex_destroy
static struct ast_config * ast_config_new(void)
void localized_merge_contexts_and_delete(struct ast_context **extcontexts, void *tab, const char *registrar)
struct ast_category * ast_config_get_current_category(const struct ast_config *cfg)
Retrieve the current category name being built.
static char * config_filename
ast_sw: Switch statement in extensions.conf
static void LLB_ADD(char *str)
static int ast_unlock_contexts(void)
#define pthread_mutex_lock
struct ast_config * realtime_multi_get(const char *database, const char *table, va_list ap)
Asterisk file paths, configured in asterisk.conf.
static int quote(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat)
Set the category within the configuration as being current.
int ast_context_includes_count(struct ast_context *con)
Inlinable API function macro.
struct sla_ringing_trunk * last
static struct ast_sw * ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw)
Data structure associated with a custom dialplan function.
Asterisk architecture endianess compatibility definitions.
static struct ast_config_engine text_file_engine
static struct sigaction null_sig_handler
static char * extconfig_conf
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
pthread_cond_t ast_cond_t
struct ast_switch * pbx_findswitch(const char *sw)
char * included_file
file name included
structure to hold extensions
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
static int ast_add_hint(struct ast_exten *e)
ast_add_hint: Add hint to hint list, check initial extension state
static void _null_sig_handler(int sig)
NULL handler so we can collect the child exit status.
static char * ast_process_quotes_and_slashes(char *start, char find, char replace_with)
static force_inline int ast_strlen_zero(const char *s)
#define ast_strdupa(s)
duplicate a string in memory from the stack
static void inherit_category(struct ast_category *new, const struct ast_category *base)
void localized_use_conf_dir(void)
static int matchcid(const char *cidpattern, const char *callerid)
static struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name)
static struct ast_context * local_contexts
static struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
#define ast_malloc(len)
A wrapper for malloc()
static void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
struct ast_includes includes
struct ast_variable * root
char stuff[0]
Contents of file, name, and value in that order stuffed here.
int ast_language_is_prefix
The following variable controls the layout of localized sound files. If 0, use the historical layout ...
static struct ast_config_engine * config_engine_list
static int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
static void null_datad(void *foo)
int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)
External configuration handlers (realtime and static configuration)
static void move_variables(struct ast_category *old, struct ast_category *new)
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
struct ast_comment * precomments
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)
static char * comment_buffer
struct ast_category * last_browse
static int autofallthrough_config
static void get_timerange(struct ast_timing *i, char *times)
store a bitmask of valid times, one bit each 2 minute
static int ast_rwlock_destroy(ast_rwlock_t *prwlock)
struct ast_exten * exten
Hint extension.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
int __ast_pthread_mutex_unlock(const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t)
static void ast_category_destroy(struct ast_category *cat)
#define STATUS_NO_PRIORITY
static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
#define AST_RWLIST_REMOVE_CURRENT
const char * ast_config_AST_CONFIG_DIR
static int array(struct ast_channel *chan, const char *cmd, char *var, const char *value)
static void ast_variables_destroy(struct ast_variable *v)
static int ast_rwlock_wrlock(ast_rwlock_t *prwlock)
ast_ignorepat: Ignore patterns in dial plan
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
int(* ast_state_cb_type)(char *context, char *id, enum ast_extension_states state, void *data)
static unsigned int safe_system_level
Keep track of how many threads are currently trying to wait*() on a child process.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Structure for dial plan hints.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
struct ast_comment * precomments
static const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
static int ast_context_verify_includes(struct ast_context *con)
static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
extract offset:length from variable name. Returns 1 if there is a offset:length part, which is trimmed off (values go into variables)
int localized_add_extension2(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
const ast_string_field name
#define AST_PBX_MAX_STACK
static void ast_category_append(struct ast_config *config, struct ast_category *category)
static void CB_INIT(void)
General Definitions for Asterisk top level program Included by asterisk.h to handle platform-specific...
struct ast_config * localized_config_load_with_comments(const char *filename)
struct ao2_container * callbacks
int ast_context_ignorepats_count(struct ast_context *con)
int include_location_lineno
static void ast_includes_destroy(struct ast_config_include *incls)
static const char * ast_var_name(const struct ast_var_t *var)
void ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt,...)
static struct ast_exten * ast_walk_context_extensions(struct ast_context *con, struct ast_exten *exten)
#define PTHREAD_MUTEX_INIT_VALUE
#define ast_channel_unlock(chan)
#define AST_RWLOCK_DEFINE_STATIC(rwlock)
#define ast_calloc(num, len)
A wrapper for calloc()
struct ast_var_t::@249 entries
Structures for AEL - the Asterisk extension language.
static struct ast_var_t * ast_var_assign(const char *name, const char *value)
const char * foundcontext
#define AST_CACHE_DIR_LEN
void ast_console_puts(const char *string)
write the string to the root console, and all attached network console clients
static struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, void *tab, const char *name, const char *registrar)
static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
ast_change_hint: Change hint for an extension
static char userscontext[AST_MAX_EXTENSION]
static struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
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)
#define AST_DEFAULT_OPTIONS
Structure used to handle boolean flags.
#define AST_MAX_REENTRANCY
struct ast_variable * realtime_var_get(const char *database, const char *table, va_list ap)
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
static int ast_context_add_include2(struct ast_context *con, const char *value, const char *registrar)
static int ast_wrlock_context(struct ast_context *con)
static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
static int ext_strncpy(char *dst, const char *src, int len)
copy a string skipping whitespace
char debug_filename[AST_FILENAME_MAX]
struct ast_flags ast_options
static int ext_cmp(const char *a, const char *b)
the full routine to compare extensions in rules.
char * strsep(char **str, const char *delims)
pthread_mutex_t ast_mutex_t
#define AST_MAX_EXTENSION
struct ast_variable * last
struct ast_context * localized_context_find_or_create(struct ast_context **extcontexts, void *tab, const char *name, const char *registrar)
static struct ast_config * ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_incl_file)
struct ast_config_include * next
char record_cache_dir[AST_CACHE_DIR_LEN]
static struct ast_config_engine * find_engine(const char *family, char *database, int dbsiz, char *table, int tabsiz)
Find realtime engine for realtime family.
static void CB_ADD(char *str)
ast_app: A registered application
int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t)
#define ast_opt_exec_includes
static void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
config_load_func * load_func
static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
int localized_context_add_include2(struct ast_context *con, const char *value, const char *registrar)
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
struct ast_exten * localized_walk_extension_priorities(struct ast_exten *exten, struct ast_exten *priority)
static void destroy_exten(struct ast_exten *e)
static void __ast_context_destroy(struct ast_context *con, const char *registrar)
static struct ast_context * ast_context_find(const char *name)
int ast_context_switches_count(struct ast_context *con)
int() ast_switch_f(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
static int pbx_builtin_setvar(struct ast_channel *chan, const void *data)
static void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar)
static ast_rwlock_t globalslock
int __ast_pthread_mutex_trylock(const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t)
#define WEXITSTATUS(status)
static struct ast_config_include * ast_include_find(struct ast_config *conf, const char *included_file)
struct ast_context * parent
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
void localized_use_local_dir(void)
struct ast_config * localized_config_load(const char *filename)
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)
#define pthread_mutex_unlock
static void ast_var_delete(struct ast_var_t *var)
#define ast_channel_trylock(chan)
void ast_mark_lock_failed(void *lock_addr)
Mark the last lock as failed (trylock)
struct ast_category * root
static int ast_rwlock_unlock(ast_rwlock_t *prwlock)
static char context[AST_MAX_CONTEXT]
static int ast_true(const char *s)
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
static int write_protect_config
#define AST_RWLIST_TRAVERSE
static struct sigaction safe_system_prev_handler
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define ast_opt_dont_warn
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
static int ast_wrlock_contexts(void)
void ast_log_backtrace(void)
Log a backtrace of the current thread's execution stack to the Asterisk log.
#define pthread_mutex_trylock
static snd_pcm_format_t format
struct ast_switch::@278 list
int localized_pbx_builtin_setvar(struct ast_channel *chan, const void *data)
#define WIFEXITED(status)
ast_context: An extension context - must remain in sync with fake_context
#define STATUS_NO_CONTEXT
int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan)
Evaluate the given expression.
static int ast_context_add_switch2(struct ast_context *con, const char *value, const char *data, int eval, const char *registrar)
static int ast_add_extension2(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Main interface to add extensions to the list for out context.
static int ast_extension_match(const char *pattern, const char *data)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
static const char * ast_var_value(const struct ast_var_t *var)
#define AST_RWLIST_INSERT_HEAD
Structure for mutex and tracking information.
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
int ast_atomic_dec_and_test(volatile int *p)
decrement *p by 1 and return true if the variable has reached 0. Useful e.g. to check if a refcount h...
#define AST_INLINE_API(hdr, body)
static int pbx_load_config(const char *config_file)