2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2006, Digium, Inc.
6 * See http://www.asterisk.org for more information about
7 * the Asterisk project. Please do not directly contact
8 * any of the maintainers of this project for assistance;
9 * the project provides a web site, mailing lists and IRC
10 * channels for your use.
12 * This program is free software, distributed under the terms of
13 * the GNU General Public License Version 2. See the LICENSE file
14 * at the top of the source tree.
19 * \brief Utility functions
21 * \note These are important for portability and security,
22 * so please use them in favour of other routines.
23 * Please consult the CODING GUIDELINES for more information.
27 <support_level>core</support_level>
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
40 #include <sys/syscall.h>
41 #if defined(__APPLE__)
42 #include <mach/mach.h>
43 #elif defined(HAVE_SYS_THR_H)
47 #include "asterisk/network.h"
48 #include "asterisk/ast_version.h"
50 #define AST_API_MODULE /* ensure that inlinable API functions will be built in lock.h if required */
51 #include "asterisk/lock.h"
52 #include "asterisk/io.h"
53 #include "asterisk/md5.h"
54 #include "asterisk/sha1.h"
55 #include "asterisk/cli.h"
56 #include "asterisk/linkedlists.h"
58 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
59 #include "asterisk/strings.h"
61 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
62 #include "asterisk/time.h"
64 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
65 #include "asterisk/stringfields.h"
67 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
68 #include "asterisk/utils.h"
70 #define AST_API_MODULE
71 #include "asterisk/threadstorage.h"
73 #define AST_API_MODULE
74 #include "asterisk/config.h"
76 static char base64[64];
79 AST_THREADSTORAGE(inet_ntoa_buf);
81 #if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6)
83 #define ERANGE 34 /*!< duh? ERANGE value copied from web... */
86 AST_MUTEX_DEFINE_STATIC(__mutex);
88 /*! \brief Reentrant replacement for gethostbyname for BSD-based systems.
90 routine is derived from code originally written and placed in the public
91 domain by Enzo Michelangeli <em@em.no-ip.com> */
93 static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
94 size_t buflen, struct hostent **result,
99 ast_mutex_lock(&__mutex); /* begin critical area */
102 ph = gethostbyname(name);
103 *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
110 int naddr = 0, naliases = 0;
111 /* determine if we have enough space in buf */
113 /* count how many addresses */
114 for (p = ph->h_addr_list; *p != 0; p++) {
115 nbytes += ph->h_length; /* addresses */
116 nbytes += sizeof(*p); /* pointers */
119 nbytes += sizeof(*p); /* one more for the terminating NULL */
121 /* count how many aliases, and total length of strings */
122 for (p = ph->h_aliases; *p != 0; p++) {
123 nbytes += (strlen(*p)+1); /* aliases */
124 nbytes += sizeof(*p); /* pointers */
127 nbytes += sizeof(*p); /* one more for the terminating NULL */
129 /* here nbytes is the number of bytes required in buffer */
130 /* as a terminator must be there, the minimum value is ph->h_length */
131 if (nbytes > buflen) {
133 ast_mutex_unlock(&__mutex); /* end critical area */
134 return ERANGE; /* not enough space in buf!! */
137 /* There is enough space. Now we need to do a deep copy! */
138 /* Allocation in buffer:
139 from [0] to [(naddr-1) * sizeof(*p)]:
140 pointers to addresses
141 at [naddr * sizeof(*p)]:
143 from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
145 at [(naddr+naliases+1) * sizeof(*p)]:
147 then naddr addresses (fixed length), and naliases aliases (asciiz).
150 *ret = *ph; /* copy whole structure (not its address!) */
153 q = (char **)buf; /* pointer to pointers area (type: char **) */
154 ret->h_addr_list = q; /* update pointer to address list */
155 pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
156 for (p = ph->h_addr_list; *p != 0; p++) {
157 memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
158 *q++ = pbuf; /* the pointer is the one inside buf... */
159 pbuf += ph->h_length; /* advance pbuf */
161 *q++ = NULL; /* address list terminator */
164 ret->h_aliases = q; /* update pointer to aliases list */
165 for (p = ph->h_aliases; *p != 0; p++) {
166 strcpy(pbuf, *p); /* copy alias strings */
167 *q++ = pbuf; /* the pointer is the one inside buf... */
168 pbuf += strlen(*p); /* advance pbuf */
169 *pbuf++ = 0; /* string terminator */
171 *q++ = NULL; /* terminator */
173 strcpy(pbuf, ph->h_name); /* copy alias strings */
175 pbuf += strlen(ph->h_name); /* advance pbuf */
176 *pbuf++ = 0; /* string terminator */
178 *result = ret; /* and let *result point to structure */
181 h_errno = hsave; /* restore h_errno */
182 ast_mutex_unlock(&__mutex); /* end critical area */
184 return (*result == NULL); /* return 0 on success, non-zero on error */
190 /*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the
191 standard gethostbyname (which is not thread safe)
193 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
199 struct hostent *result = NULL;
200 /* Although it is perfectly legitimate to lookup a pure integer, for
201 the sake of the sanity of people who like to name their peers as
202 integers, we break with tradition and refuse to look up a
209 else if (!isdigit(*s))
214 /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
217 memset(hp, 0, sizeof(struct ast_hostent));
218 hp->hp.h_addrtype = AF_INET;
219 hp->hp.h_addr_list = (void *) hp->buf;
220 hp->hp.h_addr = hp->buf + sizeof(void *);
221 /* For AF_INET, this will always be 4 */
223 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
228 #ifdef HAVE_GETHOSTBYNAME_R_5
229 result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
231 if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
234 res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
236 if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
242 /*! \brief Produce 32 char MD5 hash of value. */
243 void ast_md5_hash(char *output, const char *input)
245 struct MD5Context md5;
246 unsigned char digest[16];
251 MD5Update(&md5, (const unsigned char *) input, strlen(input));
252 MD5Final(digest, &md5);
254 for (x = 0; x < 16; x++)
255 ptr += sprintf(ptr, "%2.2x", digest[x]);
258 /*! \brief Produce 40 char SHA1 hash of value. */
259 void ast_sha1_hash(char *output, const char *input)
261 struct SHA1Context sha;
264 uint8_t Message_Digest[20];
268 SHA1Input(&sha, (const unsigned char *) input, strlen(input));
270 SHA1Result(&sha, Message_Digest);
272 for (x = 0; x < 20; x++)
273 ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
276 /*! \brief Produce a 20 byte SHA1 hash of value. */
277 void ast_sha1_hash_uint(uint8_t *digest, const char *input)
279 struct SHA1Context sha;
283 SHA1Input(&sha, (const unsigned char *) input, strlen(input));
285 SHA1Result(&sha, digest);
288 /*! \brief decode BASE64 encoded text */
289 int ast_base64decode(unsigned char *dst, const char *src, int max)
292 unsigned int byte = 0;
293 unsigned int bits = 0;
295 while(*src && *src != '=' && (cnt < max)) {
296 /* Shift in 6 bits of input */
298 byte |= (b2a[(int)(*src)]) & 0x3f;
302 /* If we have at least 8 bits left over, take that character
306 *dst = (byte >> bits) & 0xff;
311 /* Don't worry about left over bits, they're extra anyway */
315 /*! \brief encode text to BASE64 coding */
316 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
320 unsigned int byte = 0;
323 /* Reserve space for null byte at end of string */
325 while ((cntin < srclen) && (cnt < max)) {
330 if ((bits == 24) && (cnt + 4 <= max)) {
331 *dst++ = base64[(byte >> 18) & 0x3f];
332 *dst++ = base64[(byte >> 12) & 0x3f];
333 *dst++ = base64[(byte >> 6) & 0x3f];
334 *dst++ = base64[byte & 0x3f];
340 if (linebreaks && (cnt < max) && (col == 64)) {
346 if (bits && (cnt + 4 <= max)) {
347 /* Add one last character for the remaining bits,
348 padding the rest with 0 */
350 *dst++ = base64[(byte >> 18) & 0x3f];
351 *dst++ = base64[(byte >> 12) & 0x3f];
353 *dst++ = base64[(byte >> 6) & 0x3f];
359 if (linebreaks && (cnt < max)) {
367 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
369 return ast_base64encode_full(dst, src, srclen, max, 0);
372 static void base64_init(void)
375 memset(b2a, -1, sizeof(b2a));
376 /* Initialize base-64 Conversion table */
377 for (x = 0; x < 26; x++) {
382 base64[x + 26] = 'a' + x;
383 b2a['a' + x] = x + 26;
386 base64[x + 52] = '0' + x;
387 b2a['0' + x] = x + 52;
396 const struct ast_flags ast_uri_http = {AST_URI_UNRESERVED};
397 const struct ast_flags ast_uri_http_legacy = {AST_URI_LEGACY_SPACE | AST_URI_UNRESERVED};
398 const struct ast_flags ast_uri_sip_user = {AST_URI_UNRESERVED | AST_URI_SIP_USER_UNRESERVED};
400 char *ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec)
402 const char *ptr = string; /* Start with the string */
404 const char *mark = "-_.!~*'()"; /* no encode set, RFC 2396 section 2.3, RFC 3261 sec 25 */
405 const char *user_unreserved = "&=+$,;?/"; /* user-unreserved set, RFC 3261 sec 25 */
407 while (*ptr && out - outbuf < buflen - 1) {
408 if (ast_test_flag(&spec, AST_URI_LEGACY_SPACE) && *ptr == ' ') {
409 /* for legacy encoding, encode spaces as '+' */
412 } else if (!(ast_test_flag(&spec, AST_URI_MARK)
413 && strchr(mark, *ptr))
414 && !(ast_test_flag(&spec, AST_URI_ALPHANUM)
415 && ((*ptr >= '0' && *ptr <= '9')
416 || (*ptr >= 'A' && *ptr <= 'Z')
417 || (*ptr >= 'a' && *ptr <= 'z')))
418 && !(ast_test_flag(&spec, AST_URI_SIP_USER_UNRESERVED)
419 && strchr(user_unreserved, *ptr))) {
421 if (out - outbuf >= buflen - 3) {
424 out += sprintf(out, "%%%02X", (unsigned char) *ptr);
426 *out = *ptr; /* Continue copying the string */
439 void ast_uri_decode(char *s, struct ast_flags spec)
444 for (o = s; *s; s++, o++) {
445 if (ast_test_flag(&spec, AST_URI_LEGACY_SPACE) && *s == '+') {
446 /* legacy mode, decode '+' as space */
448 } else if (*s == '%' && s[1] != '\0' && s[2] != '\0' && sscanf(s + 1, "%2x", &tmp) == 1) {
449 /* have '%', two chars and correct parsing */
451 s += 2; /* Will be incremented once more when we break out */
452 } else /* all other cases, just copy */
458 char *ast_escape_quoted(const char *string, char *outbuf, int buflen)
460 const char *ptr = string;
462 char *allow = "\t\v !"; /* allow LWS (minus \r and \n) and "!" */
464 while (*ptr && out - outbuf < buflen - 1) {
465 if (!(strchr(allow, *ptr))
466 && !(*ptr >= '#' && *ptr <= '[') /* %x23 - %x5b */
467 && !(*ptr >= ']' && *ptr <= '~') /* %x5d - %x7e */
468 && !((unsigned char) *ptr > 0x7f)) { /* UTF8-nonascii */
470 if (out - outbuf >= buflen - 2) {
473 out += sprintf(out, "\\%c", (unsigned char) *ptr);
487 int ast_xml_escape(const char *string, char * const outbuf, const size_t buflen)
490 char *end = outbuf + buflen - 1; /* save one for the null terminator */
492 /* Handle the case for the empty output buffer */
497 /* Escaping rules from http://www.w3.org/TR/REC-xml/#syntax */
498 /* This also prevents partial entities at the end of a string */
499 while (*string && dst < end) {
500 const char *entity = NULL;
513 /* necessary if ]]> is in the string; easier to escape them all */
518 /* necessary in single-quoted strings; easier to escape them all */
523 /* necessary in double-quoted strings; easier to escape them all */
533 ast_assert(len == strlen(entity));
534 if (end - dst < len) {
535 /* no room for the entity; stop */
538 /* just checked for length; strcpy is fine */
544 /* Write null terminator */
546 /* If any chars are left in string, return failure */
547 return *string == '\0' ? 0 : -1;
550 /*! \brief ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
551 const char *ast_inet_ntoa(struct in_addr ia)
555 if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
558 return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
561 static int dev_urandom_fd;
564 #undef pthread_create /* For ast_pthread_create function only */
565 #endif /* !__linux__ */
567 #if !defined(LOW_MEMORY)
571 /*! \brief A reasonable maximum number of locks a thread would be holding ... */
572 #define AST_MAX_LOCKS 64
574 /* Allow direct use of pthread_mutex_t and friends */
575 #undef pthread_mutex_t
576 #undef pthread_mutex_lock
577 #undef pthread_mutex_unlock
578 #undef pthread_mutex_init
579 #undef pthread_mutex_destroy
582 * \brief Keep track of which locks a thread holds
584 * There is an instance of this struct for every active thread
586 struct thr_lock_info {
587 /*! The thread's ID */
589 /*! The thread name which includes where the thread was started */
590 const char *thread_name;
591 /*! This is the actual container of info for what locks this thread holds */
596 const char *lock_name;
599 enum ast_lock_type type;
600 /*! This thread is waiting on this lock */
603 struct ast_bt *backtrace;
605 } locks[AST_MAX_LOCKS];
606 /*! This is the number of locks currently held by this thread.
607 * The index (num_locks - 1) has the info on the last one in the
609 unsigned int num_locks;
610 /*! Protects the contents of the locks member
611 * Intentionally not ast_mutex_t */
612 pthread_mutex_t lock;
613 AST_LIST_ENTRY(thr_lock_info) entry;
617 * \brief Locked when accessing the lock_infos list
619 AST_MUTEX_DEFINE_STATIC(lock_infos_lock);
621 * \brief A list of each thread's lock info
623 static AST_LIST_HEAD_NOLOCK_STATIC(lock_infos, thr_lock_info);
626 * \brief Destroy a thread's lock info
628 * This gets called automatically when the thread stops
630 static void lock_info_destroy(void *data)
632 struct thr_lock_info *lock_info = data;
635 pthread_mutex_lock(&lock_infos_lock.mutex);
636 AST_LIST_REMOVE(&lock_infos, lock_info, entry);
637 pthread_mutex_unlock(&lock_infos_lock.mutex);
640 for (i = 0; i < lock_info->num_locks; i++) {
641 if (lock_info->locks[i].pending == -1) {
642 /* This just means that the last lock this thread went for was by
643 * using trylock, and it failed. This is fine. */
648 "Thread '%s' still has a lock! - '%s' (%p) from '%s' in %s:%d!\n",
649 lock_info->thread_name,
650 lock_info->locks[i].lock_name,
651 lock_info->locks[i].lock_addr,
652 lock_info->locks[i].func,
653 lock_info->locks[i].file,
654 lock_info->locks[i].line_num
658 pthread_mutex_destroy(&lock_info->lock);
659 if (lock_info->thread_name)
660 free((void *) lock_info->thread_name);
665 * \brief The thread storage key for per-thread lock info
667 AST_THREADSTORAGE_CUSTOM(thread_lock_info, NULL, lock_info_destroy);
669 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
670 int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
672 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
673 int line_num, const char *func, const char *lock_name, void *lock_addr)
676 struct thr_lock_info *lock_info;
679 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
682 pthread_mutex_lock(&lock_info->lock);
684 for (i = 0; i < lock_info->num_locks; i++) {
685 if (lock_info->locks[i].lock_addr == lock_addr) {
686 lock_info->locks[i].times_locked++;
688 lock_info->locks[i].backtrace = bt;
690 pthread_mutex_unlock(&lock_info->lock);
695 if (lock_info->num_locks == AST_MAX_LOCKS) {
696 /* Can't use ast_log here, because it will cause infinite recursion */
697 fprintf(stderr, "XXX ERROR XXX A thread holds more locks than '%d'."
698 " Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
699 pthread_mutex_unlock(&lock_info->lock);
703 if (i && lock_info->locks[i - 1].pending == -1) {
704 /* The last lock on the list was one that this thread tried to lock but
705 * failed at doing so. It has now moved on to something else, so remove
706 * the old lock from the list. */
708 lock_info->num_locks--;
709 memset(&lock_info->locks[i], 0, sizeof(lock_info->locks[0]));
712 lock_info->locks[i].file = filename;
713 lock_info->locks[i].line_num = line_num;
714 lock_info->locks[i].func = func;
715 lock_info->locks[i].lock_name = lock_name;
716 lock_info->locks[i].lock_addr = lock_addr;
717 lock_info->locks[i].times_locked = 1;
718 lock_info->locks[i].type = type;
719 lock_info->locks[i].pending = 1;
721 lock_info->locks[i].backtrace = bt;
723 lock_info->num_locks++;
725 pthread_mutex_unlock(&lock_info->lock);
728 void ast_mark_lock_acquired(void *lock_addr)
730 struct thr_lock_info *lock_info;
732 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
735 pthread_mutex_lock(&lock_info->lock);
736 if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
737 lock_info->locks[lock_info->num_locks - 1].pending = 0;
739 pthread_mutex_unlock(&lock_info->lock);
742 void ast_mark_lock_failed(void *lock_addr)
744 struct thr_lock_info *lock_info;
746 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
749 pthread_mutex_lock(&lock_info->lock);
750 if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
751 lock_info->locks[lock_info->num_locks - 1].pending = -1;
752 lock_info->locks[lock_info->num_locks - 1].times_locked--;
754 pthread_mutex_unlock(&lock_info->lock);
757 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)
759 struct thr_lock_info *lock_info;
762 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
765 pthread_mutex_lock(&lock_info->lock);
767 for (i = lock_info->num_locks - 1; i >= 0; i--) {
768 if (lock_info->locks[i].lock_addr == lock_addr)
773 /* Lock not found :( */
774 pthread_mutex_unlock(&lock_info->lock);
778 ast_copy_string(filename, lock_info->locks[i].file, filename_size);
779 *lineno = lock_info->locks[i].line_num;
780 ast_copy_string(func, lock_info->locks[i].func, func_size);
781 ast_copy_string(mutex_name, lock_info->locks[i].lock_name, mutex_name_size);
783 pthread_mutex_unlock(&lock_info->lock);
789 void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt)
791 void ast_remove_lock_info(void *lock_addr)
794 struct thr_lock_info *lock_info;
797 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
800 pthread_mutex_lock(&lock_info->lock);
802 for (i = lock_info->num_locks - 1; i >= 0; i--) {
803 if (lock_info->locks[i].lock_addr == lock_addr)
808 /* Lock not found :( */
809 pthread_mutex_unlock(&lock_info->lock);
813 if (lock_info->locks[i].times_locked > 1) {
814 lock_info->locks[i].times_locked--;
816 lock_info->locks[i].backtrace = bt;
818 pthread_mutex_unlock(&lock_info->lock);
822 if (i < lock_info->num_locks - 1) {
823 /* Not the last one ... *should* be rare! */
824 memmove(&lock_info->locks[i], &lock_info->locks[i + 1],
825 (lock_info->num_locks - (i + 1)) * sizeof(lock_info->locks[0]));
828 lock_info->num_locks--;
830 pthread_mutex_unlock(&lock_info->lock);
833 static const char *locktype2str(enum ast_lock_type type)
848 static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt)
854 ast_str_append(str, 0, "\tNo backtrace to print\n");
858 /* store frame count locally to avoid the memory corruption that
859 * sometimes happens on virtualized CentOS 6.x systems */
860 num_frames = bt->num_frames;
861 if ((symbols = ast_bt_get_symbols(bt->addresses, num_frames))) {
864 for (frame_iterator = 0; frame_iterator < num_frames; ++frame_iterator) {
865 ast_str_append(str, 0, "\t%s\n", symbols[frame_iterator]);
870 ast_str_append(str, 0, "\tCouldn't retrieve backtrace symbols\n");
875 static void append_lock_information(struct ast_str **str, struct thr_lock_info *lock_info, int i)
879 struct ast_lock_track *lt;
881 ast_str_append(str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d)\n",
882 lock_info->locks[i].pending > 0 ? "Waiting for " :
883 lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
884 lock_info->locks[i].file,
885 locktype2str(lock_info->locks[i].type),
886 lock_info->locks[i].line_num,
887 lock_info->locks[i].func, lock_info->locks[i].lock_name,
888 lock_info->locks[i].lock_addr,
889 lock_info->locks[i].times_locked);
891 append_backtrace_information(str, lock_info->locks[i].backtrace);
894 if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
897 /* We only have further details for mutexes right now */
898 if (lock_info->locks[i].type != AST_MUTEX)
901 lock = lock_info->locks[i].lock_addr;
903 ast_reentrancy_lock(lt);
904 for (j = 0; *str && j < lt->reentrancy; j++) {
905 ast_str_append(str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n",
906 lt->file[j], lt->lineno[j], lt->func[j]);
908 ast_reentrancy_unlock(lt);
912 /*! This function can help you find highly temporal locks; locks that happen for a
913 short time, but at unexpected times, usually at times that create a deadlock,
914 Why is this thing locked right then? Who is locking it? Who am I fighting
917 To answer such questions, just call this routine before you would normally try
918 to aquire a lock. It doesn't do anything if the lock is not acquired. If the
919 lock is taken, it will publish a line or two to the console via ast_log().
921 Sometimes, the lock message is pretty uninformative. For instance, you might
922 find that the lock is being aquired deep within the astobj2 code; this tells
923 you little about higher level routines that call the astobj2 routines.
924 But, using gdb, you can set a break at the ast_log below, and for that
925 breakpoint, you can set the commands:
928 which will give a stack trace and continue. -- that aught to do the job!
931 void log_show_lock(void *this_lock_addr)
933 struct thr_lock_info *lock_info;
936 if (!(str = ast_str_create(4096))) {
937 ast_log(LOG_NOTICE,"Could not create str\n");
942 pthread_mutex_lock(&lock_infos_lock.mutex);
943 AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
945 pthread_mutex_lock(&lock_info->lock);
946 for (i = 0; str && i < lock_info->num_locks; i++) {
947 /* ONLY show info about this particular lock, if
949 if (lock_info->locks[i].lock_addr == this_lock_addr) {
950 append_lock_information(&str, lock_info, i);
951 ast_log(LOG_NOTICE, "%s", ast_str_buffer(str));
955 pthread_mutex_unlock(&lock_info->lock);
957 pthread_mutex_unlock(&lock_infos_lock.mutex);
962 static char *handle_show_locks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
964 struct thr_lock_info *lock_info;
967 if (!(str = ast_str_create(4096)))
972 e->command = "core show locks";
974 "Usage: core show locks\n"
975 " This command is for lock debugging. It prints out which locks\n"
976 "are owned by each active thread.\n";
983 ast_str_append(&str, 0, "\n"
984 "=======================================================================\n"
986 "=== Currently Held Locks\n"
987 "=======================================================================\n"
989 "=== <pending> <lock#> (<file>): <lock type> <line num> <function> <lock name> <lock addr> (times locked)\n"
990 "===\n", ast_get_version());
995 pthread_mutex_lock(&lock_infos_lock.mutex);
996 AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
998 if (lock_info->num_locks) {
999 ast_str_append(&str, 0, "=== Thread ID: 0x%lx (%s)\n", (long) lock_info->thread_id,
1000 lock_info->thread_name);
1001 pthread_mutex_lock(&lock_info->lock);
1002 for (i = 0; str && i < lock_info->num_locks; i++) {
1003 append_lock_information(&str, lock_info, i);
1005 pthread_mutex_unlock(&lock_info->lock);
1008 ast_str_append(&str, 0, "=== -------------------------------------------------------------------\n"
1014 pthread_mutex_unlock(&lock_infos_lock.mutex);
1019 ast_str_append(&str, 0, "=======================================================================\n"
1025 ast_cli(a->fd, "%s", ast_str_buffer(str));
1032 static struct ast_cli_entry utils_cli[] = {
1033 AST_CLI_DEFINE(handle_show_locks, "Show which locks are held by which thread"),
1036 #endif /* DEBUG_THREADS */
1039 * support for 'show threads'. The start routine is wrapped by
1040 * dummy_start(), so that ast_register_thread() and
1041 * ast_unregister_thread() know the thread identifier.
1044 void *(*start_routine)(void *);
1050 * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
1051 * are odd macros which start and end a block, so they _must_ be
1052 * used in pairs (the latter with a '1' argument to call the
1054 * On BSD we don't need this, but we keep it for compatibility.
1056 static void *dummy_start(void *data)
1059 struct thr_arg a = *((struct thr_arg *) data); /* make a local copy */
1060 #ifdef DEBUG_THREADS
1061 struct thr_lock_info *lock_info;
1062 pthread_mutexattr_t mutex_attr;
1064 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
1067 lock_info->thread_id = pthread_self();
1068 lock_info->thread_name = strdup(a.name);
1070 pthread_mutexattr_init(&mutex_attr);
1071 pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND);
1072 pthread_mutex_init(&lock_info->lock, &mutex_attr);
1073 pthread_mutexattr_destroy(&mutex_attr);
1075 pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
1076 AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry);
1077 pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
1078 #endif /* DEBUG_THREADS */
1080 /* note that even though data->name is a pointer to allocated memory,
1081 we are not freeing it here because ast_register_thread is going to
1082 keep a copy of the pointer and then ast_unregister_thread will
1086 ast_register_thread(a.name);
1087 pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());
1089 ret = a.start_routine(a.data);
1091 pthread_cleanup_pop(1);
1096 #endif /* !LOW_MEMORY */
1098 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
1099 void *data, size_t stacksize, const char *file, const char *caller,
1100 int line, const char *start_fn)
1102 #if !defined(LOW_MEMORY)
1107 attr = ast_alloca(sizeof(*attr));
1108 pthread_attr_init(attr);
1112 /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
1113 which is kind of useless. Change this here to
1114 PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
1115 priority will propagate down to new threads by default.
1116 This does mean that callers cannot set a different priority using
1117 PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
1118 the priority afterwards with pthread_setschedparam(). */
1119 if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
1120 ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
1124 stacksize = AST_STACKSIZE;
1126 if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
1127 ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));
1129 #if !defined(LOW_MEMORY)
1130 if ((a = ast_malloc(sizeof(*a)))) {
1131 a->start_routine = start_routine;
1133 start_routine = dummy_start;
1134 if (ast_asprintf(&a->name, "%-20s started at [%5d] %s %s()",
1135 start_fn, line, file, caller) < 0) {
1140 #endif /* !LOW_MEMORY */
1142 return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
1146 int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
1147 void *data, size_t stacksize, const char *file, const char *caller,
1148 int line, const char *start_fn)
1150 unsigned char attr_destroy = 0;
1154 attr = ast_alloca(sizeof(*attr));
1155 pthread_attr_init(attr);
1159 if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
1160 ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno));
1162 res = ast_pthread_create_stack(thread, attr, start_routine, data,
1163 stacksize, file, caller, line, start_fn);
1166 pthread_attr_destroy(attr);
1171 int ast_wait_for_input(int fd, int ms)
1173 struct pollfd pfd[1];
1174 memset(pfd, 0, sizeof(pfd));
1176 pfd[0].events = POLLIN|POLLPRI;
1177 return ast_poll(pfd, 1, ms);
1180 static int ast_wait_for_output(int fd, int timeoutms)
1182 struct pollfd pfd = {
1187 struct timeval start = ast_tvnow();
1190 /* poll() until the fd is writable without blocking */
1191 while ((res = ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
1195 ast_debug(1, "Timed out trying to write\n");
1198 } else if (res == -1) {
1199 /* poll() returned an error, check to see if it was fatal */
1201 if (errno == EINTR || errno == EAGAIN) {
1202 elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1203 if (elapsed >= timeoutms) {
1206 /* This was an acceptable error, go back into poll() */
1210 /* Fatal error, bail. */
1211 ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno));
1215 elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1216 if (elapsed >= timeoutms) {
1225 * Try to write string, but wait no more than ms milliseconds before timing out.
1227 * \note The code assumes that the file descriptor has NONBLOCK set,
1228 * so there is only one system call made to do a write, unless we actually
1229 * have a need to wait. This way, we get better performance.
1230 * If the descriptor is blocking, all assumptions on the guaranteed
1231 * detail do not apply anymore.
1233 int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
1235 struct timeval start = ast_tvnow();
1240 if (ast_wait_for_output(fd, timeoutms - elapsed)) {
1244 res = write(fd, s, len);
1246 if (res < 0 && errno != EAGAIN && errno != EINTR) {
1247 /* fatal error from write() */
1248 ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
1253 /* It was an acceptable error */
1257 /* Update how much data we have left to write */
1262 elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1263 if (elapsed >= timeoutms) {
1264 /* We've taken too long to write
1265 * This is only an error condition if we haven't finished writing. */
1274 int ast_careful_fwrite(FILE *f, int fd, const char *src, size_t len, int timeoutms)
1276 struct timeval start = ast_tvnow();
1281 if (ast_wait_for_output(fd, timeoutms - elapsed)) {
1282 /* poll returned a fatal error, so bail out immediately. */
1286 /* Clear any errors from a previous write */
1289 n = fwrite(src, 1, len, f);
1291 if (ferror(f) && errno != EINTR && errno != EAGAIN) {
1292 /* fatal error from fwrite() */
1294 /* Don't spam the logs if it was just that the connection is closed. */
1295 ast_log(LOG_ERROR, "fwrite() returned error: %s\n", strerror(errno));
1301 /* Update for data already written to the socket */
1305 elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1306 if (elapsed >= timeoutms) {
1307 /* We've taken too long to write
1308 * This is only an error condition if we haven't finished writing. */
1315 if (errno == EAGAIN || errno == EINTR) {
1319 /* Don't spam the logs if it was just that the connection is closed. */
1320 ast_log(LOG_ERROR, "fflush() returned error: %s\n", strerror(errno));
1326 return n < 0 ? -1 : 0;
1329 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
1335 if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
1336 e = s + strlen(s) - 1;
1337 if (*e == *(end_quotes + (q - beg_quotes))) {
1346 char *ast_unescape_semicolon(char *s)
1351 while ((e = strchr(work, ';'))) {
1352 if ((e > work) && (*(e-1) == '\\')) {
1353 memmove(e - 1, e, strlen(e) + 1);
1363 /* !\brief unescape some C sequences in place, return pointer to the original string.
1365 char *ast_unescape_c(char *src)
1371 for (ret = dst = src; (c = *src++); *dst++ = c ) {
1373 continue; /* copy char at the end of the loop */
1374 switch ((c = *src++)) {
1375 case '\0': /* special, trailing '\' */
1378 case 'b': /* backspace */
1381 case 'f': /* form feed */
1394 /* default, use the char literally */
1400 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
1404 if (!buffer || !*buffer || !space || !*space)
1407 result = vsnprintf(*buffer, *space, fmt, ap);
1411 else if (result > *space)
1419 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
1425 result = ast_build_string_va(buffer, space, fmt, ap);
1431 int ast_regex_string_to_regex_pattern(const char *regex_string, struct ast_str **regex_pattern)
1433 int regex_len = strlen(regex_string);
1436 /* Chop off the leading / if there is one */
1437 if ((regex_len >= 1) && (regex_string[0] == '/')) {
1438 ast_str_set(regex_pattern, 0, "%s", regex_string + 1);
1442 /* Chop off the ending / if there is one */
1443 if ((regex_len > 1) && (regex_string[regex_len - 1] == '/')) {
1444 ast_str_truncate(*regex_pattern, -1);
1451 int ast_true(const char *s)
1453 if (ast_strlen_zero(s))
1456 /* Determine if this is a true value */
1457 if (!strcasecmp(s, "yes") ||
1458 !strcasecmp(s, "true") ||
1459 !strcasecmp(s, "y") ||
1460 !strcasecmp(s, "t") ||
1461 !strcasecmp(s, "1") ||
1462 !strcasecmp(s, "on"))
1468 int ast_false(const char *s)
1470 if (ast_strlen_zero(s))
1473 /* Determine if this is a false value */
1474 if (!strcasecmp(s, "no") ||
1475 !strcasecmp(s, "false") ||
1476 !strcasecmp(s, "n") ||
1477 !strcasecmp(s, "f") ||
1478 !strcasecmp(s, "0") ||
1479 !strcasecmp(s, "off"))
1485 #define ONE_MILLION 1000000
1487 * put timeval in a valid range. usec is 0..999999
1488 * negative values are not allowed and truncated.
1490 static struct timeval tvfix(struct timeval a)
1492 if (a.tv_usec >= ONE_MILLION) {
1493 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
1494 (long)a.tv_sec, (long int) a.tv_usec);
1495 a.tv_sec += a.tv_usec / ONE_MILLION;
1496 a.tv_usec %= ONE_MILLION;
1497 } else if (a.tv_usec < 0) {
1498 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
1499 (long)a.tv_sec, (long int) a.tv_usec);
1505 struct timeval ast_tvadd(struct timeval a, struct timeval b)
1507 /* consistency checks to guarantee usec in 0..999999 */
1510 a.tv_sec += b.tv_sec;
1511 a.tv_usec += b.tv_usec;
1512 if (a.tv_usec >= ONE_MILLION) {
1514 a.tv_usec -= ONE_MILLION;
1519 struct timeval ast_tvsub(struct timeval a, struct timeval b)
1521 /* consistency checks to guarantee usec in 0..999999 */
1524 a.tv_sec -= b.tv_sec;
1525 a.tv_usec -= b.tv_usec;
1526 if (a.tv_usec < 0) {
1528 a.tv_usec += ONE_MILLION;
1533 int ast_remaining_ms(struct timeval start, int max_ms)
1540 ms = max_ms - ast_tvdiff_ms(ast_tvnow(), start);
1552 AST_MUTEX_DEFINE_STATIC(randomlock);
1555 long int ast_random(void)
1559 if (dev_urandom_fd >= 0) {
1560 int read_res = read(dev_urandom_fd, &res, sizeof(res));
1562 long int rm = RAND_MAX;
1563 res = res < 0 ? ~res : res;
1569 /* XXX - Thread safety really depends on the libc, not the OS.
1571 * But... popular Linux libc's (uClibc, glibc, eglibc), all have a
1572 * somewhat thread safe random(3) (results are random, but not
1573 * reproducible). The libc's for other systems (BSD, et al.), not so
1579 ast_mutex_lock(&randomlock);
1581 ast_mutex_unlock(&randomlock);
1586 void ast_replace_subargument_delimiter(char *s)
1595 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
1597 char *dataPut = start;
1601 for (; *start; start++) {
1603 *dataPut++ = *start; /* Always goes verbatim */
1606 if (*start == '\\') {
1607 inEscape = 1; /* Do not copy \ into the data */
1608 } else if (*start == '\'') {
1609 inQuotes = 1 - inQuotes; /* Do not copy ' into the data */
1611 /* Replace , with |, unless in quotes */
1612 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
1616 if (start != dataPut)
1621 void ast_join(char *s, size_t len, const char * const w[])
1626 /* Join words into a string */
1629 for (x = 0; ofs < len && w[x]; x++) {
1632 for (src = w[x]; *src && ofs < len; src++)
1641 * stringfields support routines.
1644 /* this is a little complex... string fields are stored with their
1645 allocated size in the bytes preceding the string; even the
1646 constant 'empty' string has to be this way, so the code that
1647 checks to see if there is enough room for a new string doesn't
1648 have to have any special case checks
1651 static const struct {
1652 ast_string_field_allocation allocation;
1654 } __ast_string_field_empty_buffer;
1656 ast_string_field __ast_string_field_empty = __ast_string_field_empty_buffer.string;
1658 #define ALLOCATOR_OVERHEAD 48
1660 static size_t optimal_alloc_size(size_t size)
1664 size += ALLOCATOR_OVERHEAD;
1666 for (count = 1; size; size >>= 1, count++);
1668 return (1 << count) - ALLOCATOR_OVERHEAD;
1671 /*! \brief add a new block to the pool.
1672 * We can only allocate from the topmost pool, so the
1673 * fields in *mgr reflect the size of that only.
1675 static int add_string_pool(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
1676 size_t size, const char *file, int lineno, const char *func)
1678 struct ast_string_field_pool *pool;
1679 size_t alloc_size = optimal_alloc_size(sizeof(*pool) + size);
1681 #if defined(__AST_DEBUG_MALLOC)
1682 if (!(pool = __ast_calloc(1, alloc_size, file, lineno, func))) {
1686 if (!(pool = ast_calloc(1, alloc_size))) {
1691 pool->prev = *pool_head;
1692 pool->size = alloc_size - sizeof(*pool);
1694 mgr->last_alloc = NULL;
1700 * This is an internal API, code should not use it directly.
1701 * It initializes all fields as empty, then uses 'size' for 3 functions:
1702 * size > 0 means initialize the pool list with a pool of given size.
1703 * This must be called right after allocating the object.
1704 * size = 0 means release all pools except the most recent one.
1705 * If the first pool was allocated via embedding in another
1706 * object, that pool will be preserved instead.
1707 * This is useful to e.g. reset an object to the initial value.
1708 * size < 0 means release all pools.
1709 * This must be done before destroying the object.
1711 int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
1712 int needed, const char *file, int lineno, const char *func)
1714 const char **p = (const char **) pool_head + 1;
1715 struct ast_string_field_pool *cur = NULL;
1716 struct ast_string_field_pool *preserve = NULL;
1718 /* clear fields - this is always necessary */
1719 while ((struct ast_string_field_mgr *) p != mgr) {
1720 *p++ = __ast_string_field_empty;
1723 mgr->last_alloc = NULL;
1724 #if defined(__AST_DEBUG_MALLOC)
1725 mgr->owner_file = file;
1726 mgr->owner_func = func;
1727 mgr->owner_line = lineno;
1729 if (needed > 0) { /* allocate the initial pool */
1731 mgr->embedded_pool = NULL;
1732 return add_string_pool(mgr, pool_head, needed, file, lineno, func);
1735 /* if there is an embedded pool, we can't actually release *all*
1736 * pools, we must keep the embedded one. if the caller is about
1737 * to free the structure that contains the stringfield manager
1738 * and embedded pool anyway, it will be freed as part of that
1741 if ((needed < 0) && mgr->embedded_pool) {
1745 if (needed < 0) { /* reset all pools */
1747 } else if (mgr->embedded_pool) { /* preserve the embedded pool */
1748 preserve = mgr->embedded_pool;
1750 } else { /* preserve the last pool */
1751 if (*pool_head == NULL) {
1752 ast_log(LOG_WARNING, "trying to reset empty pool\n");
1755 preserve = *pool_head;
1756 cur = preserve->prev;
1760 preserve->prev = NULL;
1761 preserve->used = preserve->active = 0;
1765 struct ast_string_field_pool *prev = cur->prev;
1767 if (cur != preserve) {
1773 *pool_head = preserve;
1778 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr,
1779 struct ast_string_field_pool **pool_head, size_t needed)
1781 char *result = NULL;
1782 size_t space = (*pool_head)->size - (*pool_head)->used;
1785 /* Make room for ast_string_field_allocation and make it a multiple of that. */
1786 to_alloc = ast_make_room_for(needed, ast_string_field_allocation);
1787 ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0);
1789 if (__builtin_expect(to_alloc > space, 0)) {
1790 size_t new_size = (*pool_head)->size;
1792 while (new_size < to_alloc) {
1796 #if defined(__AST_DEBUG_MALLOC)
1797 if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
1800 if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
1805 /* pool->base is always aligned (gcc aligned attribute). We ensure that
1806 * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation)
1807 * causing result to always be aligned as well; which in turn fixes that
1808 * AST_STRING_FIELD_ALLOCATION(result) is aligned. */
1809 result = (*pool_head)->base + (*pool_head)->used;
1810 (*pool_head)->used += to_alloc;
1811 (*pool_head)->active += needed;
1812 result += ast_alignof(ast_string_field_allocation);
1813 AST_STRING_FIELD_ALLOCATION(result) = needed;
1814 mgr->last_alloc = result;
1819 int __ast_string_field_ptr_grow(struct ast_string_field_mgr *mgr,
1820 struct ast_string_field_pool **pool_head, size_t needed,
1821 const ast_string_field *ptr)
1823 ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr);
1824 size_t space = (*pool_head)->size - (*pool_head)->used;
1826 if (*ptr != mgr->last_alloc) {
1834 (*pool_head)->used += grow;
1835 (*pool_head)->active += grow;
1836 AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
1841 void __ast_string_field_release_active(struct ast_string_field_pool *pool_head,
1842 const ast_string_field ptr)
1844 struct ast_string_field_pool *pool, *prev;
1846 if (ptr == __ast_string_field_empty) {
1850 for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) {
1851 if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) {
1852 pool->active -= AST_STRING_FIELD_ALLOCATION(ptr);
1853 if ((pool->active == 0) && prev) {
1854 prev->prev = pool->prev;
1862 void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
1863 struct ast_string_field_pool **pool_head,
1864 ast_string_field *ptr, const char *format, va_list ap)
1868 size_t space = (*pool_head)->size - (*pool_head)->used;
1873 /* if the field already has space allocated, try to reuse it;
1874 otherwise, try to use the empty space at the end of the current
1877 if (*ptr != __ast_string_field_empty) {
1878 target = (char *) *ptr;
1879 available = AST_STRING_FIELD_ALLOCATION(*ptr);
1880 if (*ptr == mgr->last_alloc) {
1884 /* pool->used is always a multiple of ast_alignof(ast_string_field_allocation)
1885 * so we don't need to re-align anything here.
1887 target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation);
1888 available = space - ast_alignof(ast_string_field_allocation);
1892 needed = vsnprintf(target, available, format, ap2) + 1;
1895 if (needed > available) {
1896 /* the allocation could not be satisfied using the field's current allocation
1897 (if it has one), or the space available in the pool (if it does not). allocate
1898 space for it, adding a new string pool if necessary.
1900 if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) {
1903 vsprintf(target, format, ap);
1904 va_end(ap); /* XXX va_end without va_start? */
1905 __ast_string_field_release_active(*pool_head, *ptr);
1907 } else if (*ptr != target) {
1908 /* the allocation was satisfied using available space in the pool, but not
1909 using the space already allocated to the field
1911 __ast_string_field_release_active(*pool_head, *ptr);
1912 mgr->last_alloc = *ptr = target;
1913 AST_STRING_FIELD_ALLOCATION(target) = needed;
1914 (*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation);
1915 (*pool_head)->active += needed;
1916 } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) {
1917 /* the allocation was satisfied by using available space in the pool *and*
1918 the field was the last allocated field from the pool, so it grew
1920 AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
1921 (*pool_head)->used += ast_align_for(grow, ast_string_field_allocation);
1922 (*pool_head)->active += grow;
1926 void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
1927 struct ast_string_field_pool **pool_head,
1928 ast_string_field *ptr, const char *format, ...)
1932 va_start(ap, format);
1933 __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap);
1937 void *__ast_calloc_with_stringfields(unsigned int num_structs, size_t struct_size, size_t field_mgr_offset,
1938 size_t field_mgr_pool_offset, size_t pool_size, const char *file,
1939 int lineno, const char *func)
1941 struct ast_string_field_mgr *mgr;
1942 struct ast_string_field_pool *pool;
1943 struct ast_string_field_pool **pool_head;
1944 size_t pool_size_needed = sizeof(*pool) + pool_size;
1945 size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed);
1949 #if defined(__AST_DEBUG_MALLOC)
1950 if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
1954 if (!(allocation = ast_calloc(num_structs, size_to_alloc))) {
1959 for (x = 0; x < num_structs; x++) {
1960 void *base = allocation + (size_to_alloc * x);
1963 mgr = base + field_mgr_offset;
1964 pool_head = base + field_mgr_pool_offset;
1965 pool = base + struct_size;
1967 p = (const char **) pool_head + 1;
1968 while ((struct ast_string_field_mgr *) p != mgr) {
1969 *p++ = __ast_string_field_empty;
1972 mgr->embedded_pool = pool;
1974 pool->size = size_to_alloc - struct_size - sizeof(*pool);
1975 #if defined(__AST_DEBUG_MALLOC)
1976 mgr->owner_file = file;
1977 mgr->owner_func = func;
1978 mgr->owner_line = lineno;
1985 /* end of stringfields support */
1987 AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
1989 int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
1992 ast_mutex_lock(&fetchadd_m);
1995 ast_mutex_unlock(&fetchadd_m);
2000 * get values from config variables.
2002 int ast_get_timeval(const char *src, struct timeval *dst, struct timeval _default, int *consumed)
2004 long double dtv = 0.0;
2012 if (ast_strlen_zero(src))
2015 /* only integer at the moment, but one day we could accept more formats */
2016 if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) {
2018 dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
2020 *consumed = scanned;
2027 * get values from config variables.
2029 int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
2039 if (ast_strlen_zero(src))
2042 /* only integer at the moment, but one day we could accept more formats */
2043 if (sscanf(src, "%30ld%n", &t, &scanned) == 1) {
2046 *consumed = scanned;
2052 void ast_enable_packet_fragmentation(int sock)
2054 #if defined(HAVE_IP_MTU_DISCOVER)
2055 int val = IP_PMTUDISC_DONT;
2057 if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
2058 ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
2059 #endif /* HAVE_IP_MTU_DISCOVER */
2062 int ast_mkdir(const char *path, int mode)
2065 int len = strlen(path), count = 0, x, piececount = 0;
2066 char *tmp = ast_strdupa(path);
2068 char *fullpath = ast_alloca(len + 1);
2071 for (ptr = tmp; *ptr; ptr++) {
2076 /* Count the components to the directory path */
2077 pieces = ast_alloca(count * sizeof(*pieces));
2078 for (ptr = tmp; *ptr; ptr++) {
2081 pieces[piececount++] = ptr + 1;
2086 for (x = 0; x < piececount; x++) {
2087 /* This looks funky, but the buffer is always ideally-sized, so it's fine. */
2088 strcat(fullpath, "/");
2089 strcat(fullpath, pieces[x]);
2090 res = mkdir(fullpath, mode);
2091 if (res && errno != EEXIST)
2097 int ast_utils_init(void)
2099 dev_urandom_fd = open("/dev/urandom", O_RDONLY);
2101 #ifdef DEBUG_THREADS
2102 #if !defined(LOW_MEMORY)
2103 ast_cli_register_multiple(utils_cli, ARRAY_LEN(utils_cli));
2111 *\brief Parse digest authorization header.
2112 *\return Returns -1 if we have no auth or something wrong with digest.
2113 *\note This function may be used for Digest request and responce header.
2114 * request arg is set to nonzero, if we parse Digest Request.
2115 * pedantic arg can be set to nonzero if we need to do addition Digest check.
2117 int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic) {
2119 struct ast_str *str = ast_str_create(16);
2121 /* table of recognised keywords, and places where they should be copied */
2124 const ast_string_field *field;
2126 { "username=", &d->username },
2127 { "realm=", &d->realm },
2128 { "nonce=", &d->nonce },
2129 { "uri=", &d->uri },
2130 { "domain=", &d->domain },
2131 { "response=", &d->response },
2132 { "cnonce=", &d->cnonce },
2133 { "opaque=", &d->opaque },
2134 /* Special cases that cannot be directly copied */
2135 { "algorithm=", NULL },
2141 if (ast_strlen_zero(digest) || !d || !str) {
2146 ast_str_set(&str, 0, "%s", digest);
2148 c = ast_skip_blanks(ast_str_buffer(str));
2150 if (strncasecmp(c, "Digest ", strlen("Digest "))) {
2151 ast_log(LOG_WARNING, "Missing Digest.\n");
2155 c += strlen("Digest ");
2157 /* lookup for keys/value pair */
2158 while (c && *c && *(c = ast_skip_blanks(c))) {
2160 for (i = keys; i->key != NULL; i++) {
2161 char *src, *separator;
2163 if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
2167 /* Found. Skip keyword, take text in quotes or up to the separator. */
2168 c += strlen(i->key);
2177 strsep(&c, separator); /* clear separator and move ptr */
2179 ast_unescape_c(src);
2182 ast_string_field_ptr_set(d, i->field, src);
2184 /* Special cases that require additional procesing */
2185 if (!strcasecmp(i->key, "algorithm=")) {
2186 if (strcasecmp(src, "MD5")) {
2187 ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", src);
2191 } else if (!strcasecmp(i->key, "qop=") && !strcasecmp(src, "auth")) {
2193 } else if (!strcasecmp(i->key, "nc=")) {
2195 if (sscanf(src, "%30lx", &u) != 1) {
2196 ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", src);
2200 ast_string_field_set(d, nc, src);
2205 if (i->key == NULL) { /* not found, try ',' */
2211 /* Digest checkout */
2212 if (ast_strlen_zero(d->realm) || ast_strlen_zero(d->nonce)) {
2213 /* "realm" and "nonce" MUST be always exist */
2218 /* Additional check for Digest response */
2219 if (ast_strlen_zero(d->username) || ast_strlen_zero(d->uri) || ast_strlen_zero(d->response)) {
2223 if (pedantic && d->qop && (ast_strlen_zero(d->cnonce) || ast_strlen_zero(d->nc))) {
2231 #ifndef __AST_DEBUG_MALLOC
2232 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...)
2238 if ((res = vasprintf(ret, fmt, ap)) == -1) {
2247 int ast_get_tid(void)
2250 #if defined (__linux) && defined(SYS_gettid)
2251 ret = syscall(SYS_gettid); /* available since Linux 1.4.11 */
2252 #elif defined(__sun)
2253 ret = pthread_self();
2254 #elif defined(__APPLE__)
2255 ret = mach_thread_self();
2256 mach_port_deallocate(mach_task_self(), ret);
2257 #elif defined(__FreeBSD__) && defined(HAVE_SYS_THR_H)
2259 thr_self(&lwpid); /* available since sys/thr.h creation 2003 */
2265 char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size)
2267 const char *envPATH = getenv("PATH");
2273 tpath = ast_strdupa(envPATH);
2274 while ((path = strsep(&tpath, ":"))) {
2275 snprintf(fullpath, fullpath_size, "%s/%s", path, binary);
2276 if (!stat(fullpath, &unused)) {
2283 void ast_do_crash(void)
2285 #if defined(DO_CRASH)
2288 * Just in case abort() doesn't work or something else super
2289 * silly, and for Qwell's amusement.
2292 #endif /* defined(DO_CRASH) */
2295 #if defined(AST_DEVMODE)
2296 void __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function)
2299 * Attempt to put it into the logger, but hope that at least
2300 * someone saw the message on stderr ...
2302 ast_log(__LOG_ERROR, file, line, function, "FRACK!, Failed assertion %s (%d)\n",
2303 condition_str, condition);
2304 fprintf(stderr, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
2305 condition_str, condition, line, function, file);
2307 * Give the logger a chance to get the message out, just in case
2308 * we abort(), or Asterisk crashes due to whatever problem just
2309 * happened after we exit ast_assert().
2314 #endif /* defined(AST_DEVMODE) */