35#include <sys/syscall.h>
39#elif defined(__FreeBSD__)
41#elif defined(__NetBSD__)
87#if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6)
99static int gethostbyname_r (
const char *
name,
struct hostent *ret,
char *
buf,
100 size_t buflen,
struct hostent **
result,
116 int naddr = 0, naliases = 0;
120 for (p = ph->h_addr_list; *p != 0; p++) {
121 nbytes += ph->h_length;
122 nbytes +=
sizeof(*p);
125 nbytes +=
sizeof(*p);
128 for (p = ph->h_aliases; *p != 0; p++) {
129 nbytes += (strlen(*p)+1);
130 nbytes +=
sizeof(*p);
133 nbytes +=
sizeof(*p);
137 if (nbytes > buflen) {
160 ret->h_addr_list = q;
161 pbuf =
buf + ((naddr + naliases + 2) *
sizeof(*p));
162 for (p = ph->h_addr_list; *p != 0; p++) {
163 memcpy(pbuf, *p, ph->h_length);
165 pbuf += ph->h_length;
171 for (p = ph->h_aliases; *p != 0; p++) {
179 strcpy(pbuf, ph->h_name);
181 pbuf += strlen(ph->h_name);
201#ifndef HAVE_GETHOSTBYNAME_R_5
216 else if (!isdigit(*s))
225 hp->
hp.h_addrtype = AF_INET;
226 hp->
hp.h_addr_list = (
void *) hp->
buf;
227 hp->
hp.h_addr = hp->
buf +
sizeof(
void *);
230 if (inet_pton(AF_INET, host, hp->
hp.h_addr) > 0)
235#ifdef HAVE_GETHOSTBYNAME_R_5
236 result = gethostbyname_r(host, &hp->
hp, hp->
buf,
sizeof(hp->
buf), &herrno);
238 if (!
result || !hp->
hp.h_addr_list || !hp->
hp.h_addr_list[0])
241 res = gethostbyname_r(host, &hp->
hp, hp->
buf,
sizeof(hp->
buf), &
result, &herrno);
243 if (res || !
result || !hp->
hp.h_addr_list || !hp->
hp.h_addr_list[0])
253 unsigned char digest[16];
258 MD5Update(&
md5, (
const unsigned char *) input, strlen(input));
261 for (x = 0; x < 16; x++)
262 ptr += sprintf(ptr,
"%02hhx", digest[x]);
271 uint8_t Message_Digest[20];
275 SHA1Input(&sha, (
const unsigned char *) input, strlen(input));
279 for (x = 0; x < 20; x++)
280 ptr += sprintf(ptr,
"%02hhx", Message_Digest[x]);
290 SHA1Input(&sha, (
const unsigned char *) input, strlen(input));
299 unsigned int byte = 0;
300 unsigned int bits = 0;
301 while(*src && *src !=
'=' && (cnt <
max)) {
304 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;
573#define BASELINELEN 72
574#define BASEMAXINLINE 256
616 if (!
inbuf(bio, fi)) {
630 if (fputs(endl, so) == EOF) {
637 if (putc(((
unsigned char)
c), so) == EOF) {
648 static const unsigned char dtable[] = {
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
649 'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
'a',
'b',
'c',
'd',
'e',
'f',
650 'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
'0',
651 '1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'+',
'/'};
655 memset(&bio, 0,
sizeof(bio));
659 unsigned char igroup[3], ogroup[4];
662 memset(igroup, 0,
sizeof(igroup));
664 for (n = 0; n < 3; n++) {
665 if ((
c =
inchar(&bio, inputfile)) == EOF) {
670 igroup[n] = (
unsigned char)
c;
674 ogroup[0]= dtable[igroup[0] >> 2];
675 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
676 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
677 ogroup[3]= dtable[igroup[2] & 0x3F];
687 for (i = 0; i < 4; i++) {
688 ochar(&bio, ogroup[i], outputfile, endl);
693 if (fputs(endl, outputfile) == EOF) {
705 if (!(fi = fopen(filename,
"rb"))) {
725 const char *mark =
"-_.!~*'()";
726 const char *user_unreserved =
"&=+$,;?/";
728 while (*ptr &&
out - outbuf < buflen - 1) {
734 && strchr(mark, *ptr))
736 && ((*ptr >=
'0' && *ptr <=
'9')
737 || (*ptr >=
'A' && *ptr <=
'Z')
738 || (*ptr >=
'a' && *ptr <=
'z')))
740 && strchr(user_unreserved, *ptr))) {
742 if (
out - outbuf >= buflen - 3) {
745 out += sprintf(
out,
"%%%02hhX", (
unsigned char) *ptr);
765 for (o = s; *s; s++, o++) {
769 }
else if (*s ==
'%' && s[1] !=
'\0' && s[2] !=
'\0' && sscanf(s + 1,
"%2x", &tmp) == 1) {
789 length = strlen(
string);
790 endl = (
char *)
string + length;
796 if (ptr + 2 >= endl) {
800 if (sscanf(ptr + 1,
"%2x", &tmp) != 1) {
805 }
else if (!isalnum((
unsigned char ) *ptr) && !strchr(
"-_.+", *ptr)) {
819 char *allow =
"\t\v !";
821 while (*ptr &&
out - outbuf < buflen - 1) {
822 if (!(strchr(allow, *ptr))
823 && !(*ptr >=
'#' && *ptr <=
'[')
824 && !(*ptr >=
']' && *ptr <=
'~')
825 && !((
unsigned char) *ptr > 0x7f)) {
827 if (
out - outbuf >= buflen - 2) {
830 out += sprintf(
out,
"\\%c", (
unsigned char) *ptr);
850 if (
string ==
NULL || outbuf ==
NULL) {
855 while (*ptr &&
out - outbuf < buflen - 1) {
857 if (
out - outbuf >= buflen - 2) {
880 int quote_str_len = strlen(quote_str);
882 for (esc_pos = 0, unesc_pos = 0;
883 esc_pos < quote_str_len;
884 esc_pos++, unesc_pos++) {
885 if (quote_str[esc_pos] ==
'\\') {
888 if (esc_pos >= quote_str_len) {
893 quote_str[unesc_pos] = quote_str[esc_pos];
895 quote_str[unesc_pos] =
'\0';
901 char *
end = outbuf + buflen - 1;
910 while (*
string && dst <
end) {
911 const char *entity =
NULL;
958 return *
string ==
'\0' ? 0 : -1;
969 return inet_ntop(AF_INET, &ia,
buf, INET_ADDRSTRLEN);
980#if !defined(LOW_MEMORY)
982#define AST_MAX_LOCKS 64
985#undef pthread_mutex_t
986#undef pthread_mutex_lock
987#undef pthread_mutex_unlock
988#undef pthread_mutex_init
989#undef pthread_mutex_destroy
996struct thr_lock_info {
1000 const char *thread_name;
1005 const char *lock_name;
1008 int times_lock_attempted;
1009 struct timeval last_locked;
1010 struct timeval last_unlocked;
1018 struct ast_bt *backtrace;
1020 } locks[AST_MAX_LOCKS];
1024 unsigned int num_locks;
1047static void lock_info_destroy(
void *data)
1057 for (i = 0; i <
lock_info->num_locks; i++) {
1058 if (
lock_info->locks[i].pending == -1) {
1065 "Thread '%s' still has a lock! - '%s' (%p) from '%s' in %s:%d!\n",
1089 int line_num,
const char *func,
const char *lock_name,
void *lock_addr,
struct ast_bt *bt)
1091#if !defined(LOW_MEMORY)
1100 for (i = 0; i <
lock_info->num_locks; i++) {
1101 if (
lock_info->locks[i].lock_addr == lock_addr) {
1103 lock_info->locks[i].times_lock_attempted++;
1113 if (
lock_info->num_locks == AST_MAX_LOCKS) {
1115 fprintf(stderr,
"XXX ERROR XXX A thread holds more locks than '%d'."
1116 " Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
1121 if (i &&
lock_info->locks[i - 1].pending == -1) {
1131 lock_info->locks[i].line_num = line_num;
1133 lock_info->locks[i].lock_name = lock_name;
1134 lock_info->locks[i].lock_addr = lock_addr;
1136 lock_info->locks[i].times_lock_attempted = 1;
1149void ast_mark_lock_acquired(
void *lock_addr)
1151#if !defined(LOW_MEMORY)
1167#if !defined(LOW_MEMORY)
1183int 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)
1185#if !defined(LOW_MEMORY)
1194 for (i =
lock_info->num_locks - 1; i >= 0; i--) {
1195 if (
lock_info->locks[i].lock_addr == lock_addr)
1218void ast_suspend_lock_info(
void *lock_addr)
1220#if !defined(LOW_MEMORY)
1230 for (i =
lock_info->num_locks - 1; i >= 0; i--) {
1231 if (
lock_info->locks[i].lock_addr == lock_addr)
1247void ast_restore_lock_info(
void *lock_addr)
1249#if !defined(LOW_MEMORY)
1258 for (i =
lock_info->num_locks - 1; i >= 0; i--) {
1259 if (
lock_info->locks[i].lock_addr == lock_addr)
1276void ast_remove_lock_info(
void *lock_addr,
struct ast_bt *bt)
1278#if !defined(LOW_MEMORY)
1287 for (i =
lock_info->num_locks - 1; i >= 0; i--) {
1288 if (
lock_info->locks[i].lock_addr == lock_addr)
1298 if (
lock_info->locks[i].times_locked > 1) {
1308 if (i < lock_info->num_locks - 1) {
1320#if !defined(LOW_MEMORY)
1336static void append_backtrace_information(
struct ast_str **
str,
struct ast_bt *bt)
1352 for (frame_iterator = 1; frame_iterator <
AST_VECTOR_SIZE(symbols); ++frame_iterator) {
1363static void append_lock_information(
struct ast_str **
str,
struct thr_lock_info *
lock_info,
int i)
1368 struct timeval held_for;
1370 char lock_time[32], unlock_time[32], held_time[32];
1375 lock_time,
sizeof(lock_time));
1377 unlock_time,
sizeof(unlock_time));
1381 "=== %s.%06ld, %s.%06ld, %s.%06ld (%d, %d%s)\n",
1382 lock_info->locks[i].pending > 0 ?
"Waiting for " :
1383 lock_info->locks[i].pending < 0 ?
"Tried and failed to get " :
"", i,
1391 lock_info->locks[i].last_locked.tv_usec,
1393 lock_info->locks[i].last_unlocked.tv_usec,
1397 lock_info->locks[i].times_lock_attempted,
1398 lock_info->locks[i].suspended ?
" - suspended" :
"");
1400 append_backtrace_information(
str,
lock_info->locks[i].backtrace);
1412 ast_reentrancy_lock(lt);
1417 ast_reentrancy_unlock(lt);
1440void ast_log_show_lock(
void *this_lock_addr)
1442#if !defined(LOW_MEMORY)
1459 if (
lock_info->locks[i].lock_addr == this_lock_addr) {
1473struct ast_str *ast_dump_locks(
void)
1475#if !defined(LOW_MEMORY)
1478 char print_time[32];
1488 "=======================================================================\n"
1490 "=== Currently Held Locks at Time: %s.%06ld =================\n"
1491 "=======================================================================\n"
1493 "=== <pending> <lock#> (<file>): <lock type> <line num> <function> <lock name> <lock addr>\n"
1494 "=== <locked at>, <failed at>, <held for> (attempts, times locked)\n"
1503 int header_printed = 0;
1511 if (!header_printed) {
1528 if (header_printed) {
1529 ast_str_append(&
str, 0,
"=== -------------------------------------------------------------------\n"
1542 ast_str_append(&
str, 0,
"=======================================================================\n"
1551#if !defined(LOW_MEMORY)
1558 e->
command =
"core show locks";
1560 "Usage: core show locks\n"
1561 " This command is for lock debugging. It prints out which locks\n"
1562 "are owned by each active thread.\n";
1570 str = ast_dump_locks();
1583 AST_CLI_DEFINE(handle_show_locks,
"Show which locks are held by which thread"),
1588#if !defined(LOW_MEMORY)
1595 void *(*start_routine)(
void *);
1613 pthread_mutexattr_t mutex_attr;
1622 pthread_mutexattr_init(&mutex_attr);
1625 pthread_mutexattr_destroy(&mutex_attr);
1641 ret =
a.start_routine(
a.data);
1643 pthread_cleanup_pop(1);
1652#if !defined(LOW_MEMORY)
1660 void *data,
size_t stacksize,
const char *file,
const char *caller,
1661 int line,
const char *start_fn)
1663#if !defined(LOW_MEMORY)
1669 pthread_attr_init(attr);
1672#if defined(__linux__) || defined(__FreeBSD__)
1680 if ((
errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
1687 if ((
errno = pthread_attr_setstacksize(attr, stacksize ? stacksize :
AST_STACKSIZE)))
1690#if !defined(LOW_MEMORY)
1696 start_fn, line, file, caller) < 0) {
1708 void *
data,
size_t stacksize,
const char *file,
const char *caller,
1709 int line,
const char *start_fn)
1711 unsigned char attr_destroy = 0;
1716 pthread_attr_init(attr);
1720 if ((
errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
1724 stacksize, file, caller, line, start_fn);
1727 pthread_attr_destroy(attr);
1734 struct pollfd pfd[1];
1736 memset(pfd, 0,
sizeof(pfd));
1738 pfd[0].events = POLLIN | POLLPRI;
1744 struct pollfd pfd[1];
1746 memset(pfd, 0,
sizeof(pfd));
1748 pfd[0].events = POLLOUT;
1754 struct pollfd pfd = {
1763 while ((res =
ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
1767 ast_debug(1,
"Timed out trying to write\n");
1770 }
else if (res == -1) {
1775 if (elapsed >= timeoutms) {
1788 if (elapsed >= timeoutms) {
1816 res = write(fd, s,
len);
1818 if (res < 0 &&
errno != EAGAIN &&
errno != EINTR) {
1820 if (
errno == EPIPE) {
1822 ast_debug(1,
"write() failed due to reading end being closed: %s\n", strerror(
errno));
1841 if (elapsed >= timeoutms) {
1858 if ((q = strchr(beg_quotes, *s)) && *q !=
'\0') {
1859 e = s + strlen(s) - 1;
1860 if (*e == *(end_quotes + (q - beg_quotes))) {
1882 memset(stack, 0,
sizeof(stack));
1884 for(is = st; *is; is++) {
1886 if (*++is !=
'\0') {
1893 if (*is ==
'\'' || *is ==
'"') {
1894 if (*is == stack[inquote]) {
1895 stack[inquote--] =
'\0';
1897 if (++inquote >=
sizeof(stack)) {
1900 stack[inquote] = *is;
1904 if (*is == sep && !inquote) {
1940 const char qstr[] = {
quote };
1947 memset(stack, 0,
sizeof(stack));
1949 for(is = st; *is; is++) {
1951 if (*++is !=
'\0') {
1959 if (*is == stack[inquote]) {
1960 stack[inquote--] =
'\0';
1962 if (++inquote >=
sizeof(stack)) {
1965 stack[inquote] = *is;
1969 if (*is == sep && !inquote) {
2003 while ((e = strchr(work,
';'))) {
2004 if ((e > work) && (*(e-1) ==
'\\')) {
2005 memmove(e - 1, e, strlen(e) + 1);
2023 for (ret = dst = src; (
c = *src++); *dst++ =
c ) {
2026 switch ((
c = *src++)) {
2057 '\a',
'\b',
'\f',
'\n',
'\r',
'\t',
'\v',
'\\',
'\'',
'\"',
'\?',
'\0'
2065 'a',
'b',
'f',
'n',
'r',
't',
'v',
'\\',
'\'',
'"',
'?',
'\0'
2068char *
ast_escape(
char *dest,
const char *s,
size_t size,
const char *to_escape)
2073 if (!dest || !size) {
2086 for (p = dest; *s && --size; ++s, ++p) {
2088 if (strchr(to_escape, *s)) {
2121 if (!dest || !size) {
2129 for (p = dest; *s && --size; ++s, ++p) {
2162 *size = strlen(s) * 2 + 1;
2186 if (!buffer || !*buffer || !space || !*space)
2189 result = vsnprintf(*buffer, *space, fmt, ap);
2193 else if (
result > *space)
2215 int regex_len = strlen(regex_string);
2219 if ((regex_len >= 1) && (regex_string[0] ==
'/')) {
2220 ast_str_set(regex_pattern, 0,
"%s", regex_string + 1);
2225 if ((regex_len > 1) && (regex_string[regex_len - 1] ==
'/')) {
2239 if (!strcasecmp(s,
"yes") ||
2240 !strcasecmp(s,
"true") ||
2241 !strcasecmp(s,
"y") ||
2242 !strcasecmp(s,
"t") ||
2243 !strcasecmp(s,
"1") ||
2244 !strcasecmp(s,
"on"))
2256 if (!strcasecmp(s,
"no") ||
2257 !strcasecmp(s,
"false") ||
2258 !strcasecmp(s,
"n") ||
2259 !strcasecmp(s,
"f") ||
2260 !strcasecmp(s,
"0") ||
2261 !strcasecmp(s,
"off"))
2267#define ONE_MILLION 1000000
2276 (
long)
a.tv_sec, (
long int)
a.tv_usec);
2279 }
else if (
a.tv_usec < 0) {
2281 (
long)
a.tv_sec, (
long int)
a.tv_usec);
2292 a.tv_sec +=
b.tv_sec;
2293 a.tv_usec +=
b.tv_usec;
2306 a.tv_sec -=
b.tv_sec;
2307 a.tv_usec -=
b.tv_usec;
2308 if (
a.tv_usec < 0) {
2333 int durh, durm, durs;
2334 durh = duration / 3600;
2335 durm = (duration % 3600) / 60;
2336 durs = duration % 60;
2337 snprintf(
buf, length,
"%02d:%02d:%02d", durh, durm, durs);
2353 long int rm = RAND_MAX;
2354 res = res < 0 ? ~res : res;
2388 char *dataPut = start;
2392 for (; *start; start++) {
2394 *dataPut++ = *start;
2397 if (*start ==
'\\') {
2399 }
else if (*start ==
'\'') {
2400 inQuotes = 1 - inQuotes;
2403 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
2407 if (start != dataPut)
2420 for (x = 0; ofs <
len && x < size && w[x] ; x++) {
2423 for (src = w[x]; *src && ofs <
len; src++)
2434 char *front, *back, *
buf = res;
2437 front = strtok_r(
buf, delim, &back);
2440 size = strlen(front);
2441 *front = toupper(*front);
2444 front = strtok_r(
NULL, delim, &back);
2453int ast_get_timeval(
const char *src,
struct timeval *dst,
struct timeval _default,
int *consumed)
2455 long double dtv = 0.0;
2467 if (sscanf(src,
"%30Lf%n", &dtv, &scanned) > 0) {
2469 dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
2471 *consumed = scanned;
2494 if (sscanf(src,
"%30ld%n", &t, &scanned) == 1) {
2497 *consumed = scanned;
2505#if defined(HAVE_IP_MTU_DISCOVER)
2506 int val = IP_PMTUDISC_DONT;
2508 if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &
val,
sizeof(
val)))
2509 ast_log(
LOG_WARNING,
"Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
2516 int len = strlen(path), count = 0, x, piececount = 0;
2522 for (ptr = tmp; *ptr; ptr++) {
2528 pieces =
ast_alloca(count *
sizeof(*pieces));
2529 for (ptr = tmp; *ptr; ptr++) {
2532 pieces[piececount++] = ptr + 1;
2537 for (x = 0; x < piececount; x++) {
2539 strcat(fullpath,
"/");
2540 strcat(fullpath, pieces[x]);
2541 res = mkdir(fullpath, mode);
2542 if (res &&
errno != EEXIST)
2548static int safe_mkdir(
const char *base_path,
char *path,
int mode)
2552 absolute_path = realpath(path,
NULL);
2554 if (absolute_path) {
2566 char *path_term = strchr(path,
'/');
2568 int parent_is_safe = 0;
2575 char c = *(path_term + 1);
2576 *(path_term + 1) =
'\0';
2577 absolute_subpath = realpath(path,
NULL);
2579 if (absolute_subpath) {
2582 absolute_subpath, base_path);
2583 }
else if (parent_is_safe) {
2586 res = mkdir(path, mode);
2598 *(path_term + 1) =
c;
2600 path_term = strchr(path_term + 1,
'/');
2604 if (!parent_is_safe) {
2609 res = mkdir(path, mode);
2610 if (res != 0 &&
errno != EEXIST) {
2623 if (base_path ==
NULL || path ==
NULL) {
2634 absolute_base_path = realpath(base_path,
NULL);
2635 if (absolute_base_path ==
NULL) {
2639 return safe_mkdir(absolute_base_path, p, mode);
2646#if defined(DEBUG_THREADS) && !defined(LOW_MEMORY)
2656#if !defined(LOW_MEMORY)
2681 {
"username=", &
d->username },
2682 {
"realm=", &
d->realm },
2683 {
"nonce=", &
d->nonce },
2684 {
"uri=", &
d->uri },
2685 {
"domain=", &
d->domain },
2686 {
"response=", &
d->response },
2687 {
"cnonce=", &
d->cnonce },
2688 {
"opaque=", &
d->opaque },
2690 {
"algorithm=",
NULL },
2705 if (strncasecmp(
c,
"Digest ", strlen(
"Digest "))) {
2710 c += strlen(
"Digest ");
2715 for (i =
keys; i->key !=
NULL; i++) {
2716 char *src, *separator;
2718 if (strncasecmp(
c, i->key, strlen(i->key)) != 0) {
2723 c += strlen(i->key);
2740 if (!strcasecmp(i->key,
"algorithm=")) {
2741 if (strcasecmp(src,
"MD5")) {
2746 }
else if (!strcasecmp(i->key,
"qop=") && !strcasecmp(src,
"auth")) {
2748 }
else if (!strcasecmp(i->key,
"nc=")) {
2750 if (sscanf(src,
"%30lx", &u) != 1) {
2760 if (i->key ==
NULL) {
2789#if defined (__linux) && defined(SYS_gettid)
2790 ret = syscall(SYS_gettid);
2792 ret = pthread_self();
2793#elif defined(__APPLE__)
2794 ret = mach_thread_self();
2795 mach_port_deallocate(mach_task_self(), ret);
2796#elif defined(__FreeBSD__)
2800#elif defined(__NetBSD__)
2802#elif defined(__OpenBSD__)
2810 const char *envPATH = getenv(
"PATH");
2817 while ((path =
strsep(&tpath,
":"))) {
2818 snprintf(fullpath, fullpath_size,
"%s/%s", path, binary);
2819 if (!stat(fullpath, &unused)) {
2828 int udp6_socket = socket(AF_INET6, SOCK_DGRAM, 0);
2830 if (udp6_socket < 0) {
2840#if defined(DO_CRASH)
2856 fprintf(stderr,
"FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
2857 condition_str, condition, line, function, file);
2859 condition_str, condition);
2878 if (s && (maxlen > 0)) {
2882 for (x = 0; x < 5; x++) {
2883 sprintf(s,
"%02hhx:", eid->
eid[x]);
2886 sprintf(s,
"%02hhx", eid->
eid[5]);
2891#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__Darwin__)
2893#include <net/if_dl.h>
2897 struct ifaddrs *ifap, *ifaphead;
2899 const struct sockaddr_dl *sdl;
2903 unsigned char empty_mac[6] = {0, 0, 0, 0, 0, 0};
2904 unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2906 rtnerr = getifaddrs(&ifaphead);
2909 "You will have to set it manually.\n");
2915 "You will have to set it manually.\n");
2919 for (ifap = ifaphead; ifap; ifap = ifap->ifa_next) {
2920 if (ifap->ifa_addr->sa_family != AF_LINK) {
2924 sdl = (
const struct sockaddr_dl *) ifap->ifa_addr;
2925 ap = ((caddr_t) ((sdl)->sdl_data + (sdl)->sdl_nlen));
2926 alen = sdl->sdl_alen;
2927 if (alen != 6 || !(memcmp(ap, &empty_mac, 6) && memcmp(ap, &full_mac, 6))) {
2931 memcpy(eid, ap,
sizeof(*eid));
2932 ast_debug(1,
"Seeding global EID '%s'\n",
2934 freeifaddrs(ifaphead);
2939 "You will have to set it manually.\n");
2940 freeifaddrs(ifaphead);
2945#elif defined(SOLARIS)
2946#include <sys/sockio.h>
2947#include <net/if_arp.h>
2953 struct lifreq *ifr =
NULL;
2957 struct sockaddr_in *sa, *sa2;
2961 unsigned char empty_mac[6] = {0, 0, 0, 0, 0, 0};
2962 unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2964 s = socket(AF_INET, SOCK_STREAM, 0);
2967 " You will have to set it manually.\n");
2972 ifn.lifn_family = AF_UNSPEC;
2975 if (ioctl(s, SIOCGLIFNUM, &ifn) < 0) {
2977 " You will have to set it manually.\n");
2982 bufsz = ifn.lifn_count *
sizeof(
struct lifreq);
2985 "You will have to set it manually.\n");
2989 memset(
buf, 0, bufsz);
2992 ifc.lifc_len = bufsz;
2994 ifc.lifc_family = AF_UNSPEC;
2996 if (ioctl(s, SIOCGLIFCONF, &ifc) < 0) {
2998 "You will have to set it manually.\n");
3004 for (ifr = (
struct lifreq *)
buf, x = 0; x < ifn.lifn_count; ifr++, x++) {
3007 sa = (
struct sockaddr_in *)&(ifr->lifr_addr);
3008 sa2 = (
struct sockaddr_in *)&(ar.arp_pa);
3011 if(ioctl(s, SIOCGARP, &ar) >= 0) {
3012 p = (
unsigned char *)&(ar.arp_ha.sa_data);
3013 if (!(memcmp(p, &empty_mac, 6) && memcmp(p, &full_mac, 6))) {
3017 memcpy(eid, p,
sizeof(*eid));
3018 ast_debug(1,
"Seeding global EID '%s'\n",
3027 "You will have to set it manually.\n");
3044 int bufsz, num_interfaces;
3045 unsigned char empty_mac[6] = {0, 0, 0, 0, 0, 0};
3046 unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
3048 s = socket(AF_INET, SOCK_STREAM, 0);
3051 "You will have to set it manually.\n");
3057 if (ioctl(s, SIOCGIFCONF, &ifc) || ifc.ifc_len <= 0) {
3059 "You will have to set it manually.\n");
3063 bufsz = ifc.ifc_len;
3067 "You will have to set it manually.\n");
3073 if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
3074 ast_log(
LOG_WARNING,
"Unable to retrieve ethernet interfaces for seeding global EID. "
3075 "You will have to set it manually.\n");
3082 num_interfaces = ifc.ifc_len /
sizeof(*ifr);
3084 for (i = 0; i < num_interfaces; i++) {
3086 if (!ioctl(s, SIOCGIFHWADDR, ifr)) {
3087 unsigned char *hwaddr = (
unsigned char *) ifr->ifr_hwaddr.sa_data;
3089 if (!(memcmp(hwaddr, &empty_mac, 6) && memcmp(hwaddr, &full_mac, 6))) {
3093 memcpy(eid, hwaddr,
sizeof(*eid));
3094 ast_debug(1,
"Seeding global EID '%s' from '%s' using 'siocgifhwaddr'\n",
3103 "You will have to set it manually.\n");
3113 unsigned int eid_int[6];
3116 if (sscanf(s,
"%2x:%2x:%2x:%2x:%2x:%2x", &eid_int[0], &eid_int[1], &eid_int[2],
3117 &eid_int[3], &eid_int[4], &eid_int[5]) != 6) {
3121 for (x = 0; x < 6; x++) {
3122 eid->
eid[x] = eid_int[x];
3130 return memcmp(eid1, eid2,
sizeof(*eid1));
3143#if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
3144#if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
3145#define eaccess euidaccess
3147 return eaccess(filename,
R_OK) == 0;
3149 int fd = open(filename, O_RDONLY | O_NONBLOCK);
3160 unsigned int major[2] = { 0 };
3161 unsigned int minor[2] = { 0 };
3162 unsigned int patch[2] = { 0 };
3163 unsigned int extra[2] = { 0 };
3166 sscanf(version1,
"%u.%u.%u.%u", &major[0], &minor[0], &patch[0], &extra[0]);
3167 sscanf(version2,
"%u.%u.%u.%u", &major[1], &minor[1], &patch[1], &extra[1]);
3169 res = major[0] - major[1];
3173 res = minor[0] - minor[1];
3177 res = patch[0] - patch[1];
3181 return extra[0] - extra[1];
3185 const char *file,
int lineno,
const char *function)
3189 f = fcntl(fd, F_GETFL);
3192 "Failed to get fcntl() flags for file descriptor: %s\n", strerror(
errno));
3198 if ((f & flags) == flags) {
3216 f = fcntl(fd, F_SETFL, f);
3219 "Failed to set fcntl() flags for file descriptor: %s\n", strerror(
errno));
3226#ifndef HAVE_SOCK_NONBLOCK
3229 int s = socket(domain,
type, protocol);
3246 int p = pipe(filedes);
3269 int *thread_user_interface;
3272 &thread_user_interface_tl,
sizeof(*thread_user_interface));
3273 if (thread_user_interface ==
NULL) {
3274 ast_log(
LOG_ERROR,
"Error setting user interface status for current thread\n");
3278 *thread_user_interface = !!is_user_interface;
3284 int *thread_user_interface;
3287 &thread_user_interface_tl,
sizeof(*thread_user_interface));
3288 if (thread_user_interface ==
NULL) {
3294 return *thread_user_interface;
3299 char *token, *saveptr, *path = getenv(
"PATH");
3312 token = strtok_r(path,
":", &saveptr);
3313 while (token !=
NULL) {
3314 len = snprintf(filename,
sizeof(filename),
"%s/%s", token, cmd);
3315 if (len < 0 || len >=
sizeof(filename)) {
3320 if (access(filename, X_OK) == 0) {
3325 token = strtok_r(
NULL,
":", &saveptr);
void ast_cli_unregister_multiple(void)
Asterisk version information.
const char * ast_get_version(void)
Retrieve the Asterisk version string.
char * strsep(char **str, const char *delims)
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
void ast_std_free(void *ptr)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_calloc(num, len)
A wrapper for calloc()
#define ast_malloc(len)
A wrapper for malloc()
#define ast_bt_free_symbols(string_vector)
#define ast_bt_get_symbols(addresses, num_frames)
static int request(void *obj)
Standard Command Line Interface.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
int ast_cli_allow_at_shutdown(struct ast_cli_entry *e)
Allow a CLI command to be executed while Asterisk is shutting down.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
void ast_mark_lock_failed(void *lock_addr)
static const struct ast_datastore_info lock_info
static int md5(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int quote(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Configuration File Parser.
#define ast_debug(level,...)
Log a DEBUG message.
void ast_log_backtrace(void)
Log a backtrace of the current thread's execution stack to the Asterisk log.
I/O Management (derived from Cheops-NG)
A set of macros to manage forward-linked lists.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#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_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Asterisk locking-related definitions:
#define pthread_mutex_lock
#define ast_mutex_unlock(a)
#define pthread_mutex_unlock
#define pthread_mutex_destroy
#define ast_mutex_lock(a)
#define AST_MUTEX_DEFINE_STATIC(mutex)
#define pthread_mutex_init
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
void MD5Init(struct MD5Context *context)
void MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], struct MD5Context *context)
Wrapper for network related headers, masking differences between various operating systems....
static dundi_eid empty_eid
#define ast_poll(a, b, c)
int SHA1Result(SHA1Context *, uint8_t Message_Digest[SHA1HashSize])
SHA1Result Returns the resulting 160-bit digest.
int SHA1Input(SHA1Context *, const uint8_t *bytes, unsigned int bytecount)
int SHA1Reset(SHA1Context *)
SHA1Reset.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
const char * ast_string_field
#define ast_string_field_ptr_set(x, ptr, data)
Set a field to a simple string value.
String manipulation functions.
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
char *attribute_pure ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
A structure to hold backtrace information. This structure provides an easy means to store backtrace i...
void * addresses[AST_MAX_BT_FRAMES]
descriptor for a cli entry.
An Entity ID is essentially a MAC address, brief and unique.
Structure used to handle boolean flags.
Lock tracking information.
int lineno[AST_MAX_REENTRANCY]
const char * file[AST_MAX_REENTRANCY]
const char * func[AST_MAX_REENTRANCY]
Structure for mutex and tracking information.
Support for dynamic strings.
String vector definitions.
Structure used for base64 encoding.
unsigned char iobuf[BASEMAXINLINE]
void *(* start_routine)(void *)
Definitions to aid in the use of thread local storage.
#define AST_THREADSTORAGE_CUSTOM(a, b, c)
Define a thread storage variable, with custom initialization and cleanup.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
Time-related functions and macros.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
char * ast_to_camel_case_delim(const char *s, const char *delim)
Attempts to convert the given string to camel case using the specified delimiter.
int ast_thread_is_user_interface(void)
Indicates whether the current thread is a user interface.
void ast_unescape_quoted(char *quote_str)
Unescape quotes in a string.
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.
int ast_base64_encode_file(FILE *inputfile, FILE *outputfile, const char *endl)
Performs a base 64 encode algorithm on the contents of a File.
int ast_base64decode(unsigned char *dst, const char *src, int max)
decode BASE64 encoded text
int ast_check_command_in_path(const char *cmd)
Test for the presence of an executable command in $PATH.
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.
static char base64url[64]
static int dev_urandom_fd
int ast_xml_escape(const char *string, char *const outbuf, const size_t buflen)
Escape reserved characters for use in XML.
char * ast_base64url_encode_string(const char *src)
Encode string in base64 URL.
int ast_file_is_readable(const char *filename)
Test that a file exists and is readable by the effective user.
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.
int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
get values from config variables.
int __ast_fd_set_flags(int fd, int flags, enum ast_fd_flag_operation op, const char *file, int lineno, const char *function)
int ast_background_stacksize(void)
char * ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size)
Resolve a binary to a full pathname.
char * ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec)
Turn text string to URI-encoded XX version.
void ast_set_default_eid(struct ast_eid *eid)
Fill in an ast_eid with the default eid of this machine.
int ast_thread_user_interface_set(int is_user_interface)
Set the current thread's user interface status.
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
Compare two EIDs.
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.
static void * dummy_start(void *data)
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
char * ast_unescape_c(char *src)
Convert some C escape sequences.
static int inchar(struct baseio *bio, FILE *fi)
utility used by base_encode()
int ast_build_string(char **buffer, size_t *space, const char *fmt,...)
Build a string in a buffer, designed to be called repeatedly.
int ast_wait_for_input(int fd, int ms)
int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic)
Parse digest authorization header.
char * ast_base64decode_string(const char *src)
Decode BASE64 encoded text and return the string.
void ast_format_duration_hh_mm_ss(int duration, char *buf, size_t length)
Formats a duration into HH:MM:SS.
static void utils_shutdown(void)
int ast_get_timeval(const char *src, struct timeval *dst, struct timeval _default, int *consumed)
get values from config variables.
char * ast_unescape_semicolon(char *s)
Strip backslash for "escaped" semicolons, the string to be stripped (will be modified).
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
char * ast_base64encode_string(const char *src)
Encode to BASE64 and return encoded string.
char * ast_escape_c(char *dest, const char *s, size_t size)
Escape standard 'C' sequences in the given string.
int ast_get_tid(void)
Get current thread ID.
char * ast_strsep(char **iss, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
long int ast_random(void)
static void base64_init(void)
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
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_escape_alloc(const char *s, const char *to_escape)
Escape the 'to_escape' characters in the given string.
const struct ast_flags ast_uri_http
int ast_wait_for_output(int fd, int ms)
static char * escape_alloc(const char *s, size_t *size)
void ast_enable_packet_fragmentation(int sock)
Disable PMTU discovery on a socket.
int ast_base64url_decode(unsigned char *dst, const char *src, int max)
Decode data from base64 URL.
int ast_compare_versions(const char *version1, const char *version2)
Compare 2 major.minor.patch.extra version strings.
char * ast_strsep_quoted(char **iss, const char sep, const char quote, uint32_t flags)
Like ast_strsep() except you can specify a specific quote character.
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
int ast_eid_is_empty(const struct ast_eid *eid)
Check if EID is empty.
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
int ast_base64url_encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64 URL.
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
void DO_CRASH_NORETURN ast_do_crash(void)
Force a crash if DO_CRASH is defined.
char * ast_process_quotes_and_slashes(char *start, char find, char replace_with)
Process a string to find and replace characters.
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
static int safe_mkdir(const char *base_path, char *path, int mode)
char * ast_escape_semicolons(const char *string, char *outbuf, int buflen)
Escape semicolons found in a string.
int ast_false(const char *s)
Make sure something is false. Determine if a string containing a boolean value is "false"....
static char escape_sequences_map[]
int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
encode text to BASE64 coding
int ast_true(const char *s)
Make sure something is true. Determine if a string containing a boolean value is "true"....
void ast_sha1_hash_uint(uint8_t *digest, const char *input)
Produce a 20 byte SHA1 hash of value.
static int inbuf(struct baseio *bio, FILE *fi)
utility used by inchar(), for base_encode()
static int ochar(struct baseio *bio, int c, FILE *so, const char *endl)
utility used by base_encode()
int ast_uri_verify_encoded(const char *string)
Verify if a string is valid as a URI component.
int ast_check_ipv6(void)
Test that an OS supports IPv6 Networking.
char * ast_base64url_decode_string(const char *src)
Decode string from base64 URL.
char * ast_escape_c_alloc(const char *s)
Escape standard 'C' sequences in the given string.
const char * ast_inet_ntoa(struct in_addr ia)
ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa
int ast_str_to_eid(struct ast_eid *eid, const char *s)
Convert a string into an EID.
void ast_uri_decode(char *s, struct ast_flags spec)
Decode URI, URN, URL (overwrite string)
int ast_base64_encode_file_path(const char *filename, FILE *outputfile, const char *endl)
Performs a base 64 encode algorithm on the contents of a File.
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 ...
static struct timeval tvfix(struct timeval a)
void ast_replace_subargument_delimiter(char *s)
Replace '^' in a string with ','.
void DO_CRASH_NORETURN __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function)
const struct ast_flags ast_uri_sip_user
void ast_md5_hash(char *output, const char *input)
Produce 32 char MD5 hash of value.
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_sha1_hash(char *output, const char *input)
Produce 40 char SHA1 hash of value.
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_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".
const struct ast_flags ast_uri_http_legacy
static int wait_for_output(int fd, int timeoutms)
void ast_join_delim(char *s, size_t len, const char *const w[], unsigned int size, char delim)
Join an array of strings into a single string.
char * ast_escape(char *dest, const char *s, size_t size, const char *to_escape)
Escape the 'to_escape' characters in the given string.
static ast_mutex_t randomlock
#define ast_test_flag(p, flag)
#define AST_URI_LEGACY_SPACE
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define AST_URI_SIP_USER_UNRESERVED
#define DO_CRASH_NORETURN
#define ast_socket_nonblock(domain, type, protocol)
Create a non-blocking socket.
#define AST_URI_UNRESERVED
#define AST_STACKSIZE_LOW
#define ast_fd_set_flags(fd, flags)
Set flags on the given file descriptor.
void ast_register_thread(char *name)
void ast_unregister_thread(void *id)
#define ast_pipe_nonblock(filedes)
Create a non-blocking pipe.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.