37 #include <sys/syscall.h>
39 #if defined(__APPLE__)
40 #include <mach/mach.h>
41 #elif defined(HAVE_SYS_THR_H)
45 #ifdef HAVE_DEV_URANDOM
52 #define AST_API_MODULE
60 #define AST_API_MODULE
63 #define AST_API_MODULE
66 #define AST_API_MODULE
69 #define AST_API_MODULE
72 #define AST_API_MODULE
75 #define AST_API_MODULE
83 #if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6)
95 static int gethostbyname_r (
const char *
name,
struct hostent *ret,
char *buf,
96 size_t buflen,
struct hostent **result,
112 int naddr = 0, naliases = 0;
116 for (p = ph->h_addr_list; *p != 0; p++) {
117 nbytes += ph->h_length;
118 nbytes +=
sizeof(*p);
121 nbytes +=
sizeof(*p);
124 for (p = ph->h_aliases; *p != 0; p++) {
125 nbytes += (strlen(*p)+1);
126 nbytes +=
sizeof(*p);
129 nbytes +=
sizeof(*p);
133 if (nbytes > buflen) {
156 ret->h_addr_list = q;
157 pbuf = buf + ((naddr + naliases + 2) *
sizeof(*p));
158 for (p = ph->h_addr_list; *p != 0; p++) {
159 memcpy(pbuf, *p, ph->h_length);
161 pbuf += ph->h_length;
167 for (p = ph->h_aliases; *p != 0; p++) {
175 strcpy(pbuf, ph->h_name);
177 pbuf += strlen(ph->h_name);
186 return (*result == NULL);
201 struct hostent *result = NULL;
211 else if (!isdigit(*s))
220 hp->
hp.h_addrtype = AF_INET;
221 hp->
hp.h_addr_list = (
void *) hp->
buf;
222 hp->
hp.h_addr = hp->
buf +
sizeof(
void *);
225 if (inet_pton(AF_INET, host, hp->
hp.h_addr) > 0)
230 #ifdef HAVE_GETHOSTBYNAME_R_5
231 result = gethostbyname_r(host, &hp->
hp, hp->
buf,
sizeof(hp->
buf), &herrno);
233 if (!result || !hp->
hp.h_addr_list || !hp->
hp.h_addr_list[0])
236 res = gethostbyname_r(host, &hp->
hp, hp->
buf,
sizeof(hp->
buf), &result, &herrno);
238 if (res || !result || !hp->
hp.h_addr_list || !hp->
hp.h_addr_list[0])
248 unsigned char digest[16];
253 MD5Update(&md5, (
const unsigned char *) input, strlen(input));
256 for (x = 0; x < 16; x++)
257 ptr += sprintf(ptr,
"%2.2x", (
unsigned)digest[x]);
266 uint8_t Message_Digest[20];
270 SHA1Input(&sha, (
const unsigned char *) input, strlen(input));
274 for (x = 0; x < 20; x++)
275 ptr += sprintf(ptr,
"%2.2x", (
unsigned)Message_Digest[x]);
282 unsigned int byte = 0;
283 unsigned int bits = 0;
285 while(*src && *src !=
'=' && (cnt < max)) {
288 byte |= (b2a[(int)(*src)]) & 0x3f;
296 *dst = (byte >> bits) & 0xff;
310 unsigned int byte = 0;
315 while ((cntin < srclen) && (cnt < max)) {
320 if ((bits == 24) && (cnt + 4 <= max)) {
321 *dst++ = base64[(byte >> 18) & 0x3f];
322 *dst++ = base64[(byte >> 12) & 0x3f];
323 *dst++ = base64[(byte >> 6) & 0x3f];
324 *dst++ = base64[byte & 0x3f];
330 if (linebreaks && (cnt < max) && (col == 64)) {
336 if (bits && (cnt + 4 <= max)) {
340 *dst++ = base64[(byte >> 18) & 0x3f];
341 *dst++ = base64[(byte >> 12) & 0x3f];
343 *dst++ = base64[(byte >> 6) & 0x3f];
349 if (linebreaks && (cnt < max)) {
365 memset(b2a, -1,
sizeof(b2a));
367 for (x = 0; x < 26; x++) {
372 base64[x + 26] =
'a' + x;
373 b2a[
'a' + x] = x + 26;
376 base64[x + 52] =
'0' + x;
377 b2a[
'0' + x] = x + 52;
398 char *
ast_uri_encode(
const char *
string,
char *outbuf,
int buflen,
int do_special_char)
402 const char *mark =
"-_.!~*'()";
404 while (*ptr && out - outbuf < buflen - 1) {
405 if ((
const signed char) *ptr < 32 || *ptr == 0x7f || *ptr ==
'%' ||
407 !(*ptr >=
'0' && *ptr <=
'9') &&
408 !(*ptr >=
'A' && *ptr <=
'Z') &&
409 !(*ptr >=
'a' && *ptr <=
'z') &&
410 !strchr(mark, *ptr))) {
411 if (out - outbuf >= buflen - 3) {
415 out += sprintf(out,
"%%%02X", (
unsigned) *ptr);
435 char *allow =
"\t\v !";
437 while (*ptr && out - outbuf < buflen - 1) {
438 if (!(strchr(allow, *ptr))
439 && !(*ptr >=
'#' && *ptr <=
'[')
440 && !(*ptr >=
']' && *ptr <=
'~')
441 && !((
unsigned char) *ptr > 0x7f)) {
443 if (out - outbuf >= buflen - 2) {
446 out += sprintf(out,
"\\%c", (
unsigned char) *ptr);
465 int quote_str_len = strlen(quote_str);
467 for (esc_pos = 0, unesc_pos = 0;
468 esc_pos < quote_str_len;
469 esc_pos++, unesc_pos++) {
470 if (quote_str[esc_pos] ==
'\\') {
473 if (esc_pos >= quote_str_len) {
478 quote_str[unesc_pos] = quote_str[esc_pos];
480 quote_str[unesc_pos] =
'\0';
489 for (o = s; *s; s++, o++) {
490 if (*s ==
'%' && s[1] !=
'\0' && s[2] !=
'\0' && sscanf(s + 1,
"%2x", &tmp) == 1) {
503 char *end = outbuf + buflen - 1;
512 while (*
string && dst < end) {
513 const char *
entity = NULL;
547 if (end - dst < len) {
560 return *
string ==
'\0' ? 0 : -1;
571 return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
574 #ifdef HAVE_DEV_URANDOM
579 #undef pthread_create
582 #if !defined(LOW_MEMORY)
587 #define AST_MAX_LOCKS 64
590 #undef pthread_mutex_t
591 #undef pthread_mutex_lock
592 #undef pthread_mutex_unlock
593 #undef pthread_mutex_init
594 #undef pthread_mutex_destroy
601 struct thr_lock_info {
605 const char *thread_name;
611 const char *lock_name;
622 } locks[AST_MAX_LOCKS];
626 unsigned int num_locks;
647 static void lock_info_destroy(
void *data)
657 for (i = 0; i < lock_info->num_locks; i++) {
658 if (lock_info->locks[i].pending == -1) {
665 "Thread '%s' still has a lock! - '%s' (%p) from '%s' in %s:%d!\n",
666 lock_info->thread_name,
667 lock_info->locks[i].lock_name,
668 lock_info->locks[i].lock_addr,
669 lock_info->locks[i].func,
670 lock_info->locks[i].file,
671 lock_info->locks[i].line_num
676 if (lock_info->thread_name)
677 free((
void *) lock_info->thread_name);
687 int line_num,
const char *func,
const char *lock_name,
void *lock_addr,
struct ast_bt *bt)
689 void ast_store_lock_info(
enum ast_lock_type type,
const char *filename,
690 int line_num,
const char *func,
const char *lock_name,
void *lock_addr)
701 for (i = 0; i < lock_info->num_locks; i++) {
702 if (lock_info->locks[i].lock_addr == lock_addr) {
703 lock_info->locks[i].times_locked++;
705 lock_info->locks[i].backtrace = bt;
712 if (lock_info->num_locks == AST_MAX_LOCKS) {
714 fprintf(stderr,
"XXX ERROR XXX A thread holds more locks than '%d'."
715 " Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
720 if (i && lock_info->locks[i - 1].pending == -1) {
725 lock_info->num_locks--;
726 memset(&lock_info->locks[i], 0,
sizeof(lock_info->locks[0]));
729 lock_info->locks[i].file = filename;
730 lock_info->locks[i].line_num = line_num;
731 lock_info->locks[i].func = func;
732 lock_info->locks[i].lock_name = lock_name;
733 lock_info->locks[i].lock_addr = lock_addr;
734 lock_info->locks[i].times_locked = 1;
735 lock_info->locks[i].type =
type;
736 lock_info->locks[i].pending = 1;
738 lock_info->locks[i].backtrace = bt;
740 lock_info->num_locks++;
745 void ast_mark_lock_acquired(
void *lock_addr)
753 if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
754 lock_info->locks[lock_info->num_locks - 1].pending = 0;
759 void ast_mark_lock_failed(
void *lock_addr)
767 if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
768 lock_info->locks[lock_info->num_locks - 1].pending = -1;
769 lock_info->locks[lock_info->num_locks - 1].times_locked--;
774 int ast_find_lock_info(
void *lock_addr,
char *filename,
size_t filename_size,
int *lineno,
char *func,
size_t func_size,
char *mutex_name,
size_t mutex_name_size)
784 for (i = lock_info->num_locks - 1; i >= 0; i--) {
785 if (lock_info->locks[i].lock_addr == lock_addr)
796 *lineno = lock_info->locks[i].line_num;
798 ast_copy_string(mutex_name, lock_info->locks[i].lock_name, mutex_name_size);
805 void ast_suspend_lock_info(
void *lock_addr)
816 for (i = lock_info->num_locks - 1; i >= 0; i--) {
817 if (lock_info->locks[i].lock_addr == lock_addr)
827 lock_info->locks[i].suspended = 1;
832 void ast_restore_lock_info(
void *lock_addr)
842 for (i = lock_info->num_locks - 1; i >= 0; i--) {
843 if (lock_info->locks[i].lock_addr == lock_addr)
853 lock_info->locks[i].suspended = 0;
860 void ast_remove_lock_info(
void *lock_addr,
struct ast_bt *bt)
862 void ast_remove_lock_info(
void *lock_addr)
873 for (i = lock_info->num_locks - 1; i >= 0; i--) {
874 if (lock_info->locks[i].lock_addr == lock_addr)
884 if (lock_info->locks[i].times_locked > 1) {
885 lock_info->locks[i].times_locked--;
887 lock_info->locks[i].backtrace = bt;
893 if (i < lock_info->num_locks - 1) {
895 memmove(&lock_info->locks[i], &lock_info->locks[i + 1],
896 (lock_info->num_locks - (i + 1)) *
sizeof(lock_info->locks[0]));
899 lock_info->num_locks--;
919 static void append_backtrace_information(
struct ast_str **
str,
struct ast_bt *bt)
935 for (frame_iterator = 0; frame_iterator < num_frames; ++frame_iterator) {
941 ast_str_append(str, 0,
"\tCouldn't retrieve backtrace symbols\n");
946 static void append_lock_information(
struct ast_str **str,
struct thr_lock_info *lock_info,
int i)
952 ast_str_append(str, 0,
"=== ---> %sLock #%d (%s): %s %d %s %s %p (%d%s)\n",
953 lock_info->locks[i].pending > 0 ?
"Waiting for " :
954 lock_info->locks[i].pending < 0 ?
"Tried and failed to get " :
"", i,
955 lock_info->locks[i].file,
956 locktype2str(lock_info->locks[i].type),
957 lock_info->locks[i].line_num,
958 lock_info->locks[i].func, lock_info->locks[i].lock_name,
959 lock_info->locks[i].lock_addr,
960 lock_info->locks[i].times_locked,
961 lock_info->locks[i].suspended ?
" - suspended" :
"");
963 append_backtrace_information(str, lock_info->locks[i].backtrace);
966 if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
970 if (lock_info->locks[i].type != AST_MUTEX)
973 lock = lock_info->locks[i].lock_addr;
975 ast_reentrancy_lock(lt);
976 for (j = 0; *str && j < lt->
reentrancy; j++) {
977 ast_str_append(str, 0,
"=== --- ---> Locked Here: %s line %d (%s)\n",
980 ast_reentrancy_unlock(lt);
1003 void log_show_lock(
void *this_lock_addr)
1018 for (i = 0; str && i < lock_info->num_locks; i++) {
1021 if (lock_info->locks[i].lock_addr == this_lock_addr) {
1022 append_lock_information(&str, lock_info, i);
1041 e->
command =
"core show locks";
1043 "Usage: core show locks\n"
1044 " This command is for lock debugging. It prints out which locks\n"
1045 "are owned by each active thread.\n";
1056 "=======================================================================\n"
1058 "=== Currently Held Locks\n"
1059 "=======================================================================\n"
1061 "=== <pending> <lock#> (<file>): <lock type> <line num> <function> <lock name> <lock addr> (times locked)\n"
1070 int header_printed = 0;
1072 for (i = 0; str && i < lock_info->num_locks; i++) {
1074 if (lock_info->locks[i].suspended) {
1078 if (!header_printed) {
1079 ast_str_append(&str, 0,
"=== Thread ID: 0x%lx (%s)\n", (
long) lock_info->thread_id,
1080 lock_info->thread_name);
1084 append_lock_information(&str, lock_info, i);
1090 if (header_printed) {
1091 ast_str_append(&str, 0,
"=== -------------------------------------------------------------------\n"
1103 ast_str_append(&str, 0,
"=======================================================================\n"
1117 AST_CLI_DEFINE(handle_show_locks,
"Show which locks are held by which thread"),
1128 void *(*start_routine)(
void *);
1144 #ifdef DEBUG_THREADS
1146 pthread_mutexattr_t mutex_attr;
1151 lock_info->thread_id = pthread_self();
1154 pthread_mutexattr_init(&mutex_attr);
1157 pthread_mutexattr_destroy(&mutex_attr);
1175 pthread_cleanup_pop(1);
1183 void *data,
size_t stacksize,
const char *file,
const char *caller,
1184 int line,
const char *start_fn)
1186 #if !defined(LOW_MEMORY)
1192 pthread_attr_init(attr);
1203 if ((
errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
1210 if ((
errno = pthread_attr_setstacksize(attr, stacksize ? stacksize :
AST_STACKSIZE)))
1213 #if !defined(LOW_MEMORY)
1219 start_fn, line, file, caller) < 0) {
1231 void *data,
size_t stacksize,
const char *file,
const char *caller,
1232 int line,
const char *start_fn)
1234 unsigned char attr_destroy = 0;
1239 pthread_attr_init(attr);
1243 if ((
errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
1247 stacksize, file, caller, line, start_fn);
1250 pthread_attr_destroy(attr);
1257 struct pollfd pfd[1];
1259 memset(pfd, 0,
sizeof(pfd));
1261 pfd[0].events = POLLIN | POLLPRI;
1267 struct pollfd pfd[1];
1269 memset(pfd, 0,
sizeof(pfd));
1271 pfd[0].events = POLLOUT;
1277 struct pollfd pfd = {
1286 while ((res =
ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
1290 ast_debug(1,
"Timed out trying to write\n");
1293 }
else if (res == -1) {
1298 if (elapsed >= timeoutms) {
1311 if (elapsed >= timeoutms) {
1339 res = write(fd, s, len);
1341 if (res < 0 &&
errno != EAGAIN &&
errno != EINTR) {
1358 if (elapsed >= timeoutms) {
1384 n = fwrite(src, 1, len, f);
1386 if (ferror(f) &&
errno != EINTR &&
errno != EAGAIN) {
1401 if (elapsed >= timeoutms) {
1420 if (
errno && !feof(f)) {
1428 return n < 0 ? -1 : 0;
1437 if ((q = strchr(beg_quotes, *s)) && *q !=
'\0') {
1438 e = s + strlen(s) - 1;
1439 if (*e == *(end_quotes + (q - beg_quotes))) {
1453 while ((e = strchr(work,
';'))) {
1454 if ((e > work) && (*(e-1) ==
'\\')) {
1455 memmove(e - 1, e, strlen(e) + 1);
1473 for (ret = dst = src; (c = *src++); *dst++ = c ) {
1476 switch ((c = *src++)) {
1506 if (!buffer || !*buffer || !space || !*space)
1509 result = vsnprintf(*buffer, *space, fmt, ap);
1513 else if (result > *space)
1539 if (!strcasecmp(s,
"yes") ||
1540 !strcasecmp(s,
"true") ||
1541 !strcasecmp(s,
"y") ||
1542 !strcasecmp(s,
"t") ||
1543 !strcasecmp(s,
"1") ||
1544 !strcasecmp(s,
"on"))
1556 if (!strcasecmp(s,
"no") ||
1557 !strcasecmp(s,
"false") ||
1558 !strcasecmp(s,
"n") ||
1559 !strcasecmp(s,
"f") ||
1560 !strcasecmp(s,
"0") ||
1561 !strcasecmp(s,
"off"))
1567 #define ONE_MILLION 1000000
1572 static struct timeval
tvfix(struct timeval a)
1576 (
long)a.tv_sec, (
long int) a.tv_usec);
1579 }
else if (a.tv_usec < 0) {
1581 (
long)a.tv_sec, (
long int) a.tv_usec);
1587 struct timeval
ast_tvadd(struct timeval a, struct timeval b)
1592 a.tv_sec += b.tv_sec;
1593 a.tv_usec += b.tv_usec;
1601 struct timeval
ast_tvsub(struct timeval a, struct timeval b)
1606 a.tv_sec -= b.tv_sec;
1607 a.tv_usec -= b.tv_usec;
1608 if (a.tv_usec < 0) {
1643 #ifdef HAVE_DEV_URANDOM
1644 if (dev_urandom_fd >= 0) {
1645 int read_res = read(dev_urandom_fd, &res,
sizeof(res));
1647 long int rm = RAND_MAX;
1648 res = res < 0 ? ~res : res;
1666 char *dataPut = start;
1670 for (; *start; start++) {
1672 *dataPut++ = *start;
1675 if (*start ==
'\\') {
1677 }
else if (*start ==
'\'') {
1678 inQuotes = 1 - inQuotes;
1681 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
1685 if (start != dataPut)
1698 for (x = 0; ofs < len && w[x]; x++) {
1701 for (src = w[x]; *src && ofs <
len; src++)
1720 static const struct {
1727 #define ALLOCATOR_OVERHEAD 48
1735 for (count = 1; size; size >>= 1, count++);
1745 size_t size,
const char *file,
int lineno,
const char *func)
1750 #if defined(__AST_DEBUG_MALLOC)
1751 if (!(pool =
__ast_calloc(1, alloc_size, file, lineno, func))) {
1760 pool->
prev = *pool_head;
1761 pool->
size = alloc_size -
sizeof(*pool);
1781 int needed,
const char *file,
int lineno,
const char *func)
1783 const char **p = (
const char **) pool_head + 1;
1793 #if defined(__AST_DEBUG_MALLOC)
1794 mgr->owner_file = file;
1795 mgr->owner_func = func;
1796 mgr->owner_line = lineno;
1820 if (*pool_head == NULL) {
1824 preserve = *pool_head;
1825 cur = preserve->
prev;
1829 preserve->
prev = NULL;
1836 if (cur != preserve) {
1842 *pool_head = preserve;
1850 char *result = NULL;
1851 size_t space = (*pool_head)->size - (*pool_head)->used;
1858 if (__builtin_expect(to_alloc > space, 0)) {
1859 size_t new_size = (*pool_head)->size;
1861 while (new_size < to_alloc) {
1865 #if defined(__AST_DEBUG_MALLOC)
1866 if (
add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
1869 if (
add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
1878 result = (*pool_head)->base + (*pool_head)->used;
1879 (*pool_head)->used += to_alloc;
1880 (*pool_head)->active += needed;
1893 size_t space = (*pool_head)->size - (*pool_head)->used;
1903 (*pool_head)->used += grow;
1904 (*pool_head)->active += grow;
1915 if (ptr == __ast_string_field_empty) {
1919 for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->
prev) {
1920 if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) {
1922 if (pool->active == 0) {
1941 size_t space = (*pool_head)->size - (*pool_head)->used;
1950 if (*ptr != __ast_string_field_empty) {
1951 target = (
char *) *ptr;
1968 res = vsnprintf(target, available, format, ap1);
1978 needed = (size_t)res + 1;
1980 if (needed > available) {
1988 vsprintf(target, format, ap2);
1991 }
else if (*ptr != target) {
2000 (*pool_head)->active += needed;
2007 (*pool_head)->active += grow;
2017 va_start(ap1, format);
2018 va_start(ap2, format);
2027 size_t field_mgr_pool_offset,
size_t pool_size,
const char *file,
2028 int lineno,
const char *func)
2033 size_t pool_size_needed =
sizeof(*pool) + pool_size;
2038 #if defined(__AST_DEBUG_MALLOC)
2039 if (!(allocation =
__ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
2043 if (!(allocation =
ast_calloc(num_structs, size_to_alloc))) {
2048 for (x = 0; x < num_structs; x++) {
2049 void *
base = allocation + (size_to_alloc * x);
2052 mgr = base + field_mgr_offset;
2053 pool_head = base + field_mgr_pool_offset;
2054 pool = base + struct_size;
2056 p = (
const char **) pool_head + 1;
2063 pool->
size = size_to_alloc - struct_size -
sizeof(*pool);
2064 #if defined(__AST_DEBUG_MALLOC)
2065 mgr->owner_file = file;
2066 mgr->owner_func = func;
2067 mgr->owner_line = lineno;
2091 int ast_get_timeval(
const char *src,
struct timeval *dst,
struct timeval _default,
int *consumed)
2093 long double dtv = 0.0;
2105 if (sscanf(src,
"%30Lf%n", &dtv, &scanned) > 0) {
2107 dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
2109 *consumed = scanned;
2132 if (sscanf(src,
"%30ld%n", &t, &scanned) == 1) {
2135 *consumed = scanned;
2143 #if defined(HAVE_IP_MTU_DISCOVER)
2144 int val = IP_PMTUDISC_DONT;
2146 if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val,
sizeof(val)))
2147 ast_log(
LOG_WARNING,
"Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
2154 int len = strlen(path), count = 0, x, piececount = 0;
2160 for (ptr = tmp; *ptr; ptr++) {
2166 pieces =
ast_alloca(count *
sizeof(*pieces));
2167 for (ptr = tmp; *ptr; ptr++) {
2170 pieces[piececount++] = ptr + 1;
2175 for (x = 0; x < piececount; x++) {
2177 strcat(fullpath,
"/");
2178 strcat(fullpath, pieces[x]);
2179 res = mkdir(fullpath, mode);
2180 if (res &&
errno != EEXIST)
2186 #if defined(DEBUG_THREADS) && !defined(LOW_MEMORY)
2187 static void utils_shutdown(
void)
2195 #ifdef HAVE_DEV_URANDOM
2196 dev_urandom_fd = open(
"/dev/urandom", O_RDONLY);
2199 #ifdef DEBUG_THREADS
2200 #if !defined(LOW_MEMORY)
2226 {
"realm=", &d->
realm },
2227 {
"nonce=", &d->
nonce },
2228 {
"uri=", &d->
uri },
2229 {
"domain=", &d->
domain },
2231 {
"cnonce=", &d->
cnonce },
2232 {
"opaque=", &d->
opaque },
2234 {
"algorithm=", NULL },
2249 if (strncasecmp(c,
"Digest ", strlen(
"Digest "))) {
2254 c += strlen(
"Digest ");
2259 for (i = keys; i->key != NULL; i++) {
2260 char *src, *separator;
2262 if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
2267 c += strlen(i->key);
2284 if (!strcasecmp(i->key,
"algorithm=")) {
2285 if (strcasecmp(src,
"MD5")) {
2290 }
else if (!strcasecmp(i->key,
"qop=") && !strcasecmp(src,
"auth")) {
2292 }
else if (!strcasecmp(i->key,
"nc=")) {
2294 if (sscanf(src,
"%30lx", &u) != 1) {
2304 if (i->key == NULL) {
2330 #ifndef __AST_DEBUG_MALLOC
2331 int _ast_asprintf(
char **ret,
const char *file,
int lineno,
const char *func,
const char *fmt, ...)
2337 if ((res =
vasprintf(ret, fmt, ap)) == -1) {
2349 #if defined (__linux) && defined(SYS_gettid)
2350 ret = syscall(SYS_gettid);
2351 #elif defined(__sun)
2352 ret = pthread_self();
2353 #elif defined(__APPLE__)
2354 ret = mach_thread_self();
2355 mach_port_deallocate(mach_task_self(), ret);
2356 #elif defined(__FreeBSD__) && defined(HAVE_SYS_THR_H)
2366 const char *envPATH = getenv(
"PATH");
2373 while ((path =
strsep(&tpath,
":"))) {
2374 snprintf(fullpath, fullpath_size,
"%s/%s", path, binary);
2375 if (!stat(fullpath, &unused)) {
2384 #if defined(DO_CRASH)
2394 #if defined(AST_DEVMODE)
2395 void __ast_assert_failed(
int condition,
const char *condition_str,
const char *file,
int line,
const char *
function)
2402 condition_str, condition);
2403 fprintf(stderr,
"FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
2404 condition_str, condition, line,
function, file);
void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, ast_string_field *ptr, const char *format,...)
const ast_string_field cnonce
#define ast_string_field_ptr_set(x, ptr, data)
Set a field to a simple string value.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
int vasprintf(char **strp, const char *fmt, va_list ap)
void ast_std_free(void *ptr)
#define pthread_mutex_init
void ast_register_thread(char *name)
#define AST_CLI_DEFINE(fn, txt,...)
void ast_enable_packet_fragmentation(int sock)
Disable PMTU discovery on a socket.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
char * strsep(char **str, const char *delims)
String manipulation functions.
uint16_t ast_string_field_allocation
ast_string_field_allocation allocation
const char * file[AST_MAX_REENTRANCY]
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Asterisk version information.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
int ast_careful_fwrite(FILE *f, int fd, const char *s, size_t len, int timeoutms)
Write data to a file stream with a timeout.
Time-related functions and macros.
#define ast_alignof(type)
Return the number of bytes used in the alignment of type.
int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
Try to write string, but wait no more than ms milliseconds before timing out.
const char * ast_get_version(void)
Retrieve the Asterisk version string.
void ast_uri_decode(char *s)
Decode URI, URN, URL (overwrite string)
struct ast_string_field_pool * embedded_pool
descriptor for a cli entry.
int __ast_string_field_ptr_grow(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, size_t needed, const ast_string_field *ptr)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
char * ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size)
Resolve a binary to a full pathname.
const ast_string_field opaque
const ast_string_field domain
void MD5Final(unsigned char digest[16], struct MD5Context *context)
void *(* start_routine)(void *)
int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize, const char *file, const char *caller, int line, const char *start_fn)
void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, ast_string_field *ptr, const char *format, va_list a1, va_list a2)
#define MALLOC_FAILURE_MSG
Configuration File Parser.
void *attribute_malloc __ast_calloc_with_stringfields(unsigned int num_structs, size_t struct_size, size_t field_mgr_offset, size_t field_mgr_pool_offset, size_t pool_size, const char *file, int lineno, const char *func)
char ** ast_bt_get_symbols(void **addresses, size_t num_frames)
const char * __ast_string_field_empty
void * __ast_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
struct ast_str * ast_str_create(size_t init_len)
Create a malloc'ed dynamic length string.
const char * ast_string_field
#define ast_mutex_lock(a)
const ast_string_field username
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
char * ast_uri_encode(const char *string, char *outbuf, int buflen, int do_special_char)
Turn text string to URI-encoded XX version.
char * ast_process_quotes_and_slashes(char *start, char find, char replace_with)
Process a string to find and replace characters.
I/O Management (derived from Cheops-NG)
Definitions to aid in the use of thread local storage.
int lineno[AST_MAX_REENTRANCY]
void ast_cli(int fd, const char *fmt,...)
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
static int input(yyscan_t yyscanner)
int ast_get_timeval(const char *src, struct timeval *tv, struct timeval _default, int *consumed)
get values from config variables.
int ast_xml_escape(const char *string, char *outbuf, size_t buflen)
Escape reserved characters for use in XML.
static struct ast_threadstorage inet_ntoa_buf
void MD5Init(struct MD5Context *context)
String fields in structures.
struct ast_lock_track * track
static size_t optimal_alloc_size(size_t size)
#define AST_STRING_FIELD_ALLOCATION(x)
Macro to provide access to the allocation field that lives immediately in front of a string field...
#define ALLOCATOR_OVERHEAD
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
static struct timeval tvfix(struct timeval a)
#define ast_asprintf(a, b, c...)
#define pthread_mutex_destroy
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
get values from config variables.
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
const ast_string_field uri
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_make_room_for(offset, type)
Increase offset by the required alignment of type and make sure it is a multiple of said alignment...
int ast_build_string(char **buffer, size_t *space, const char *fmt,...)
Build a string in a buffer, designed to be called repeatedly.
void ast_unregister_thread(void *id)
#define pthread_mutex_lock
const ast_string_field response
int ast_get_tid(void)
Get current thread ID.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_poll(a, b, c)
void ast_unescape_quoted(char *quote_str)
Unescape quotes in a string.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
long int ast_random(void)
A set of macros to manage forward-linked lists.
static int dev_urandom_fd
Wrapper for network related headers, masking differences between various operating systems...
void ast_sha1_hash(char *output, const char *input)
Produces SHA1 hash based on input string.
void __ast_string_field_release_active(struct ast_string_field_pool *pool_head, const ast_string_field ptr)
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
#define ast_strdupa(s)
duplicate a string in memory from the stack
int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
#define AST_LIST_HEAD_NOLOCK_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
const ast_string_field nc
const char * func[AST_MAX_REENTRANCY]
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.
void ast_join(char *s, size_t len, const char *const w[])
static ast_mutex_t randomlock
glibc puts a lock inside random(3), so that the results are thread-safe. BSD libc (and others) do not...
const ast_string_field realm
int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
Build a string in a buffer, designed to be called repeatedly.
static void * dummy_start(void *data)
void * addresses[AST_MAX_BT_FRAMES]
char * ast_unescape_semicolon(char *s)
Strip backslash for "escaped" semicolons, the string to be stripped (will be modified).
#define AST_THREADSTORAGE_CUSTOM(a, b, c)
Define a thread storage variable, with custom initialization and cleanup.
static void base64_init(void)
void ast_do_crash(void)
Force a crash if DO_CRASH is defined.
static int available(struct dahdi_pvt **pvt, int is_specific_channel)
const ast_string_field nonce
struct hostent * ast_gethostbyname(const char *host, struct ast_hostent *hp)
Thread-safe gethostbyname function to use in Asterisk.
int ast_wait_for_output(int fd, int ms)
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, size_t needed)
int SHA1Result(SHA1Context *, uint8_t Message_Digest[SHA1HashSize])
struct ast_string_field_pool * prev
int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic)
Parse digest authorization header.
#define ast_align_for(offset, type)
Increase offset so it is a multiple of the required alignment of type.
static struct ast_datastore_info lock_info
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
int ast_wait_for_input(int fd, int ms)
static struct @305 __ast_string_field_empty_buffer
int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, int needed, const char *file, int lineno, const char *func)
#define pthread_mutex_unlock
int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize, const char *file, const char *caller, int line, const char *start_fn)
static int wait_for_output(int fd, int timeoutms)
void ast_md5_hash(char *output, const char *input)
Produces MD5 hash based on input string.
static struct hostent * hp
static snd_pcm_format_t format
static ast_mutex_t fetchadd_m
static enum AST_LOCK_TYPE ast_lock_type
int SHA1Reset(SHA1Context *)
SHA1Reset.
#define AST_MUTEX_DEFINE_STATIC(mutex)
ast_string_field last_alloc
Structure for mutex and tracking information.
int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
encode text to BASE64 coding
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
static int add_string_pool(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, size_t size, const char *file, int lineno, const char *func)
add a new block to the pool. We can only allocate from the topmost pool, so the fields in *mgr reflec...
#define ast_mutex_unlock(a)
int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt,...)
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
char * ast_unescape_c(char *s)
Convert some C escape sequences.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
int SHA1Input(SHA1Context *, const uint8_t *bytes, unsigned int bytecount)