35 #include <sys/syscall.h> 37 #if defined(__APPLE__) 38 #include <mach/mach.h> 39 #elif defined(HAVE_SYS_THR_H) 46 #define AST_API_MODULE 55 #define AST_API_MODULE 58 #define AST_API_MODULE 61 #define AST_API_MODULE 64 #define AST_API_MODULE 67 #define AST_API_MODULE 70 #define AST_API_MODULE 78 #if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6) 90 static int gethostbyname_r (
const char *
name,
struct hostent *ret,
char *
buf,
91 size_t buflen,
struct hostent **
result,
107 int naddr = 0, naliases = 0;
111 for (p = ph->h_addr_list; *p != 0; p++) {
112 nbytes += ph->h_length;
113 nbytes +=
sizeof(*p);
116 nbytes +=
sizeof(*p);
119 for (p = ph->h_aliases; *p != 0; p++) {
120 nbytes += (strlen(*p)+1);
121 nbytes +=
sizeof(*p);
124 nbytes +=
sizeof(*p);
128 if (nbytes > buflen) {
151 ret->h_addr_list = q;
152 pbuf = buf + ((naddr + naliases + 2) *
sizeof(*p));
153 for (p = ph->h_addr_list; *p != 0; p++) {
154 memcpy(pbuf, *p, ph->h_length);
156 pbuf += ph->h_length;
162 for (p = ph->h_aliases; *p != 0; p++) {
170 strcpy(pbuf, ph->h_name);
172 pbuf += strlen(ph->h_name);
181 return (*result ==
NULL);
192 #ifndef HAVE_GETHOSTBYNAME_R_5 198 struct hostent *result =
NULL;
207 else if (!isdigit(*s))
216 hp->
hp.h_addrtype = AF_INET;
217 hp->
hp.h_addr_list = (
void *) hp->
buf;
218 hp->
hp.h_addr = hp->
buf +
sizeof(
void *);
221 if (inet_pton(AF_INET, host, hp->
hp.h_addr) > 0)
226 #ifdef HAVE_GETHOSTBYNAME_R_5 227 result = gethostbyname_r(host, &hp->
hp, hp->
buf,
sizeof(hp->
buf), &herrno);
229 if (!result || !hp->
hp.h_addr_list || !hp->
hp.h_addr_list[0])
232 res = gethostbyname_r(host, &hp->
hp, hp->
buf,
sizeof(hp->
buf), &result, &herrno);
234 if (res || !result || !hp->
hp.h_addr_list || !hp->
hp.h_addr_list[0])
244 unsigned char digest[16];
249 MD5Update(&md5, (
const unsigned char *) input, strlen(input));
252 for (x = 0; x < 16; x++)
253 ptr += sprintf(ptr,
"%02hhx", digest[x]);
262 uint8_t Message_Digest[20];
266 SHA1Input(&sha, (
const unsigned char *) input, strlen(input));
270 for (x = 0; x < 20; x++)
271 ptr += sprintf(ptr,
"%02hhx", Message_Digest[x]);
281 SHA1Input(&sha, (
const unsigned char *) input, strlen(input));
290 unsigned int byte = 0;
291 unsigned int bits = 0;
293 while(*src && *src !=
'=' && (cnt < max)) {
296 byte |= (
b2a[(int)(*src)]) & 0x3f;
304 *dst = (byte >> bits) & 0xff;
319 unsigned char *decoded_string;
325 encoded_len = strlen(src);
326 if (encoded_len > 2 && src[encoded_len - 1] ==
'=') {
328 if (src[encoded_len - 2] ==
'=') {
333 decoded_len = (encoded_len / 4 * 3) - padding;
335 if (!decoded_string) {
340 decoded_string[decoded_len] =
'\0';
342 return (
char *)decoded_string;
350 unsigned int byte = 0;
355 while ((cntin < srclen) && (cnt < max)) {
360 if ((bits == 24) && (cnt + 4 <=
max)) {
361 *dst++ =
base64[(byte >> 18) & 0x3f];
362 *dst++ =
base64[(byte >> 12) & 0x3f];
363 *dst++ =
base64[(byte >> 6) & 0x3f];
364 *dst++ =
base64[byte & 0x3f];
370 if (linebreaks && (cnt < max) && (col == 64)) {
376 if (bits && (cnt + 4 <= max)) {
380 *dst++ =
base64[(byte >> 18) & 0x3f];
381 *dst++ =
base64[(byte >> 12) & 0x3f];
383 *dst++ =
base64[(byte >> 6) & 0x3f];
389 if (linebreaks && (cnt < max)) {
406 char *encoded_string;
412 encoded_len = ((strlen(src) * 4 / 3 + 3) & ~3) + 1;
415 ast_base64encode(encoded_string, (
const unsigned char *)src, strlen(src), encoded_len);
417 return encoded_string;
423 memset(
b2a, -1,
sizeof(
b2a));
425 for (x = 0; x < 26; x++) {
431 b2a[
'a' + x] = x + 26;
435 b2a[
'0' + x] = x + 52;
452 const char *mark =
"-_.!~*'()";
453 const char *user_unreserved =
"&=+$,;?/";
455 while (*ptr && out - outbuf < buflen - 1) {
461 && strchr(mark, *ptr))
463 && ((*ptr >=
'0' && *ptr <=
'9')
464 || (*ptr >=
'A' && *ptr <=
'Z')
465 || (*ptr >=
'a' && *ptr <=
'z')))
467 && strchr(user_unreserved, *ptr))) {
469 if (out - outbuf >= buflen - 3) {
472 out += sprintf(out,
"%%%02hhX", (
unsigned char) *ptr);
492 for (o = s; *s; s++, o++) {
496 }
else if (*s ==
'%' && s[1] !=
'\0' && s[2] !=
'\0' && sscanf(s + 1,
"%2x", &tmp) == 1) {
510 char *allow =
"\t\v !";
512 while (*ptr && out - outbuf < buflen - 1) {
513 if (!(strchr(allow, *ptr))
514 && !(*ptr >=
'#' && *ptr <=
'[')
515 && !(*ptr >=
']' && *ptr <=
'~')
516 && !((
unsigned char) *ptr > 0x7f)) {
518 if (out - outbuf >= buflen - 2) {
521 out += sprintf(out,
"\\%c", (
unsigned char) *ptr);
541 if (
string ==
NULL || outbuf ==
NULL) {
546 while (*ptr && out - outbuf < buflen - 1) {
548 if (out - outbuf >= buflen - 2) {
571 int quote_str_len = strlen(quote_str);
573 for (esc_pos = 0, unesc_pos = 0;
574 esc_pos < quote_str_len;
575 esc_pos++, unesc_pos++) {
576 if (quote_str[esc_pos] ==
'\\') {
579 if (esc_pos >= quote_str_len) {
584 quote_str[unesc_pos] = quote_str[esc_pos];
586 quote_str[unesc_pos] =
'\0';
592 char *
end = outbuf + buflen - 1;
601 while (*
string && dst < end) {
636 if (end - dst < len) {
649 return *
string ==
'\0' ? 0 : -1;
660 return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
666 #undef pthread_create 671 #if !defined(LOW_MEMORY) 673 #define AST_MAX_LOCKS 64 676 #undef pthread_mutex_t 677 #undef pthread_mutex_lock 678 #undef pthread_mutex_unlock 679 #undef pthread_mutex_init 680 #undef pthread_mutex_destroy 687 struct thr_lock_info {
691 const char *thread_name;
696 const char *lock_name;
708 } locks[AST_MAX_LOCKS];
712 unsigned int num_locks;
735 static void lock_info_destroy(
void *data)
745 for (i = 0; i < lock_info->num_locks; i++) {
746 if (lock_info->locks[i].pending == -1) {
753 "Thread '%s' still has a lock! - '%s' (%p) from '%s' in %s:%d!\n",
754 lock_info->thread_name,
755 lock_info->locks[i].lock_name,
756 lock_info->locks[i].lock_addr,
757 lock_info->locks[i].func,
758 lock_info->locks[i].file,
759 lock_info->locks[i].line_num
764 if (lock_info->thread_name) {
765 ast_free((
void *) lock_info->thread_name);
777 int line_num,
const char *func,
const char *lock_name,
void *lock_addr,
struct ast_bt *bt)
779 #if !defined(LOW_MEMORY) 788 for (i = 0; i < lock_info->num_locks; i++) {
789 if (lock_info->locks[i].lock_addr == lock_addr) {
790 lock_info->locks[i].times_locked++;
792 lock_info->locks[i].backtrace = bt;
799 if (lock_info->num_locks == AST_MAX_LOCKS) {
801 fprintf(stderr,
"XXX ERROR XXX A thread holds more locks than '%d'." 802 " Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
807 if (i && lock_info->locks[i - 1].pending == -1) {
812 lock_info->num_locks--;
813 memset(&lock_info->locks[i], 0,
sizeof(lock_info->locks[0]));
816 lock_info->locks[i].file = filename;
817 lock_info->locks[i].line_num = line_num;
818 lock_info->locks[i].func = func;
819 lock_info->locks[i].lock_name = lock_name;
820 lock_info->locks[i].lock_addr = lock_addr;
821 lock_info->locks[i].times_locked = 1;
822 lock_info->locks[i].type =
type;
823 lock_info->locks[i].pending = 1;
825 lock_info->locks[i].backtrace = bt;
827 lock_info->num_locks++;
833 void ast_mark_lock_acquired(
void *lock_addr)
835 #if !defined(LOW_MEMORY) 842 if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
843 lock_info->locks[lock_info->num_locks - 1].pending = 0;
851 #if !defined(LOW_MEMORY) 858 if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
859 lock_info->locks[lock_info->num_locks - 1].pending = -1;
860 lock_info->locks[lock_info->num_locks - 1].times_locked--;
866 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)
868 #if !defined(LOW_MEMORY) 877 for (i = lock_info->num_locks - 1; i >= 0; i--) {
878 if (lock_info->locks[i].lock_addr == lock_addr)
889 *lineno = lock_info->locks[i].line_num;
891 ast_copy_string(mutex_name, lock_info->locks[i].lock_name, mutex_name_size);
901 void ast_suspend_lock_info(
void *lock_addr)
903 #if !defined(LOW_MEMORY) 913 for (i = lock_info->num_locks - 1; i >= 0; i--) {
914 if (lock_info->locks[i].lock_addr == lock_addr)
924 lock_info->locks[i].suspended = 1;
930 void ast_restore_lock_info(
void *lock_addr)
932 #if !defined(LOW_MEMORY) 941 for (i = lock_info->num_locks - 1; i >= 0; i--) {
942 if (lock_info->locks[i].lock_addr == lock_addr)
952 lock_info->locks[i].suspended = 0;
959 void ast_remove_lock_info(
void *lock_addr,
struct ast_bt *bt)
961 #if !defined(LOW_MEMORY) 970 for (i = lock_info->num_locks - 1; i >= 0; i--) {
971 if (lock_info->locks[i].lock_addr == lock_addr)
981 if (lock_info->locks[i].times_locked > 1) {
982 lock_info->locks[i].times_locked--;
984 lock_info->locks[i].backtrace = bt;
990 if (i < lock_info->num_locks - 1) {
992 memmove(&lock_info->locks[i], &lock_info->locks[i + 1],
993 (lock_info->num_locks - (i + 1)) *
sizeof(lock_info->locks[0]));
996 lock_info->num_locks--;
1002 #if !defined(LOW_MEMORY) 1018 static void append_backtrace_information(
struct ast_str **
str,
struct ast_bt *bt)
1020 struct ast_vector_string *symbols;
1034 for (frame_iterator = 1; frame_iterator <
AST_VECTOR_SIZE(symbols); ++frame_iterator) {
1040 ast_str_append(str, 0,
"\tCouldn't retrieve backtrace symbols\n");
1045 static void append_lock_information(
struct ast_str **str,
struct thr_lock_info *
lock_info,
int i)
1051 ast_str_append(str, 0,
"=== ---> %sLock #%d (%s): %s %d %s %s %p (%d%s)\n",
1052 lock_info->locks[i].pending > 0 ?
"Waiting for " :
1053 lock_info->locks[i].pending < 0 ?
"Tried and failed to get " :
"", i,
1054 lock_info->locks[i].file,
1055 locktype2str(lock_info->locks[i].type),
1056 lock_info->locks[i].line_num,
1057 lock_info->locks[i].func, lock_info->locks[i].lock_name,
1058 lock_info->locks[i].lock_addr,
1059 lock_info->locks[i].times_locked,
1060 lock_info->locks[i].suspended ?
" - suspended" :
"");
1062 append_backtrace_information(str, lock_info->locks[i].backtrace);
1065 if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
1069 if (lock_info->locks[i].type !=
AST_MUTEX)
1072 lock = lock_info->locks[i].lock_addr;
1074 ast_reentrancy_lock(lt);
1075 for (j = 0; *str && j < lt->
reentrancy; j++) {
1076 ast_str_append(str, 0,
"=== --- ---> Locked Here: %s line %d (%s)\n",
1079 ast_reentrancy_unlock(lt);
1102 void ast_log_show_lock(
void *this_lock_addr)
1104 #if !defined(LOW_MEMORY) 1118 for (i = 0; str && i < lock_info->num_locks; i++) {
1121 if (lock_info->locks[i].lock_addr == this_lock_addr) {
1122 append_lock_information(&str, lock_info, i);
1135 struct ast_str *ast_dump_locks(
void)
1137 #if !defined(LOW_MEMORY) 1146 "=======================================================================\n" 1148 "=== Currently Held Locks\n" 1149 "=======================================================================\n" 1151 "=== <pending> <lock#> (<file>): <lock type> <line num> <function> <lock name> <lock addr> (times locked)\n" 1161 int header_printed = 0;
1163 for (i = 0; str && i < lock_info->num_locks; i++) {
1165 if (lock_info->locks[i].suspended) {
1169 if (!header_printed) {
1170 if (lock_info->lwp != -1) {
1172 (
long unsigned) lock_info->thread_id, lock_info->lwp, lock_info->thread_name);
1175 (
long unsigned) lock_info->thread_id, lock_info->thread_name);
1180 append_lock_information(&str, lock_info, i);
1186 if (header_printed) {
1187 ast_str_append(&str, 0,
"=== -------------------------------------------------------------------\n" 1200 ast_str_append(&str, 0,
"=======================================================================\n" 1209 #if !defined(LOW_MEMORY) 1216 e->
command =
"core show locks";
1218 "Usage: core show locks\n" 1219 " This command is for lock debugging. It prints out which locks\n" 1220 "are owned by each active thread.\n";
1228 str = ast_dump_locks();
1241 AST_CLI_DEFINE(handle_show_locks,
"Show which locks are held by which thread"),
1246 #if !defined(LOW_MEMORY) 1253 void *(*start_routine)(
void *);
1269 #ifdef DEBUG_THREADS 1271 pthread_mutexattr_t mutex_attr;
1276 lock_info->thread_id = pthread_self();
1280 pthread_mutexattr_init(&mutex_attr);
1283 pthread_mutexattr_destroy(&mutex_attr);
1301 pthread_cleanup_pop(1);
1310 #if !defined(LOW_MEMORY) 1318 void *data,
size_t stacksize,
const char *
file,
const char *caller,
1319 int line,
const char *start_fn)
1321 #if !defined(LOW_MEMORY) 1327 pthread_attr_init(attr);
1330 #if defined(__linux__) || defined(__FreeBSD__) 1338 if ((
errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
1345 if ((
errno = pthread_attr_setstacksize(attr, stacksize ? stacksize :
AST_STACKSIZE)))
1348 #if !defined(LOW_MEMORY) 1354 start_fn, line, file, caller) < 0) {
1366 void *data,
size_t stacksize,
const char *
file,
const char *caller,
1367 int line,
const char *start_fn)
1369 unsigned char attr_destroy = 0;
1374 pthread_attr_init(attr);
1378 if ((
errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
1382 stacksize, file, caller, line, start_fn);
1385 pthread_attr_destroy(attr);
1392 struct pollfd pfd[1];
1394 memset(pfd, 0,
sizeof(pfd));
1396 pfd[0].events = POLLIN | POLLPRI;
1402 struct pollfd pfd[1];
1404 memset(pfd, 0,
sizeof(pfd));
1406 pfd[0].events = POLLOUT;
1412 struct pollfd pfd = {
1421 while ((res =
ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
1425 ast_debug(1,
"Timed out trying to write\n");
1428 }
else if (res == -1) {
1433 if (elapsed >= timeoutms) {
1446 if (elapsed >= timeoutms) {
1474 res = write(fd, s, len);
1476 if (res < 0 &&
errno != EAGAIN &&
errno != EINTR) {
1478 if (
errno == EPIPE) {
1480 ast_debug(1,
"write() failed due to reading end being closed: %s\n", strerror(
errno));
1499 if (elapsed >= timeoutms) {
1516 if ((q = strchr(beg_quotes, *s)) && *q !=
'\0') {
1517 e = s + strlen(s) - 1;
1518 if (*e == *(end_quotes + (q - beg_quotes))) {
1539 memset(stack, 0,
sizeof(stack));
1541 for(is = st; *is; is++) {
1543 if (*++is !=
'\0') {
1550 if (*is ==
'\'' || *is ==
'"') {
1551 if (*is == stack[inquote]) {
1552 stack[inquote--] =
'\0';
1554 if (++inquote >=
sizeof(stack)) {
1557 stack[inquote] = *is;
1561 if (*is == sep && !inquote) {
1592 while ((e = strchr(work,
';'))) {
1593 if ((e > work) && (*(e-1) ==
'\\')) {
1594 memmove(e - 1, e, strlen(e) + 1);
1612 for (ret = dst = src; (c = *src++); *dst++ =
c ) {
1615 switch ((c = *src++)) {
1646 '\a',
'\b',
'\f',
'\n',
'\r',
'\t',
'\v',
'\\',
'\'',
'\"',
'\?',
'\0' 1654 'a',
'b',
'f',
'n',
'r',
't',
'v',
'\\',
'\'',
'"',
'?',
'\0' 1657 char *
ast_escape(
char *dest,
const char *s,
size_t size,
const char *to_escape)
1662 if (!dest || !size) {
1675 for (p = dest; *s && --size; ++s, ++p) {
1677 if (strchr(to_escape, *s)) {
1688 c = strchr(escape_sequences, *s);
1710 if (!dest || !size) {
1718 for (p = dest; *s && --size; ++s, ++p) {
1723 c = strchr(escape_sequences, *s);
1751 *size = strlen(s) * 2 + 1;
1775 if (!buffer || !*buffer || !space || !*space)
1778 result = vsnprintf(*buffer, *space, fmt, ap);
1782 else if (result > *space)
1804 int regex_len = strlen(regex_string);
1808 if ((regex_len >= 1) && (regex_string[0] ==
'/')) {
1809 ast_str_set(regex_pattern, 0,
"%s", regex_string + 1);
1814 if ((regex_len > 1) && (regex_string[regex_len - 1] ==
'/')) {
1828 if (!strcasecmp(s,
"yes") ||
1829 !strcasecmp(s,
"true") ||
1830 !strcasecmp(s,
"y") ||
1831 !strcasecmp(s,
"t") ||
1832 !strcasecmp(s,
"1") ||
1833 !strcasecmp(s,
"on"))
1845 if (!strcasecmp(s,
"no") ||
1846 !strcasecmp(s,
"false") ||
1847 !strcasecmp(s,
"n") ||
1848 !strcasecmp(s,
"f") ||
1849 !strcasecmp(s,
"0") ||
1850 !strcasecmp(s,
"off"))
1856 #define ONE_MILLION 1000000 1861 static struct timeval
tvfix(struct timeval a)
1865 (
long)a.tv_sec, (
long int) a.tv_usec);
1868 }
else if (a.tv_usec < 0) {
1870 (
long)a.tv_sec, (
long int) a.tv_usec);
1881 a.tv_sec +=
b.tv_sec;
1882 a.tv_usec +=
b.tv_usec;
1895 a.tv_sec -=
b.tv_sec;
1896 a.tv_usec -=
b.tv_usec;
1897 if (a.tv_usec < 0) {
1922 int durh, durm, durs;
1923 durh = duration / 3600;
1924 durm = (duration % 3600) / 60;
1925 durs = duration % 60;
1926 snprintf(buf, length,
"%02d:%02d:%02d", durh, durm, durs);
1939 if (dev_urandom_fd >= 0) {
1940 int read_res = read(dev_urandom_fd, &res,
sizeof(res));
1942 long int rm = RAND_MAX;
1943 res = res < 0 ? ~res : res;
1977 char *dataPut = start;
1981 for (; *start; start++) {
1983 *dataPut++ = *start;
1986 if (*start ==
'\\') {
1988 }
else if (*start ==
'\'') {
1989 inQuotes = 1 - inQuotes;
1992 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
1996 if (start != dataPut)
2009 for (x = 0; ofs < len && x < size && w[x] ; x++) {
2012 for (src = w[x]; *src && ofs <
len; src++)
2023 char *front, *back, *buf = res;
2026 front = strtok_r(buf, delim, &back);
2029 size = strlen(front);
2030 *front = toupper(*front);
2033 front = strtok_r(
NULL, delim, &back);
2042 int ast_get_timeval(
const char *src,
struct timeval *dst,
struct timeval _default,
int *consumed)
2044 long double dtv = 0.0;
2056 if (sscanf(src,
"%30Lf%n", &dtv, &scanned) > 0) {
2058 dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
2060 *consumed = scanned;
2083 if (sscanf(src,
"%30ld%n", &t, &scanned) == 1) {
2086 *consumed = scanned;
2094 #if defined(HAVE_IP_MTU_DISCOVER) 2095 int val = IP_PMTUDISC_DONT;
2097 if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val,
sizeof(val)))
2098 ast_log(
LOG_WARNING,
"Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
2105 int len = strlen(path), count = 0, x, piececount = 0;
2111 for (ptr = tmp; *ptr; ptr++) {
2117 pieces =
ast_alloca(count *
sizeof(*pieces));
2118 for (ptr = tmp; *ptr; ptr++) {
2121 pieces[piececount++] = ptr + 1;
2126 for (x = 0; x < piececount; x++) {
2128 strcat(fullpath,
"/");
2129 strcat(fullpath, pieces[x]);
2130 res = mkdir(fullpath, mode);
2131 if (res &&
errno != EEXIST)
2137 static int safe_mkdir(
const char *base_path,
char *path,
int mode)
2141 absolute_path = realpath(path,
NULL);
2143 if (absolute_path) {
2155 char *path_term = strchr(path,
'/');
2157 int parent_is_safe = 0;
2164 char c = *(path_term + 1);
2165 *(path_term + 1) =
'\0';
2166 absolute_subpath = realpath(path,
NULL);
2168 if (absolute_subpath) {
2171 absolute_subpath, base_path);
2172 }
else if (parent_is_safe) {
2175 res = mkdir(path, mode);
2187 *(path_term + 1) = c;
2189 path_term = strchr(path_term + 1,
'/');
2193 if (!parent_is_safe) {
2198 res = mkdir(path, mode);
2199 if (res != 0 &&
errno != EEXIST) {
2212 if (base_path ==
NULL || path ==
NULL) {
2223 absolute_base_path = realpath(base_path,
NULL);
2224 if (absolute_base_path ==
NULL) {
2228 return safe_mkdir(absolute_base_path, p, mode);
2233 close(dev_urandom_fd);
2234 dev_urandom_fd = -1;
2235 #if defined(DEBUG_THREADS) && !defined(LOW_MEMORY) 2242 dev_urandom_fd = open(
"/dev/urandom", O_RDONLY);
2244 #ifdef DEBUG_THREADS 2245 #if !defined(LOW_MEMORY) 2271 {
"realm=", &d->
realm },
2272 {
"nonce=", &d->
nonce },
2273 {
"uri=", &d->
uri },
2274 {
"domain=", &d->
domain },
2276 {
"cnonce=", &d->
cnonce },
2277 {
"opaque=", &d->
opaque },
2279 {
"algorithm=",
NULL },
2294 if (strncasecmp(c,
"Digest ", strlen(
"Digest "))) {
2299 c += strlen(
"Digest ");
2304 for (i = keys; i->key !=
NULL; i++) {
2305 char *src, *separator;
2307 if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
2312 c += strlen(i->key);
2329 if (!strcasecmp(i->key,
"algorithm=")) {
2330 if (strcasecmp(src,
"MD5")) {
2335 }
else if (!strcasecmp(i->key,
"qop=") && !strcasecmp(src,
"auth")) {
2337 }
else if (!strcasecmp(i->key,
"nc=")) {
2339 if (sscanf(src,
"%30lx", &u) != 1) {
2349 if (i->key ==
NULL) {
2378 #if defined (__linux) && defined(SYS_gettid) 2379 ret = syscall(SYS_gettid);
2380 #elif defined(__sun) 2381 ret = pthread_self();
2382 #elif defined(__APPLE__) 2383 ret = mach_thread_self();
2384 mach_port_deallocate(mach_task_self(), ret);
2385 #elif defined(__FreeBSD__) && defined(HAVE_SYS_THR_H) 2395 const char *envPATH = getenv(
"PATH");
2402 while ((path =
strsep(&tpath,
":"))) {
2403 snprintf(fullpath, fullpath_size,
"%s/%s", path, binary);
2404 if (!stat(fullpath, &unused)) {
2413 int udp6_socket = socket(AF_INET6, SOCK_DGRAM, 0);
2415 if (udp6_socket < 0) {
2425 #if defined(DO_CRASH) 2441 fprintf(stderr,
"FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
2442 condition_str, condition, line,
function, file);
2444 condition_str, condition);
2463 if (s && (maxlen > 0)) {
2467 for (x = 0; x < 5; x++) {
2468 sprintf(s,
"%02hhx:", eid->
eid[x]);
2471 sprintf(s,
"%02hhx", eid->
eid[5]);
2476 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__Darwin__) 2477 #include <ifaddrs.h> 2478 #include <net/if_dl.h> 2482 struct ifaddrs *ifap, *ifaphead;
2484 const struct sockaddr_dl *sdl;
2488 unsigned char empty_mac[6] = {0, 0, 0, 0, 0, 0};
2489 unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2491 rtnerr = getifaddrs(&ifaphead);
2494 "You will have to set it manually.\n");
2500 "You will have to set it manually.\n");
2504 for (ifap = ifaphead; ifap; ifap = ifap->ifa_next) {
2505 if (ifap->ifa_addr->sa_family != AF_LINK) {
2509 sdl = (
const struct sockaddr_dl *) ifap->ifa_addr;
2510 ap = ((caddr_t) ((sdl)->sdl_data + (sdl)->sdl_nlen));
2511 alen = sdl->sdl_alen;
2512 if (alen != 6 || !(memcmp(ap, &empty_mac, 6) && memcmp(ap, &full_mac, 6))) {
2516 memcpy(eid, ap,
sizeof(*eid));
2517 ast_debug(1,
"Seeding global EID '%s'\n",
2519 freeifaddrs(ifaphead);
2524 "You will have to set it manually.\n");
2525 freeifaddrs(ifaphead);
2530 #elif defined(SOLARIS) 2531 #include <sys/sockio.h> 2532 #include <net/if_arp.h> 2538 struct lifreq *ifr =
NULL;
2542 struct sockaddr_in *sa, *sa2;
2546 unsigned char empty_mac[6] = {0, 0, 0, 0, 0, 0};
2547 unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2549 s = socket(AF_INET, SOCK_STREAM, 0);
2552 " You will have to set it manually.\n");
2557 ifn.lifn_family = AF_UNSPEC;
2560 if (ioctl(s, SIOCGLIFNUM, &ifn) < 0) {
2562 " You will have to set it manually.\n");
2567 bufsz = ifn.lifn_count *
sizeof(
struct lifreq);
2570 "You will have to set it manually.\n");
2574 memset(buf, 0, bufsz);
2577 ifc.lifc_len = bufsz;
2579 ifc.lifc_family = AF_UNSPEC;
2581 if (ioctl(s, SIOCGLIFCONF, &ifc) < 0) {
2583 "You will have to set it manually.\n");
2589 for (ifr = (
struct lifreq *)buf, x = 0; x < ifn.lifn_count; ifr++, x++) {
2592 sa = (
struct sockaddr_in *)&(ifr->lifr_addr);
2593 sa2 = (
struct sockaddr_in *)&(ar.arp_pa);
2596 if(ioctl(s, SIOCGARP, &ar) >= 0) {
2597 p = (
unsigned char *)&(ar.arp_ha.sa_data);
2598 if (!(memcmp(p, &empty_mac, 6) && memcmp(p, &full_mac, 6))) {
2602 memcpy(eid, p,
sizeof(*eid));
2603 ast_debug(1,
"Seeding global EID '%s'\n",
2612 "You will have to set it manually.\n");
2629 int bufsz, num_interfaces;
2630 unsigned char empty_mac[6] = {0, 0, 0, 0, 0, 0};
2631 unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2633 s = socket(AF_INET, SOCK_STREAM, 0);
2636 "You will have to set it manually.\n");
2642 if (ioctl(s, SIOCGIFCONF, &ifc) || ifc.ifc_len <= 0) {
2644 "You will have to set it manually.\n");
2648 bufsz = ifc.ifc_len;
2652 "You will have to set it manually.\n");
2658 if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
2659 ast_log(
LOG_WARNING,
"Unable to retrieve ethernet interfaces for seeding global EID. " 2660 "You will have to set it manually.\n");
2667 num_interfaces = ifc.ifc_len /
sizeof(*ifr);
2669 for (i = 0; i < num_interfaces; i++) {
2671 if (!ioctl(s, SIOCGIFHWADDR, ifr)) {
2672 unsigned char *hwaddr = (
unsigned char *) ifr->ifr_hwaddr.sa_data;
2674 if (!(memcmp(hwaddr, &empty_mac, 6) && memcmp(hwaddr, &full_mac, 6))) {
2678 memcpy(eid, hwaddr,
sizeof(*eid));
2679 ast_debug(1,
"Seeding global EID '%s' from '%s' using 'siocgifhwaddr'\n",
2688 "You will have to set it manually.\n");
2698 unsigned int eid_int[6];
2701 if (sscanf(s,
"%2x:%2x:%2x:%2x:%2x:%2x", &eid_int[0], &eid_int[1], &eid_int[2],
2702 &eid_int[3], &eid_int[4], &eid_int[5]) != 6) {
2706 for (x = 0; x < 6; x++) {
2707 eid->
eid[x] = eid_int[x];
2715 return memcmp(eid1, eid2,
sizeof(*eid1));
2722 memset(&empty_eid, 0,
sizeof(empty_eid));
2723 return memcmp(eid, &empty_eid,
sizeof(empty_eid)) ? 0 : 1;
2728 #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) 2729 #if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS) 2730 #define eaccess euidaccess 2732 return eaccess(filename, R_OK) == 0;
2734 int fd = open(filename, O_RDONLY | O_NONBLOCK);
2745 unsigned int major[2] = { 0 };
2746 unsigned int minor[2] = { 0 };
2747 unsigned int patch[2] = { 0 };
2748 unsigned int extra[2] = { 0 };
2751 sscanf(version1,
"%u.%u.%u.%u", &major[0], &minor[0], &patch[0], &extra[0]);
2752 sscanf(version2,
"%u.%u.%u.%u", &major[1], &minor[1], &patch[1], &extra[1]);
2754 res = major[0] - major[1];
2758 res = minor[0] - minor[1];
2762 res = patch[0] - patch[1];
2766 return extra[0] - extra[1];
2770 const char *
file,
int lineno,
const char *
function)
2774 f = fcntl(fd, F_GETFL);
2777 "Failed to get fcntl() flags for file descriptor: %s\n", strerror(
errno));
2783 if ((f & flags) == flags) {
2801 f = fcntl(fd, F_SETFL, f);
2804 "Failed to set fcntl() flags for file descriptor: %s\n", strerror(
errno));
2811 #ifndef HAVE_SOCK_NONBLOCK 2814 int s = socket(domain, type, protocol);
2831 int p = pipe(filedes);
2854 int *thread_user_interface;
2858 if (thread_user_interface ==
NULL) {
2859 ast_log(
LOG_ERROR,
"Error setting user interface status for current thread\n");
2863 *thread_user_interface = !!is_user_interface;
2869 int *thread_user_interface;
2873 if (thread_user_interface ==
NULL) {
2879 return *thread_user_interface;
const ast_string_field cnonce
#define ast_string_field_ptr_set(x, ptr, data)
Set a field to a simple string value.
static int dev_urandom_fd
void ast_unescape_quoted(char *quote_str)
Unescape quotes in a string.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
void ast_std_free(void *ptr)
#define pthread_mutex_init
void ast_register_thread(char *name)
const struct ast_flags ast_uri_sip_user
#define AST_CLI_DEFINE(fn, txt,...)
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
Compare two EIDs.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
const struct ast_flags ast_uri_http_legacy
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
char * ast_escape_c(char *dest, const char *s, size_t size)
Escape standard 'C' sequences in the given string.
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)
String manipulation functions.
const char * file[AST_MAX_REENTRANCY]
Asterisk version information.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define ast_bt_free_symbols(string_vector)
#define ast_pipe_nonblock(filedes)
Create a non-blocking pipe.
#define ast_test_flag(p, flag)
Time-related functions and macros.
const char * ast_get_version(void)
Retrieve the Asterisk version string.
int ast_get_timeval(const char *src, struct timeval *dst, struct timeval _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.
descriptor for a cli entry.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define ast_socket_nonblock(domain, type, protocol)
Create a non-blocking socket.
const ast_string_field opaque
int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
encode text to BASE64 coding
int ast_thread_is_user_interface(void)
Indicates whether the current thread is a user interface.
static void base64_init(void)
int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
get values from config variables.
const ast_string_field domain
void MD5Final(unsigned char digest[16], struct MD5Context *context)
#define ast_bt_get_symbols(addresses, num_frames)
int ast_str_to_eid(struct ast_eid *eid, const char *s)
Convert a string into an EID.
int ast_get_tid(void)
Get current thread ID.
char * ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size)
Resolve a binary to a full pathname.
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
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.
#define ast_strdup(str)
A wrapper for strdup()
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)
char * ast_strsep(char **iss, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
char * ast_base64decode_string(const char *src)
Decode BASE64 encoded text and return the string.
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
An Entity ID is essentially a MAC address, brief and unique.
int ast_background_stacksize(void)
void MD5Init(struct MD5Context *context)
void ast_sha1_hash_uint(uint8_t *digest, const char *input)
Produce a 20 byte SHA1 hash of value.
int ast_build_string(char **buffer, size_t *space, const char *fmt,...)
Build a string in a buffer, designed to be called repeatedly.
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
void ast_log_backtrace(void)
Log a backtrace of the current thread's execution stack to the Asterisk log.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
const struct ast_flags ast_uri_http
Configuration File Parser.
#define pthread_mutex_destroy
#define ast_fd_set_flags(fd, flags)
Set flags on the given file descriptor.
const ast_string_field uri
#define ast_debug(level,...)
Log a DEBUG message.
char * ast_escape_semicolons(const char *string, char *outbuf, int buflen)
Escape semicolons found in a string.
#define AST_URI_UNRESERVED
void ast_unregister_thread(void *id)
Lock tracking information.
#define pthread_mutex_lock
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
const ast_string_field response
char * ast_escape_c_alloc(const char *s)
Escape standard 'C' sequences in the given string.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
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.
#define ast_poll(a, b, c)
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
int ast_file_is_readable(const char *filename)
Test that a file exists and is readable by the effective user.
static char * escape_alloc(const char *s, size_t *size)
#define ast_strdupa(s)
duplicate a string in memory from the stack
A set of macros to manage forward-linked lists.
#define ast_malloc(len)
A wrapper for malloc()
int ast_regex_string_to_regex_pattern(const char *regex_string, struct ast_str **regex_pattern)
Given a string regex_string in the form of "/regex/", convert it into the form of "regex"...
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)
void DO_CRASH_NORETURN ast_do_crash(void)
Force a crash if DO_CRASH is defined.
int ast_cli_allow_at_shutdown(struct ast_cli_entry *e)
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.
char * ast_unescape_semicolon(char *s)
Strip backslash for "escaped" semicolons, the string to be stripped (will be modified).
void ast_format_duration_hh_mm_ss(int duration, char *buf, size_t length)
Formats a duration into HH:MM:SS.
int ast_wait_for_input(int fd, int ms)
struct hostent * ast_gethostbyname(const char *host, struct ast_hostent *hp)
Re-entrant (thread safe) version of gethostbyname that replaces the standard gethostbyname (which is ...
Wrapper for network related headers, masking differences between various operating systems...
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
void ast_md5_hash(char *output, const char *input)
Produce 32 char MD5 hash of value.
static void * dummy_start(void *data)
#define AST_LIST_HEAD_NOLOCK_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
static const struct ast_datastore_info lock_info
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
int ast_eid_is_empty(const struct ast_eid *eid)
Check if EID is empty.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
int ast_compare_versions(const char *version1, const char *version2)
Compare 2 major.minor.patch.extra version strings.
int ast_base64decode(unsigned char *dst, const char *src, int max)
decode BASE64 encoded text
long int ast_random(void)
void ast_sha1_hash(char *output, const char *input)
Produce 40 char SHA1 hash of value.
int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic)
Parse digest authorization header.
void ast_join_delim(char *s, size_t len, const char *const w[], unsigned int size, char delim)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
void ast_uri_decode(char *s, struct ast_flags spec)
Decode URI, URN, URL (overwrite string)
const char * ast_inet_ntoa(struct in_addr ia)
ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa
const ast_string_field nc
int ast_false(const char *s)
Make sure something is false. Determine if a string containing a boolean value is "false"...
static ast_mutex_t randomlock
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.
#define ast_strlen_zero(a)
#define AST_URI_SIP_USER_UNRESERVED
#define ast_calloc(num, len)
A wrapper for calloc()
char * ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec)
Turn text string to URI-encoded XX version.
char * ast_unescape_c(char *src)
Convert some C escape sequences.
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
const ast_string_field realm
static int wait_for_output(int fd, int timeoutms)
void *(* start_routine)(void *)
static int request(void *obj)
int ast_safe_mkdir(const char *base_path, const char *path, int mode)
Recursively create directory path, but only if it resolves within the given base_path.
void * addresses[AST_MAX_BT_FRAMES]
Structure used to handle boolean flags.
static char escape_sequences_map[]
void ast_replace_subargument_delimiter(char *s)
Replace '^' in a string with ','.
#define AST_THREADSTORAGE_CUSTOM(a, b, c)
Define a thread storage variable, with custom initialization and cleanup.
char * ast_to_camel_case_delim(const char *s, const char *delim)
const ast_string_field nonce
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
static struct timeval tvfix(struct timeval a)
int ast_true(const char *s)
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".
char * strsep(char **str, const char *delims)
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.
static int safe_mkdir(const char *base_path, char *path, int mode)
char * ast_escape_alloc(const char *s, const char *to_escape)
Escape the 'to_escape' characters in the given string.
Standard Command Line Interface.
#define DO_CRASH_NORETURN
char * ast_process_quotes_and_slashes(char *start, char find, char replace_with)
Process a string to find and replace characters.
static struct ast_threadstorage thread_user_interface_tl
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define AST_STACKSIZE_LOW
int ast_check_ipv6(void)
Test that an OS supports IPv6 Networking.
static void utils_shutdown(void)
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
void DO_CRASH_NORETURN __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function)
int SHA1Result(SHA1Context *, uint8_t Message_Digest[SHA1HashSize])
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
void ast_enable_packet_fragmentation(int sock)
Disable PMTU discovery on a socket.
char * ast_base64encode_string(const char *src)
Encode to BASE64 and return encoded string.
int __ast_fd_set_flags(int fd, int flags, enum ast_fd_flag_operation op, const char *file, int lineno, const char *function)
#define pthread_mutex_unlock
void ast_mark_lock_failed(void *lock_addr)
int ast_xml_escape(const char *string, char *const outbuf, const size_t buflen)
Escape reserved characters for use in XML.
int ast_wait_for_output(int fd, int ms)
void ast_set_default_eid(struct ast_eid *eid)
Fill in an ast_eid with the default eid of this machine.
static struct ast_threadstorage inet_ntoa_buf
static struct hostent * hp
int ast_thread_user_interface_set(int is_user_interface)
Set the current thread's user interface status.
int SHA1Reset(SHA1Context *)
SHA1Reset.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
#define AST_MUTEX_DEFINE_STATIC(mutex)
Structure for mutex and tracking information.
char * ast_escape(char *dest, const char *s, size_t size, const char *to_escape)
Escape the 'to_escape' characters in the given string.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
#define ast_mutex_unlock(a)
#define AST_URI_LEGACY_SPACE
#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)