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 85 #if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6) 97 static int gethostbyname_r (
const char *
name,
struct hostent *ret,
char *
buf,
98 size_t buflen,
struct hostent **
result,
114 int naddr = 0, naliases = 0;
118 for (p = ph->h_addr_list; *p != 0; p++) {
119 nbytes += ph->h_length;
120 nbytes +=
sizeof(*p);
123 nbytes +=
sizeof(*p);
126 for (p = ph->h_aliases; *p != 0; p++) {
127 nbytes += (strlen(*p)+1);
128 nbytes +=
sizeof(*p);
131 nbytes +=
sizeof(*p);
135 if (nbytes > buflen) {
158 ret->h_addr_list = q;
159 pbuf = buf + ((naddr + naliases + 2) *
sizeof(*p));
160 for (p = ph->h_addr_list; *p != 0; p++) {
161 memcpy(pbuf, *p, ph->h_length);
163 pbuf += ph->h_length;
169 for (p = ph->h_aliases; *p != 0; p++) {
177 strcpy(pbuf, ph->h_name);
179 pbuf += strlen(ph->h_name);
188 return (*result ==
NULL);
199 #ifndef HAVE_GETHOSTBYNAME_R_5 205 struct hostent *result =
NULL;
214 else if (!isdigit(*s))
223 hp->
hp.h_addrtype = AF_INET;
224 hp->
hp.h_addr_list = (
void *) hp->
buf;
225 hp->
hp.h_addr = hp->
buf +
sizeof(
void *);
228 if (inet_pton(AF_INET, host, hp->
hp.h_addr) > 0)
233 #ifdef HAVE_GETHOSTBYNAME_R_5 234 result = gethostbyname_r(host, &hp->
hp, hp->
buf,
sizeof(hp->
buf), &herrno);
236 if (!result || !hp->
hp.h_addr_list || !hp->
hp.h_addr_list[0])
239 res = gethostbyname_r(host, &hp->
hp, hp->
buf,
sizeof(hp->
buf), &result, &herrno);
241 if (res || !result || !hp->
hp.h_addr_list || !hp->
hp.h_addr_list[0])
251 unsigned char digest[16];
256 MD5Update(&md5, (
const unsigned char *) input, strlen(input));
259 for (x = 0; x < 16; x++)
260 ptr += sprintf(ptr,
"%02hhx", digest[x]);
269 uint8_t Message_Digest[20];
273 SHA1Input(&sha, (
const unsigned char *) input, strlen(input));
277 for (x = 0; x < 20; x++)
278 ptr += sprintf(ptr,
"%02hhx", Message_Digest[x]);
288 SHA1Input(&sha, (
const unsigned char *) input, strlen(input));
297 unsigned int byte = 0;
298 unsigned int bits = 0;
300 while(*src && *src !=
'=' && (cnt < max)) {
303 byte |= (
b2a[(int)(*src)]) & 0x3f;
311 *dst = (byte >> bits) & 0xff;
326 unsigned char *decoded_string;
332 encoded_len = strlen(src);
333 if (encoded_len > 2 && src[encoded_len - 1] ==
'=') {
335 if (src[encoded_len - 2] ==
'=') {
340 decoded_len = (encoded_len / 4 * 3) - padding;
342 if (!decoded_string) {
347 decoded_string[decoded_len] =
'\0';
349 return (
char *)decoded_string;
357 unsigned int byte = 0;
362 while ((cntin < srclen) && (cnt < max)) {
367 if ((bits == 24) && (cnt + 4 <=
max)) {
368 *dst++ =
base64[(byte >> 18) & 0x3f];
369 *dst++ =
base64[(byte >> 12) & 0x3f];
370 *dst++ =
base64[(byte >> 6) & 0x3f];
371 *dst++ =
base64[byte & 0x3f];
377 if (linebreaks && (cnt < max) && (col == 64)) {
383 if (bits && (cnt + 4 <= max)) {
387 *dst++ =
base64[(byte >> 18) & 0x3f];
388 *dst++ =
base64[(byte >> 12) & 0x3f];
390 *dst++ =
base64[(byte >> 6) & 0x3f];
396 if (linebreaks && (cnt < max)) {
413 char *encoded_string;
419 encoded_len = ((strlen(src) * 4 / 3 + 3) & ~3) + 1;
422 ast_base64encode(encoded_string, (
const unsigned char *)src, strlen(src), encoded_len);
424 return encoded_string;
430 unsigned int byte = 0;
431 unsigned int bits = 0;
433 while (*src && (cnt < max)) {
435 byte |= (
b2a_url[(int)(*src)]) & 0x3f;
440 *dst = (byte >> bits) & 0xff;
451 unsigned char *decoded_string;
457 decoded_len = strlen(src) * 3 / 4;
459 if (!decoded_string) {
464 decoded_string[decoded_len] =
'\0';
466 return (
char *)decoded_string;
473 unsigned int byte = 0;
478 while ((cntin < srclen) && (cnt < max)) {
483 if ((bits == 24) && (cnt + 4 <=
max)) {
493 if (linebreaks && (cnt < max) && (col == 64)) {
499 if (bits && (cnt + 4 <= max)) {
508 if (linebreaks && (cnt < max)) {
524 char *encoded_string;
530 encoded_len = ((strlen(src) * 4 / 3 + 3) & ~3) + 1;
535 return encoded_string;
541 memset(
b2a, -1,
sizeof(
b2a));
544 for (x = 0; x < 26; x++) {
553 b2a[
'a' + x] = x + 26;
559 b2a[
'0' + x] = x + 52;
581 const char *mark =
"-_.!~*'()";
582 const char *user_unreserved =
"&=+$,;?/";
584 while (*ptr && out - outbuf < buflen - 1) {
590 && strchr(mark, *ptr))
592 && ((*ptr >=
'0' && *ptr <=
'9')
593 || (*ptr >=
'A' && *ptr <=
'Z')
594 || (*ptr >=
'a' && *ptr <=
'z')))
596 && strchr(user_unreserved, *ptr))) {
598 if (out - outbuf >= buflen - 3) {
601 out += sprintf(out,
"%%%02hhX", (
unsigned char) *ptr);
621 for (o = s; *s; s++, o++) {
625 }
else if (*s ==
'%' && s[1] !=
'\0' && s[2] !=
'\0' && sscanf(s + 1,
"%2x", &tmp) == 1) {
639 char *allow =
"\t\v !";
641 while (*ptr && out - outbuf < buflen - 1) {
642 if (!(strchr(allow, *ptr))
643 && !(*ptr >=
'#' && *ptr <=
'[')
644 && !(*ptr >=
']' && *ptr <=
'~')
645 && !((
unsigned char) *ptr > 0x7f)) {
647 if (out - outbuf >= buflen - 2) {
650 out += sprintf(out,
"\\%c", (
unsigned char) *ptr);
670 if (
string ==
NULL || outbuf ==
NULL) {
675 while (*ptr && out - outbuf < buflen - 1) {
677 if (out - outbuf >= buflen - 2) {
700 int quote_str_len = strlen(quote_str);
702 for (esc_pos = 0, unesc_pos = 0;
703 esc_pos < quote_str_len;
704 esc_pos++, unesc_pos++) {
705 if (quote_str[esc_pos] ==
'\\') {
708 if (esc_pos >= quote_str_len) {
713 quote_str[unesc_pos] = quote_str[esc_pos];
715 quote_str[unesc_pos] =
'\0';
721 char *
end = outbuf + buflen - 1;
730 while (*
string && dst < end) {
765 if (end - dst < len) {
778 return *
string ==
'\0' ? 0 : -1;
789 return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
795 #undef pthread_create 800 #if !defined(LOW_MEMORY) 802 #define AST_MAX_LOCKS 64 805 #undef pthread_mutex_t 806 #undef pthread_mutex_lock 807 #undef pthread_mutex_unlock 808 #undef pthread_mutex_init 809 #undef pthread_mutex_destroy 874 for (i = 0; i < lock_info->
num_locks; i++) {
882 "Thread '%s' still has a lock! - '%s' (%p) from '%s' in %s:%d!\n",
908 #if !defined(LOW_MEMORY) 917 for (i = 0; i < lock_info->
num_locks; i++) {
930 fprintf(stderr,
"XXX ERROR XXX A thread holds more locks than '%d'." 942 memset(&lock_info->
locks[i], 0,
sizeof(lock_info->
locks[0]));
964 #if !defined(LOW_MEMORY) 980 #if !defined(LOW_MEMORY) 997 #if !defined(LOW_MEMORY) 1006 for (i = lock_info->
num_locks - 1; i >= 0; i--) {
1032 #if !defined(LOW_MEMORY) 1042 for (i = lock_info->
num_locks - 1; i >= 0; i--) {
1061 #if !defined(LOW_MEMORY) 1070 for (i = lock_info->
num_locks - 1; i >= 0; i--) {
1090 #if !defined(LOW_MEMORY) 1099 for (i = lock_info->
num_locks - 1; i >= 0; i--) {
1121 memmove(&lock_info->
locks[i], &lock_info->
locks[i + 1],
1131 #if !defined(LOW_MEMORY) 1149 struct ast_vector_string *symbols;
1163 for (frame_iterator = 1; frame_iterator <
AST_VECTOR_SIZE(symbols); ++frame_iterator) {
1169 ast_str_append(str, 0,
"\tCouldn't retrieve backtrace symbols\n");
1180 ast_str_append(str, 0,
"=== ---> %sLock #%d (%s): %s %d %s %s %p (%d%s)\n",
1182 lock_info->
locks[i].
pending < 0 ?
"Tried and failed to get " :
"", i,
1204 for (j = 0; *str && j < lt->
reentrancy; j++) {
1205 ast_str_append(str, 0,
"=== --- ---> Locked Here: %s line %d (%s)\n",
1233 #if !defined(LOW_MEMORY) 1247 for (i = 0; str && i < lock_info->
num_locks; i++) {
1266 #if !defined(LOW_MEMORY) 1275 "=======================================================================\n" 1277 "=== Currently Held Locks\n" 1278 "=======================================================================\n" 1280 "=== <pending> <lock#> (<file>): <lock type> <line num> <function> <lock name> <lock addr> (times locked)\n" 1290 int header_printed = 0;
1292 for (i = 0; str && i < lock_info->
num_locks; i++) {
1298 if (!header_printed) {
1299 if (lock_info->
lwp != -1) {
1315 if (header_printed) {
1316 ast_str_append(&str, 0,
"=== -------------------------------------------------------------------\n" 1329 ast_str_append(&str, 0,
"=======================================================================\n" 1338 #if !defined(LOW_MEMORY) 1345 e->
command =
"core show locks";
1347 "Usage: core show locks\n" 1348 " This command is for lock debugging. It prints out which locks\n" 1349 "are owned by each active thread.\n";
1375 #if !defined(LOW_MEMORY) 1382 void *(*start_routine)(
void *);
1398 #ifdef DEBUG_THREADS 1400 pthread_mutexattr_t mutex_attr;
1409 pthread_mutexattr_init(&mutex_attr);
1412 pthread_mutexattr_destroy(&mutex_attr);
1430 pthread_cleanup_pop(1);
1439 #if !defined(LOW_MEMORY) 1447 void *data,
size_t stacksize,
const char *
file,
const char *caller,
1448 int line,
const char *start_fn)
1450 #if !defined(LOW_MEMORY) 1456 pthread_attr_init(attr);
1459 #if defined(__linux__) || defined(__FreeBSD__) 1467 if ((
errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
1474 if ((
errno = pthread_attr_setstacksize(attr, stacksize ? stacksize :
AST_STACKSIZE)))
1477 #if !defined(LOW_MEMORY) 1483 start_fn, line, file, caller) < 0) {
1495 void *
data,
size_t stacksize,
const char *
file,
const char *caller,
1496 int line,
const char *start_fn)
1498 unsigned char attr_destroy = 0;
1503 pthread_attr_init(attr);
1507 if ((
errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
1511 stacksize, file, caller, line, start_fn);
1514 pthread_attr_destroy(attr);
1521 struct pollfd pfd[1];
1523 memset(pfd, 0,
sizeof(pfd));
1525 pfd[0].events = POLLIN | POLLPRI;
1531 struct pollfd pfd[1];
1533 memset(pfd, 0,
sizeof(pfd));
1535 pfd[0].events = POLLOUT;
1541 struct pollfd pfd = {
1550 while ((res =
ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
1554 ast_debug(1,
"Timed out trying to write\n");
1557 }
else if (res == -1) {
1562 if (elapsed >= timeoutms) {
1575 if (elapsed >= timeoutms) {
1603 res = write(fd, s, len);
1605 if (res < 0 &&
errno != EAGAIN &&
errno != EINTR) {
1607 if (
errno == EPIPE) {
1609 ast_debug(1,
"write() failed due to reading end being closed: %s\n", strerror(
errno));
1628 if (elapsed >= timeoutms) {
1645 if ((q = strchr(beg_quotes, *s)) && *q !=
'\0') {
1646 e = s + strlen(s) - 1;
1647 if (*e == *(end_quotes + (q - beg_quotes))) {
1668 memset(stack, 0,
sizeof(stack));
1670 for(is = st; *is; is++) {
1672 if (*++is !=
'\0') {
1679 if (*is ==
'\'' || *is ==
'"') {
1680 if (*is == stack[inquote]) {
1681 stack[inquote--] =
'\0';
1683 if (++inquote >=
sizeof(stack)) {
1686 stack[inquote] = *is;
1690 if (*is == sep && !inquote) {
1721 while ((e = strchr(work,
';'))) {
1722 if ((e > work) && (*(e-1) ==
'\\')) {
1723 memmove(e - 1, e, strlen(e) + 1);
1741 for (ret = dst = src; (c = *src++); *dst++ =
c ) {
1744 switch ((c = *src++)) {
1775 '\a',
'\b',
'\f',
'\n',
'\r',
'\t',
'\v',
'\\',
'\'',
'\"',
'\?',
'\0' 1783 'a',
'b',
'f',
'n',
'r',
't',
'v',
'\\',
'\'',
'"',
'?',
'\0' 1786 char *
ast_escape(
char *dest,
const char *s,
size_t size,
const char *to_escape)
1791 if (!dest || !size) {
1804 for (p = dest; *s && --size; ++s, ++p) {
1806 if (strchr(to_escape, *s)) {
1817 c = strchr(escape_sequences, *s);
1839 if (!dest || !size) {
1847 for (p = dest; *s && --size; ++s, ++p) {
1852 c = strchr(escape_sequences, *s);
1880 *size = strlen(s) * 2 + 1;
1904 if (!buffer || !*buffer || !space || !*space)
1907 result = vsnprintf(*buffer, *space, fmt, ap);
1911 else if (result > *space)
1933 int regex_len = strlen(regex_string);
1937 if ((regex_len >= 1) && (regex_string[0] ==
'/')) {
1938 ast_str_set(regex_pattern, 0,
"%s", regex_string + 1);
1943 if ((regex_len > 1) && (regex_string[regex_len - 1] ==
'/')) {
1957 if (!strcasecmp(s,
"yes") ||
1958 !strcasecmp(s,
"true") ||
1959 !strcasecmp(s,
"y") ||
1960 !strcasecmp(s,
"t") ||
1961 !strcasecmp(s,
"1") ||
1962 !strcasecmp(s,
"on"))
1974 if (!strcasecmp(s,
"no") ||
1975 !strcasecmp(s,
"false") ||
1976 !strcasecmp(s,
"n") ||
1977 !strcasecmp(s,
"f") ||
1978 !strcasecmp(s,
"0") ||
1979 !strcasecmp(s,
"off"))
1985 #define ONE_MILLION 1000000 1990 static struct timeval
tvfix(struct timeval
a)
1994 (
long)
a.tv_sec, (
long int)
a.tv_usec);
1997 }
else if (
a.tv_usec < 0) {
1999 (
long)
a.tv_sec, (
long int)
a.tv_usec);
2010 a.tv_sec +=
b.tv_sec;
2011 a.tv_usec +=
b.tv_usec;
2024 a.tv_sec -=
b.tv_sec;
2025 a.tv_usec -=
b.tv_usec;
2026 if (a.tv_usec < 0) {
2051 int durh, durm, durs;
2052 durh = duration / 3600;
2053 durm = (duration % 3600) / 60;
2054 durs = duration % 60;
2055 snprintf(buf, length,
"%02d:%02d:%02d", durh, durm, durs);
2068 if (dev_urandom_fd >= 0) {
2069 int read_res = read(dev_urandom_fd, &res,
sizeof(res));
2071 long int rm = RAND_MAX;
2072 res = res < 0 ? ~res : res;
2106 char *dataPut = start;
2110 for (; *start; start++) {
2112 *dataPut++ = *start;
2115 if (*start ==
'\\') {
2117 }
else if (*start ==
'\'') {
2118 inQuotes = 1 - inQuotes;
2121 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
2125 if (start != dataPut)
2138 for (x = 0; ofs < len && x < size && w[x] ; x++) {
2141 for (src = w[x]; *src && ofs <
len; src++)
2152 char *front, *back, *buf = res;
2155 front = strtok_r(buf, delim, &back);
2158 size = strlen(front);
2159 *front = toupper(*front);
2162 front = strtok_r(
NULL, delim, &back);
2171 int ast_get_timeval(
const char *src,
struct timeval *dst,
struct timeval _default,
int *consumed)
2173 long double dtv = 0.0;
2185 if (sscanf(src,
"%30Lf%n", &dtv, &scanned) > 0) {
2187 dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
2189 *consumed = scanned;
2212 if (sscanf(src,
"%30ld%n", &t, &scanned) == 1) {
2215 *consumed = scanned;
2223 #if defined(HAVE_IP_MTU_DISCOVER) 2224 int val = IP_PMTUDISC_DONT;
2226 if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val,
sizeof(val)))
2227 ast_log(
LOG_WARNING,
"Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
2234 int len = strlen(path), count = 0, x, piececount = 0;
2240 for (ptr = tmp; *ptr; ptr++) {
2246 pieces =
ast_alloca(count *
sizeof(*pieces));
2247 for (ptr = tmp; *ptr; ptr++) {
2250 pieces[piececount++] = ptr + 1;
2255 for (x = 0; x < piececount; x++) {
2257 strcat(fullpath,
"/");
2258 strcat(fullpath, pieces[x]);
2259 res = mkdir(fullpath, mode);
2260 if (res &&
errno != EEXIST)
2266 static int safe_mkdir(
const char *base_path,
char *path,
int mode)
2270 absolute_path = realpath(path,
NULL);
2272 if (absolute_path) {
2284 char *path_term = strchr(path,
'/');
2286 int parent_is_safe = 0;
2293 char c = *(path_term + 1);
2294 *(path_term + 1) =
'\0';
2295 absolute_subpath = realpath(path,
NULL);
2297 if (absolute_subpath) {
2300 absolute_subpath, base_path);
2301 }
else if (parent_is_safe) {
2304 res = mkdir(path, mode);
2316 *(path_term + 1) = c;
2318 path_term = strchr(path_term + 1,
'/');
2322 if (!parent_is_safe) {
2327 res = mkdir(path, mode);
2328 if (res != 0 &&
errno != EEXIST) {
2341 if (base_path ==
NULL || path ==
NULL) {
2352 absolute_base_path = realpath(base_path,
NULL);
2353 if (absolute_base_path ==
NULL) {
2357 return safe_mkdir(absolute_base_path, p, mode);
2362 close(dev_urandom_fd);
2363 dev_urandom_fd = -1;
2364 #if defined(DEBUG_THREADS) && !defined(LOW_MEMORY) 2371 dev_urandom_fd = open(
"/dev/urandom", O_RDONLY);
2373 #ifdef DEBUG_THREADS 2374 #if !defined(LOW_MEMORY) 2400 {
"realm=", &d->
realm },
2401 {
"nonce=", &d->
nonce },
2402 {
"uri=", &d->
uri },
2403 {
"domain=", &d->
domain },
2405 {
"cnonce=", &d->
cnonce },
2406 {
"opaque=", &d->
opaque },
2408 {
"algorithm=",
NULL },
2423 if (strncasecmp(c,
"Digest ", strlen(
"Digest "))) {
2428 c += strlen(
"Digest ");
2433 for (i = keys; i->key !=
NULL; i++) {
2434 char *src, *separator;
2436 if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
2441 c += strlen(i->key);
2458 if (!strcasecmp(i->key,
"algorithm=")) {
2459 if (strcasecmp(src,
"MD5")) {
2464 }
else if (!strcasecmp(i->key,
"qop=") && !strcasecmp(src,
"auth")) {
2466 }
else if (!strcasecmp(i->key,
"nc=")) {
2468 if (sscanf(src,
"%30lx", &u) != 1) {
2478 if (i->key ==
NULL) {
2507 #if defined (__linux) && defined(SYS_gettid) 2508 ret = syscall(SYS_gettid);
2509 #elif defined(__sun) 2510 ret = pthread_self();
2511 #elif defined(__APPLE__) 2512 ret = mach_thread_self();
2513 mach_port_deallocate(mach_task_self(), ret);
2514 #elif defined(__FreeBSD__) && defined(HAVE_SYS_THR_H) 2524 const char *envPATH = getenv(
"PATH");
2531 while ((path =
strsep(&tpath,
":"))) {
2532 snprintf(fullpath, fullpath_size,
"%s/%s", path, binary);
2533 if (!stat(fullpath, &unused)) {
2542 int udp6_socket = socket(AF_INET6, SOCK_DGRAM, 0);
2544 if (udp6_socket < 0) {
2554 #if defined(DO_CRASH) 2570 fprintf(stderr,
"FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
2571 condition_str, condition, line,
function, file);
2573 condition_str, condition);
2592 if (s && (maxlen > 0)) {
2596 for (x = 0; x < 5; x++) {
2597 sprintf(s,
"%02hhx:", eid->
eid[x]);
2600 sprintf(s,
"%02hhx", eid->
eid[5]);
2605 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__Darwin__) 2606 #include <ifaddrs.h> 2607 #include <net/if_dl.h> 2611 struct ifaddrs *ifap, *ifaphead;
2613 const struct sockaddr_dl *sdl;
2617 unsigned char empty_mac[6] = {0, 0, 0, 0, 0, 0};
2618 unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2620 rtnerr = getifaddrs(&ifaphead);
2623 "You will have to set it manually.\n");
2629 "You will have to set it manually.\n");
2633 for (ifap = ifaphead; ifap; ifap = ifap->ifa_next) {
2634 if (ifap->ifa_addr->sa_family != AF_LINK) {
2638 sdl = (
const struct sockaddr_dl *) ifap->ifa_addr;
2639 ap = ((caddr_t) ((sdl)->sdl_data + (sdl)->sdl_nlen));
2640 alen = sdl->sdl_alen;
2641 if (alen != 6 || !(memcmp(ap, &empty_mac, 6) && memcmp(ap, &full_mac, 6))) {
2645 memcpy(eid, ap,
sizeof(*eid));
2646 ast_debug(1,
"Seeding global EID '%s'\n",
2648 freeifaddrs(ifaphead);
2653 "You will have to set it manually.\n");
2654 freeifaddrs(ifaphead);
2659 #elif defined(SOLARIS) 2660 #include <sys/sockio.h> 2661 #include <net/if_arp.h> 2667 struct lifreq *ifr =
NULL;
2671 struct sockaddr_in *sa, *sa2;
2675 unsigned char empty_mac[6] = {0, 0, 0, 0, 0, 0};
2676 unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2678 s = socket(AF_INET, SOCK_STREAM, 0);
2681 " You will have to set it manually.\n");
2686 ifn.lifn_family = AF_UNSPEC;
2689 if (ioctl(s, SIOCGLIFNUM, &ifn) < 0) {
2691 " You will have to set it manually.\n");
2696 bufsz = ifn.lifn_count *
sizeof(
struct lifreq);
2699 "You will have to set it manually.\n");
2703 memset(buf, 0, bufsz);
2706 ifc.lifc_len = bufsz;
2708 ifc.lifc_family = AF_UNSPEC;
2710 if (ioctl(s, SIOCGLIFCONF, &ifc) < 0) {
2712 "You will have to set it manually.\n");
2718 for (ifr = (
struct lifreq *)buf, x = 0; x < ifn.lifn_count; ifr++, x++) {
2721 sa = (
struct sockaddr_in *)&(ifr->lifr_addr);
2722 sa2 = (
struct sockaddr_in *)&(ar.arp_pa);
2725 if(ioctl(s, SIOCGARP, &ar) >= 0) {
2726 p = (
unsigned char *)&(ar.arp_ha.sa_data);
2727 if (!(memcmp(p, &empty_mac, 6) && memcmp(p, &full_mac, 6))) {
2731 memcpy(eid, p,
sizeof(*eid));
2732 ast_debug(1,
"Seeding global EID '%s'\n",
2741 "You will have to set it manually.\n");
2758 int bufsz, num_interfaces;
2759 unsigned char empty_mac[6] = {0, 0, 0, 0, 0, 0};
2760 unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2762 s = socket(AF_INET, SOCK_STREAM, 0);
2765 "You will have to set it manually.\n");
2771 if (ioctl(s, SIOCGIFCONF, &ifc) || ifc.ifc_len <= 0) {
2773 "You will have to set it manually.\n");
2777 bufsz = ifc.ifc_len;
2781 "You will have to set it manually.\n");
2787 if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
2788 ast_log(
LOG_WARNING,
"Unable to retrieve ethernet interfaces for seeding global EID. " 2789 "You will have to set it manually.\n");
2796 num_interfaces = ifc.ifc_len /
sizeof(*ifr);
2798 for (i = 0; i < num_interfaces; i++) {
2800 if (!ioctl(s, SIOCGIFHWADDR, ifr)) {
2801 unsigned char *hwaddr = (
unsigned char *) ifr->ifr_hwaddr.sa_data;
2803 if (!(memcmp(hwaddr, &empty_mac, 6) && memcmp(hwaddr, &full_mac, 6))) {
2807 memcpy(eid, hwaddr,
sizeof(*eid));
2808 ast_debug(1,
"Seeding global EID '%s' from '%s' using 'siocgifhwaddr'\n",
2817 "You will have to set it manually.\n");
2827 unsigned int eid_int[6];
2830 if (sscanf(s,
"%2x:%2x:%2x:%2x:%2x:%2x", &eid_int[0], &eid_int[1], &eid_int[2],
2831 &eid_int[3], &eid_int[4], &eid_int[5]) != 6) {
2835 for (x = 0; x < 6; x++) {
2836 eid->
eid[x] = eid_int[x];
2844 return memcmp(eid1, eid2,
sizeof(*eid1));
2851 memset(&empty_eid, 0,
sizeof(empty_eid));
2852 return memcmp(eid, &empty_eid,
sizeof(empty_eid)) ? 0 : 1;
2857 #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) 2858 #if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS) 2859 #define eaccess euidaccess 2861 return eaccess(filename, R_OK) == 0;
2863 int fd = open(filename, O_RDONLY | O_NONBLOCK);
2874 unsigned int major[2] = { 0 };
2875 unsigned int minor[2] = { 0 };
2876 unsigned int patch[2] = { 0 };
2877 unsigned int extra[2] = { 0 };
2880 sscanf(version1,
"%u.%u.%u.%u", &major[0], &minor[0], &patch[0], &extra[0]);
2881 sscanf(version2,
"%u.%u.%u.%u", &major[1], &minor[1], &patch[1], &extra[1]);
2883 res = major[0] - major[1];
2887 res = minor[0] - minor[1];
2891 res = patch[0] - patch[1];
2895 return extra[0] - extra[1];
2899 const char *
file,
int lineno,
const char *
function)
2903 f = fcntl(fd, F_GETFL);
2906 "Failed to get fcntl() flags for file descriptor: %s\n", strerror(
errno));
2912 if ((f & flags) == flags) {
2930 f = fcntl(fd, F_SETFL, f);
2933 "Failed to set fcntl() flags for file descriptor: %s\n", strerror(
errno));
2940 #ifndef HAVE_SOCK_NONBLOCK 2943 int s = socket(domain, type, protocol);
2960 int p = pipe(filedes);
2983 int *thread_user_interface;
2987 if (thread_user_interface ==
NULL) {
2988 ast_log(
LOG_ERROR,
"Error setting user interface status for current thread\n");
2992 *thread_user_interface = !!is_user_interface;
2998 int *thread_user_interface;
3002 if (thread_user_interface ==
NULL) {
3008 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.
#define AST_MAX_LOCKS
A reasonable maximum number of locks a thread would be holding ...
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.
struct thr_lock_info::@431 locks[AST_MAX_LOCKS]
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
static void append_lock_information(struct ast_str **str, struct thr_lock_info *lock_info, int i)
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.
void ast_mark_lock_failed(void *lock_addr)
Mark the last lock as failed (trylock)
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.
static struct ast_threadstorage thread_lock_info
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)
void ast_mark_lock_acquired(void *lock_addr)
Mark the last lock as acquired.
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 ast_lock_track * track
#define ast_strlen_zero(foo)
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.
static char * handle_show_locks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
int ast_base64url_encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
Same as ast_base64encode_full but for base64 URL.
const struct ast_flags ast_uri_http
Configuration File Parser.
#define pthread_mutex_destroy
struct thr_lock_info::@432 entry
#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.
void ast_restore_lock_info(void *lock_addr)
#define AST_URI_UNRESERVED
char * ast_base64url_encode_string(const char *src)
Encode string in base64 URL.
void ast_store_lock_info(enum ast_lock_type type, const char *filename, int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
Store lock info for the current thread.
void ast_unregister_thread(void *id)
static ast_mutex_t lock_infos_lock
Locked when accessing the lock_infos list.
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
struct ast_bt * backtrace
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)
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)
retrieve lock info for the specified mutex
static char base64url[64]
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 ast_reentrancy_lock(struct ast_lock_track *lt)
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.
static void ast_reentrancy_unlock(struct ast_lock_track *lt)
#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]
static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt)
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.
A list of each thread's lock info.
char * ast_to_camel_case_delim(const char *s, const char *delim)
static const char * locktype2str(enum ast_lock_type type)
const ast_string_field nonce
int ast_base64url_decode(unsigned char *dst, const char *src, int max)
Decode data from base64 URL.
#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.
void ast_suspend_lock_info(void *lock_addr)
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)
Keep track of which locks a thread holds.
char * ast_base64url_decode_string(const char *src)
Decode string from base64 URL.
static void lock_info_destroy(void *data)
Destroy a thread's lock info.
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
struct ast_str * ast_dump_locks(void)
Generate a lock dump equivalent to "core show locks".
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_cli_entry utils_cli[]
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.
void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt)
remove lock info for the current thread
void ast_log_show_lock(void *this_lock_addr)
log info for the current lock with ast_log().
#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)
int ast_base64url_encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64 URL.