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.
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
33 #ifdef HAVE_DEV_URANDOM
37 #include "asterisk/network.h"
39 #define AST_API_MODULE /* ensure that inlinable API functions will be built in lock.h if required */
40 #include "asterisk/lock.h"
41 #include "asterisk/io.h"
42 #include "asterisk/md5.h"
43 #include "asterisk/sha1.h"
44 #include "asterisk/cli.h"
45 #include "asterisk/linkedlists.h"
47 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
48 #include "asterisk/strings.h"
50 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
51 #include "asterisk/time.h"
53 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
54 #include "asterisk/stringfields.h"
56 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
57 #include "asterisk/utils.h"
59 #define AST_API_MODULE
60 #include "asterisk/threadstorage.h"
62 #define AST_API_MODULE
63 #include "asterisk/config.h"
65 static char base64[64];
68 AST_THREADSTORAGE(inet_ntoa_buf);
70 #if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6)
72 #define ERANGE 34 /*!< duh? ERANGE value copied from web... */
75 AST_MUTEX_DEFINE_STATIC(__mutex);
77 /*! \brief Reentrant replacement for gethostbyname for BSD-based systems.
79 routine is derived from code originally written and placed in the public
80 domain by Enzo Michelangeli <em@em.no-ip.com> */
82 static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
83 size_t buflen, struct hostent **result,
88 ast_mutex_lock(&__mutex); /* begin critical area */
91 ph = gethostbyname(name);
92 *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
99 int naddr = 0, naliases = 0;
100 /* determine if we have enough space in buf */
102 /* count how many addresses */
103 for (p = ph->h_addr_list; *p != 0; p++) {
104 nbytes += ph->h_length; /* addresses */
105 nbytes += sizeof(*p); /* pointers */
108 nbytes += sizeof(*p); /* one more for the terminating NULL */
110 /* count how many aliases, and total length of strings */
111 for (p = ph->h_aliases; *p != 0; p++) {
112 nbytes += (strlen(*p)+1); /* aliases */
113 nbytes += sizeof(*p); /* pointers */
116 nbytes += sizeof(*p); /* one more for the terminating NULL */
118 /* here nbytes is the number of bytes required in buffer */
119 /* as a terminator must be there, the minimum value is ph->h_length */
120 if (nbytes > buflen) {
122 ast_mutex_unlock(&__mutex); /* end critical area */
123 return ERANGE; /* not enough space in buf!! */
126 /* There is enough space. Now we need to do a deep copy! */
127 /* Allocation in buffer:
128 from [0] to [(naddr-1) * sizeof(*p)]:
129 pointers to addresses
130 at [naddr * sizeof(*p)]:
132 from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
134 at [(naddr+naliases+1) * sizeof(*p)]:
136 then naddr addresses (fixed length), and naliases aliases (asciiz).
139 *ret = *ph; /* copy whole structure (not its address!) */
142 q = (char **)buf; /* pointer to pointers area (type: char **) */
143 ret->h_addr_list = q; /* update pointer to address list */
144 pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
145 for (p = ph->h_addr_list; *p != 0; p++) {
146 memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
147 *q++ = pbuf; /* the pointer is the one inside buf... */
148 pbuf += ph->h_length; /* advance pbuf */
150 *q++ = NULL; /* address list terminator */
153 ret->h_aliases = q; /* update pointer to aliases list */
154 for (p = ph->h_aliases; *p != 0; p++) {
155 strcpy(pbuf, *p); /* copy alias strings */
156 *q++ = pbuf; /* the pointer is the one inside buf... */
157 pbuf += strlen(*p); /* advance pbuf */
158 *pbuf++ = 0; /* string terminator */
160 *q++ = NULL; /* terminator */
162 strcpy(pbuf, ph->h_name); /* copy alias strings */
164 pbuf += strlen(ph->h_name); /* advance pbuf */
165 *pbuf++ = 0; /* string terminator */
167 *result = ret; /* and let *result point to structure */
170 h_errno = hsave; /* restore h_errno */
171 ast_mutex_unlock(&__mutex); /* end critical area */
173 return (*result == NULL); /* return 0 on success, non-zero on error */
179 /*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the
180 standard gethostbyname (which is not thread safe)
182 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
188 struct hostent *result = NULL;
189 /* Although it is perfectly legitimate to lookup a pure integer, for
190 the sake of the sanity of people who like to name their peers as
191 integers, we break with tradition and refuse to look up a
198 else if (!isdigit(*s))
203 /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
206 memset(hp, 0, sizeof(struct ast_hostent));
207 hp->hp.h_addrtype = AF_INET;
208 hp->hp.h_addr_list = (void *) hp->buf;
209 hp->hp.h_addr = hp->buf + sizeof(void *);
210 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
215 #ifdef HAVE_GETHOSTBYNAME_R_5
216 result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
218 if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
221 res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
223 if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
229 /*! \brief Produce 32 char MD5 hash of value. */
230 void ast_md5_hash(char *output, const char *input)
232 struct MD5Context md5;
233 unsigned char digest[16];
238 MD5Update(&md5, (const unsigned char *) input, strlen(input));
239 MD5Final(digest, &md5);
241 for (x = 0; x < 16; x++)
242 ptr += sprintf(ptr, "%2.2x", digest[x]);
245 /*! \brief Produce 40 char SHA1 hash of value. */
246 void ast_sha1_hash(char *output, const char *input)
248 struct SHA1Context sha;
251 uint8_t Message_Digest[20];
255 SHA1Input(&sha, (const unsigned char *) input, strlen(input));
257 SHA1Result(&sha, Message_Digest);
259 for (x = 0; x < 20; x++)
260 ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
263 /*! \brief decode BASE64 encoded text */
264 int ast_base64decode(unsigned char *dst, const char *src, int max)
267 unsigned int byte = 0;
268 unsigned int bits = 0;
270 while(*src && *src != '=' && (cnt < max)) {
271 /* Shift in 6 bits of input */
273 byte |= (b2a[(int)(*src)]) & 0x3f;
277 /* If we have at least 8 bits left over, take that character
281 *dst = (byte >> bits) & 0xff;
286 /* Dont worry about left over bits, they're extra anyway */
290 /*! \brief encode text to BASE64 coding */
291 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
295 unsigned int byte = 0;
298 /* Reserve space for null byte at end of string */
300 while ((cntin < srclen) && (cnt < max)) {
305 if ((bits == 24) && (cnt + 4 <= max)) {
306 *dst++ = base64[(byte >> 18) & 0x3f];
307 *dst++ = base64[(byte >> 12) & 0x3f];
308 *dst++ = base64[(byte >> 6) & 0x3f];
309 *dst++ = base64[byte & 0x3f];
315 if (linebreaks && (cnt < max) && (col == 64)) {
321 if (bits && (cnt + 4 <= max)) {
322 /* Add one last character for the remaining bits,
323 padding the rest with 0 */
325 *dst++ = base64[(byte >> 18) & 0x3f];
326 *dst++ = base64[(byte >> 12) & 0x3f];
328 *dst++ = base64[(byte >> 6) & 0x3f];
334 if (linebreaks && (cnt < max)) {
342 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
344 return ast_base64encode_full(dst, src, srclen, max, 0);
347 static void base64_init(void)
350 memset(b2a, -1, sizeof(b2a));
351 /* Initialize base-64 Conversion table */
352 for (x = 0; x < 26; x++) {
357 base64[x + 26] = 'a' + x;
358 b2a['a' + x] = x + 26;
361 base64[x + 52] = '0' + x;
362 b2a['0' + x] = x + 52;
371 /*! \brief ast_uri_encode: Turn text string to URI-encoded %XX version
372 \note At this point, we're converting from ISO-8859-x (8-bit), not UTF8
373 as in the SIP protocol spec
374 If doreserved == 1 we will convert reserved characters also.
375 RFC 2396, section 2.4
376 outbuf needs to have more memory allocated than the instring
377 to have room for the expansion. Every char that is converted
378 is replaced by three ASCII characters.
380 Note: The doreserved option is needed for replaces header in
383 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved)
385 char *reserved = ";/?:@&=+$,# "; /* Reserved chars */
387 const char *ptr = string; /* Start with the string */
391 ast_copy_string(outbuf, string, buflen);
393 /* If there's no characters to convert, just go through and don't do anything */
395 if ((*ptr < 32) || (doreserved && strchr(reserved, *ptr))) {
396 /* Oops, we need to start working here */
399 out = buf + (ptr - string) ; /* Set output ptr */
401 out += sprintf(out, "%%%02x", (unsigned char) *ptr);
403 *out = *ptr; /* Continue copying the string */
413 /*! \brief ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string) */
414 void ast_uri_decode(char *s)
419 for (o = s; *s; s++, o++) {
420 if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
421 /* have '%', two chars and correct parsing */
423 s += 2; /* Will be incremented once more when we break out */
424 } else /* all other cases, just copy */
430 /*! \brief ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
431 const char *ast_inet_ntoa(struct in_addr ia)
435 if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
438 return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
441 #ifdef HAVE_DEV_URANDOM
442 static int dev_urandom_fd;
446 #undef pthread_create /* For ast_pthread_create function only */
447 #endif /* !__linux__ */
449 #if !defined(LOW_MEMORY)
453 /*! \brief A reasonable maximum number of locks a thread would be holding ... */
454 #define AST_MAX_LOCKS 64
456 /* Allow direct use of pthread_mutex_t and friends */
457 #undef pthread_mutex_t
458 #undef pthread_mutex_lock
459 #undef pthread_mutex_unlock
460 #undef pthread_mutex_init
461 #undef pthread_mutex_destroy
464 * \brief Keep track of which locks a thread holds
466 * There is an instance of this struct for every active thread
468 struct thr_lock_info {
469 /*! The thread's ID */
471 /*! The thread name which includes where the thread was started */
472 const char *thread_name;
473 /*! This is the actual container of info for what locks this thread holds */
478 const char *lock_name;
481 enum ast_lock_type type;
482 /*! This thread is waiting on this lock */
485 struct ast_bt *backtrace;
487 } locks[AST_MAX_LOCKS];
488 /*! This is the number of locks currently held by this thread.
489 * The index (num_locks - 1) has the info on the last one in the
491 unsigned int num_locks;
492 /*! Protects the contents of the locks member
493 * Intentionally not ast_mutex_t */
494 pthread_mutex_t lock;
495 AST_LIST_ENTRY(thr_lock_info) entry;
499 * \brief Locked when accessing the lock_infos list
501 AST_MUTEX_DEFINE_STATIC(lock_infos_lock);
503 * \brief A list of each thread's lock info
505 static AST_LIST_HEAD_NOLOCK_STATIC(lock_infos, thr_lock_info);
508 * \brief Destroy a thread's lock info
510 * This gets called automatically when the thread stops
512 static void lock_info_destroy(void *data)
514 struct thr_lock_info *lock_info = data;
517 pthread_mutex_lock(&lock_infos_lock.mutex);
518 AST_LIST_REMOVE(&lock_infos, lock_info, entry);
519 pthread_mutex_unlock(&lock_infos_lock.mutex);
522 for (i = 0; i < lock_info->num_locks; i++) {
523 if (lock_info->locks[i].pending == -1) {
524 /* This just means that the last lock this thread went for was by
525 * using trylock, and it failed. This is fine. */
530 "Thread '%s' still has a lock! - '%s' (%p) from '%s' in %s:%d!\n",
531 lock_info->thread_name,
532 lock_info->locks[i].lock_name,
533 lock_info->locks[i].lock_addr,
534 lock_info->locks[i].func,
535 lock_info->locks[i].file,
536 lock_info->locks[i].line_num
540 pthread_mutex_destroy(&lock_info->lock);
541 if (lock_info->thread_name)
542 free((void *) lock_info->thread_name);
547 * \brief The thread storage key for per-thread lock info
549 AST_THREADSTORAGE_CUSTOM(thread_lock_info, NULL, lock_info_destroy);
551 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
552 int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
554 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
555 int line_num, const char *func, const char *lock_name, void *lock_addr)
558 struct thr_lock_info *lock_info;
561 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
564 pthread_mutex_lock(&lock_info->lock);
566 for (i = 0; i < lock_info->num_locks; i++) {
567 if (lock_info->locks[i].lock_addr == lock_addr) {
568 lock_info->locks[i].times_locked++;
570 lock_info->locks[i].backtrace = bt;
572 pthread_mutex_unlock(&lock_info->lock);
577 if (lock_info->num_locks == AST_MAX_LOCKS) {
578 /* Can't use ast_log here, because it will cause infinite recursion */
579 fprintf(stderr, "XXX ERROR XXX A thread holds more locks than '%d'."
580 " Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
581 pthread_mutex_unlock(&lock_info->lock);
585 if (i && lock_info->locks[i - 1].pending == -1) {
586 /* The last lock on the list was one that this thread tried to lock but
587 * failed at doing so. It has now moved on to something else, so remove
588 * the old lock from the list. */
590 lock_info->num_locks--;
591 memset(&lock_info->locks[i], 0, sizeof(lock_info->locks[0]));
594 lock_info->locks[i].file = filename;
595 lock_info->locks[i].line_num = line_num;
596 lock_info->locks[i].func = func;
597 lock_info->locks[i].lock_name = lock_name;
598 lock_info->locks[i].lock_addr = lock_addr;
599 lock_info->locks[i].times_locked = 1;
600 lock_info->locks[i].type = type;
601 lock_info->locks[i].pending = 1;
603 lock_info->locks[i].backtrace = bt;
605 lock_info->num_locks++;
607 pthread_mutex_unlock(&lock_info->lock);
610 void ast_mark_lock_acquired(void *lock_addr)
612 struct thr_lock_info *lock_info;
614 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
617 pthread_mutex_lock(&lock_info->lock);
618 if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
619 lock_info->locks[lock_info->num_locks - 1].pending = 0;
621 pthread_mutex_unlock(&lock_info->lock);
624 void ast_mark_lock_failed(void *lock_addr)
626 struct thr_lock_info *lock_info;
628 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
631 pthread_mutex_lock(&lock_info->lock);
632 if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
633 lock_info->locks[lock_info->num_locks - 1].pending = -1;
634 lock_info->locks[lock_info->num_locks - 1].times_locked--;
636 pthread_mutex_unlock(&lock_info->lock);
639 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)
641 struct thr_lock_info *lock_info;
644 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
647 pthread_mutex_lock(&lock_info->lock);
649 for (i = lock_info->num_locks - 1; i >= 0; i--) {
650 if (lock_info->locks[i].lock_addr == lock_addr)
655 /* Lock not found :( */
656 pthread_mutex_unlock(&lock_info->lock);
660 ast_copy_string(filename, lock_info->locks[i].file, filename_size);
661 *lineno = lock_info->locks[i].line_num;
662 ast_copy_string(func, lock_info->locks[i].func, func_size);
663 ast_copy_string(mutex_name, lock_info->locks[i].lock_name, mutex_name_size);
665 pthread_mutex_unlock(&lock_info->lock);
671 void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt)
673 void ast_remove_lock_info(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 = lock_info->num_locks - 1; i >= 0; i--) {
685 if (lock_info->locks[i].lock_addr == lock_addr)
690 /* Lock not found :( */
691 pthread_mutex_unlock(&lock_info->lock);
695 if (lock_info->locks[i].times_locked > 1) {
696 lock_info->locks[i].times_locked--;
698 lock_info->locks[i].backtrace = bt;
700 pthread_mutex_unlock(&lock_info->lock);
704 if (i < lock_info->num_locks - 1) {
705 /* Not the last one ... *should* be rare! */
706 memmove(&lock_info->locks[i], &lock_info->locks[i + 1],
707 (lock_info->num_locks - (i + 1)) * sizeof(lock_info->locks[0]));
710 lock_info->num_locks--;
712 pthread_mutex_unlock(&lock_info->lock);
715 static const char *locktype2str(enum ast_lock_type type)
730 static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt)
735 ast_str_append(str, 0, "\tNo backtrace to print\n");
739 if ((symbols = backtrace_symbols(bt->addresses, bt->num_frames))) {
742 for (frame_iterator = 0; frame_iterator < bt->num_frames; ++frame_iterator) {
743 ast_str_append(str, 0, "\t%s\n", symbols[frame_iterator]);
748 ast_str_append(str, 0, "\tCouldn't retrieve backtrace symbols\n");
753 static void append_lock_information(struct ast_str **str, struct thr_lock_info *lock_info, int i)
757 struct ast_lock_track *lt;
759 ast_str_append(str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d)\n",
760 lock_info->locks[i].pending > 0 ? "Waiting for " :
761 lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
762 lock_info->locks[i].file,
763 locktype2str(lock_info->locks[i].type),
764 lock_info->locks[i].line_num,
765 lock_info->locks[i].func, lock_info->locks[i].lock_name,
766 lock_info->locks[i].lock_addr,
767 lock_info->locks[i].times_locked);
769 append_backtrace_information(str, lock_info->locks[i].backtrace);
772 if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
775 /* We only have further details for mutexes right now */
776 if (lock_info->locks[i].type != AST_MUTEX)
779 lock = lock_info->locks[i].lock_addr;
781 ast_reentrancy_lock(lt);
782 for (j = 0; *str && j < lt->reentrancy; j++) {
783 ast_str_append(str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n",
784 lt->file[j], lt->lineno[j], lt->func[j]);
786 ast_reentrancy_unlock(lt);
790 /*! This function can help you find highly temporal locks; locks that happen for a
791 short time, but at unexpected times, usually at times that create a deadlock,
792 Why is this thing locked right then? Who is locking it? Who am I fighting
795 To answer such questions, just call this routine before you would normally try
796 to aquire a lock. It doesn't do anything if the lock is not acquired. If the
797 lock is taken, it will publish a line or two to the console via ast_log().
799 Sometimes, the lock message is pretty uninformative. For instance, you might
800 find that the lock is being aquired deep within the astobj2 code; this tells
801 you little about higher level routines that call the astobj2 routines.
802 But, using gdb, you can set a break at the ast_log below, and for that
803 breakpoint, you can set the commands:
806 which will give a stack trace and continue. -- that aught to do the job!
809 void log_show_lock(void *this_lock_addr)
811 struct thr_lock_info *lock_info;
814 if (!(str = ast_str_create(4096))) {
815 ast_log(LOG_NOTICE,"Could not create str\n");
820 pthread_mutex_lock(&lock_infos_lock.mutex);
821 AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
823 pthread_mutex_lock(&lock_info->lock);
824 for (i = 0; str && i < lock_info->num_locks; i++) {
825 /* ONLY show info about this particular lock, if
827 if (lock_info->locks[i].lock_addr == this_lock_addr) {
828 append_lock_information(&str, lock_info, i);
829 ast_log(LOG_NOTICE, "%s", ast_str_buffer(str));
833 pthread_mutex_unlock(&lock_info->lock);
835 pthread_mutex_unlock(&lock_infos_lock.mutex);
840 static char *handle_show_locks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
842 struct thr_lock_info *lock_info;
845 if (!(str = ast_str_create(4096)))
850 e->command = "core show locks";
852 "Usage: core show locks\n"
853 " This command is for lock debugging. It prints out which locks\n"
854 "are owned by each active thread.\n";
861 ast_str_append(&str, 0, "\n"
862 "=======================================================================\n"
863 "=== Currently Held Locks ==============================================\n"
864 "=======================================================================\n"
866 "=== <pending> <lock#> (<file>): <lock type> <line num> <function> <lock name> <lock addr> (times locked)\n"
872 pthread_mutex_lock(&lock_infos_lock.mutex);
873 AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
875 if (lock_info->num_locks) {
876 ast_str_append(&str, 0, "=== Thread ID: %ld (%s)\n", (long) lock_info->thread_id,
877 lock_info->thread_name);
878 pthread_mutex_lock(&lock_info->lock);
879 for (i = 0; str && i < lock_info->num_locks; i++) {
880 append_lock_information(&str, lock_info, i);
882 pthread_mutex_unlock(&lock_info->lock);
885 ast_str_append(&str, 0, "=== -------------------------------------------------------------------\n"
891 pthread_mutex_unlock(&lock_infos_lock.mutex);
896 ast_str_append(&str, 0, "=======================================================================\n"
902 ast_cli(a->fd, "%s", ast_str_buffer(str));
909 static struct ast_cli_entry utils_cli[] = {
910 AST_CLI_DEFINE(handle_show_locks, "Show which locks are held by which thread"),
913 #endif /* DEBUG_THREADS */
916 * support for 'show threads'. The start routine is wrapped by
917 * dummy_start(), so that ast_register_thread() and
918 * ast_unregister_thread() know the thread identifier.
921 void *(*start_routine)(void *);
927 * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
928 * are odd macros which start and end a block, so they _must_ be
929 * used in pairs (the latter with a '1' argument to call the
931 * On BSD we don't need this, but we keep it for compatibility.
933 static void *dummy_start(void *data)
936 struct thr_arg a = *((struct thr_arg *) data); /* make a local copy */
938 struct thr_lock_info *lock_info;
939 pthread_mutexattr_t mutex_attr;
942 /* note that even though data->name is a pointer to allocated memory,
943 we are not freeing it here because ast_register_thread is going to
944 keep a copy of the pointer and then ast_unregister_thread will
948 ast_register_thread(a.name);
949 pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());
952 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
955 lock_info->thread_id = pthread_self();
956 lock_info->thread_name = strdup(a.name);
958 pthread_mutexattr_init(&mutex_attr);
959 pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND);
960 pthread_mutex_init(&lock_info->lock, &mutex_attr);
961 pthread_mutexattr_destroy(&mutex_attr);
963 pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
964 AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry);
965 pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
966 #endif /* DEBUG_THREADS */
968 ret = a.start_routine(a.data);
970 pthread_cleanup_pop(1);
975 #endif /* !LOW_MEMORY */
977 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
978 void *data, size_t stacksize, const char *file, const char *caller,
979 int line, const char *start_fn)
981 #if !defined(LOW_MEMORY)
986 attr = alloca(sizeof(*attr));
987 pthread_attr_init(attr);
991 /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
992 which is kind of useless. Change this here to
993 PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
994 priority will propagate down to new threads by default.
995 This does mean that callers cannot set a different priority using
996 PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
997 the priority afterwards with pthread_setschedparam(). */
998 if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
999 ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
1003 stacksize = AST_STACKSIZE;
1005 if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
1006 ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));
1008 #if !defined(LOW_MEMORY)
1009 if ((a = ast_malloc(sizeof(*a)))) {
1010 a->start_routine = start_routine;
1012 start_routine = dummy_start;
1013 if (asprintf(&a->name, "%-20s started at [%5d] %s %s()",
1014 start_fn, line, file, caller) < 0) {
1015 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
1020 #endif /* !LOW_MEMORY */
1022 return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
1026 int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
1027 void *data, size_t stacksize, const char *file, const char *caller,
1028 int line, const char *start_fn)
1030 unsigned char attr_destroy = 0;
1034 attr = alloca(sizeof(*attr));
1035 pthread_attr_init(attr);
1039 if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
1040 ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno));
1042 res = ast_pthread_create_stack(thread, attr, start_routine, data,
1043 stacksize, file, caller, line, start_fn);
1046 pthread_attr_destroy(attr);
1051 int ast_wait_for_input(int fd, int ms)
1053 struct pollfd pfd[1];
1054 memset(pfd, 0, sizeof(pfd));
1056 pfd[0].events = POLLIN|POLLPRI;
1057 return ast_poll(pfd, 1, ms);
1060 static int ast_wait_for_output(int fd, int timeoutms)
1062 struct pollfd pfd = {
1067 struct timeval start = ast_tvnow();
1070 /* poll() until the fd is writable without blocking */
1071 while ((res = ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
1075 ast_debug(1, "Timed out trying to write\n");
1078 } else if (res == -1) {
1079 /* poll() returned an error, check to see if it was fatal */
1081 if (errno == EINTR || errno == EAGAIN) {
1082 elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1083 if (elapsed >= timeoutms) {
1086 /* This was an acceptable error, go back into poll() */
1090 /* Fatal error, bail. */
1091 ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno));
1095 elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1096 if (elapsed >= timeoutms) {
1105 * Try to write string, but wait no more than ms milliseconds before timing out.
1107 * \note The code assumes that the file descriptor has NONBLOCK set,
1108 * so there is only one system call made to do a write, unless we actually
1109 * have a need to wait. This way, we get better performance.
1110 * If the descriptor is blocking, all assumptions on the guaranteed
1111 * detail do not apply anymore.
1113 int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
1115 struct timeval start = ast_tvnow();
1120 if (ast_wait_for_output(fd, timeoutms - elapsed)) {
1124 res = write(fd, s, len);
1126 if (res < 0 && errno != EAGAIN && errno != EINTR) {
1127 /* fatal error from write() */
1128 ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
1133 /* It was an acceptable error */
1137 /* Update how much data we have left to write */
1142 elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1143 if (elapsed >= timeoutms) {
1144 /* We've taken too long to write
1145 * This is only an error condition if we haven't finished writing. */
1154 int ast_careful_fwrite(FILE *f, int fd, const char *src, size_t len, int timeoutms)
1156 struct timeval start = ast_tvnow();
1161 if (ast_wait_for_output(fd, timeoutms - elapsed)) {
1162 /* poll returned a fatal error, so bail out immediately. */
1166 /* Clear any errors from a previous write */
1169 n = fwrite(src, 1, len, f);
1171 if (ferror(f) && errno != EINTR && errno != EAGAIN) {
1172 /* fatal error from fwrite() */
1174 /* Don't spam the logs if it was just that the connection is closed. */
1175 ast_log(LOG_ERROR, "fwrite() returned error: %s\n", strerror(errno));
1181 /* Update for data already written to the socket */
1185 elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1186 if (elapsed >= timeoutms) {
1187 /* We've taken too long to write
1188 * This is only an error condition if we haven't finished writing. */
1195 if (errno == EAGAIN || errno == EINTR) {
1199 /* Don't spam the logs if it was just that the connection is closed. */
1200 ast_log(LOG_ERROR, "fflush() returned error: %s\n", strerror(errno));
1206 return n < 0 ? -1 : 0;
1209 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
1215 if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
1216 e = s + strlen(s) - 1;
1217 if (*e == *(end_quotes + (q - beg_quotes))) {
1226 char *ast_unescape_semicolon(char *s)
1231 while ((e = strchr(work, ';'))) {
1232 if ((e > work) && (*(e-1) == '\\')) {
1233 memmove(e - 1, e, strlen(e) + 1);
1243 /* !\brief unescape some C sequences in place, return pointer to the original string.
1245 char *ast_unescape_c(char *src)
1251 for (ret = dst = src; (c = *src++); *dst++ = c ) {
1253 continue; /* copy char at the end of the loop */
1254 switch ((c = *src++)) {
1255 case '\0': /* special, trailing '\' */
1258 case 'b': /* backspace */
1261 case 'f': /* form feed */
1274 /* default, use the char literally */
1280 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
1284 if (!buffer || !*buffer || !space || !*space)
1287 result = vsnprintf(*buffer, *space, fmt, ap);
1291 else if (result > *space)
1299 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
1305 result = ast_build_string_va(buffer, space, fmt, ap);
1311 int ast_true(const char *s)
1313 if (ast_strlen_zero(s))
1316 /* Determine if this is a true value */
1317 if (!strcasecmp(s, "yes") ||
1318 !strcasecmp(s, "true") ||
1319 !strcasecmp(s, "y") ||
1320 !strcasecmp(s, "t") ||
1321 !strcasecmp(s, "1") ||
1322 !strcasecmp(s, "on"))
1328 int ast_false(const char *s)
1330 if (ast_strlen_zero(s))
1333 /* Determine if this is a false value */
1334 if (!strcasecmp(s, "no") ||
1335 !strcasecmp(s, "false") ||
1336 !strcasecmp(s, "n") ||
1337 !strcasecmp(s, "f") ||
1338 !strcasecmp(s, "0") ||
1339 !strcasecmp(s, "off"))
1345 #define ONE_MILLION 1000000
1347 * put timeval in a valid range. usec is 0..999999
1348 * negative values are not allowed and truncated.
1350 static struct timeval tvfix(struct timeval a)
1352 if (a.tv_usec >= ONE_MILLION) {
1353 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
1354 (long)a.tv_sec, (long int) a.tv_usec);
1355 a.tv_sec += a.tv_usec / ONE_MILLION;
1356 a.tv_usec %= ONE_MILLION;
1357 } else if (a.tv_usec < 0) {
1358 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
1359 (long)a.tv_sec, (long int) a.tv_usec);
1365 struct timeval ast_tvadd(struct timeval a, struct timeval b)
1367 /* consistency checks to guarantee usec in 0..999999 */
1370 a.tv_sec += b.tv_sec;
1371 a.tv_usec += b.tv_usec;
1372 if (a.tv_usec >= ONE_MILLION) {
1374 a.tv_usec -= ONE_MILLION;
1379 struct timeval ast_tvsub(struct timeval a, struct timeval b)
1381 /* consistency checks to guarantee usec in 0..999999 */
1384 a.tv_sec -= b.tv_sec;
1385 a.tv_usec -= b.tv_usec;
1386 if (a.tv_usec < 0) {
1388 a.tv_usec += ONE_MILLION;
1394 /*! \brief glibc puts a lock inside random(3), so that the results are thread-safe.
1395 * BSD libc (and others) do not. */
1398 AST_MUTEX_DEFINE_STATIC(randomlock);
1401 long int ast_random(void)
1404 #ifdef HAVE_DEV_URANDOM
1405 if (dev_urandom_fd >= 0) {
1406 int read_res = read(dev_urandom_fd, &res, sizeof(res));
1408 long int rm = RAND_MAX;
1409 res = res < 0 ? ~res : res;
1418 ast_mutex_lock(&randomlock);
1420 ast_mutex_unlock(&randomlock);
1425 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
1427 char *dataPut = start;
1431 for (; *start; start++) {
1433 *dataPut++ = *start; /* Always goes verbatim */
1436 if (*start == '\\') {
1437 inEscape = 1; /* Do not copy \ into the data */
1438 } else if (*start == '\'') {
1439 inQuotes = 1 - inQuotes; /* Do not copy ' into the data */
1441 /* Replace , with |, unless in quotes */
1442 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
1446 if (start != dataPut)
1451 void ast_join(char *s, size_t len, const char * const w[])
1456 /* Join words into a string */
1459 for (x = 0; ofs < len && w[x]; x++) {
1462 for (src = w[x]; *src && ofs < len; src++)
1471 * stringfields support routines.
1474 /* this is a little complex... string fields are stored with their
1475 allocated size in the bytes preceding the string; even the
1476 constant 'empty' string has to be this way, so the code that
1477 checks to see if there is enough room for a new string doesn't
1478 have to have any special case checks
1481 static const struct {
1482 ast_string_field_allocation allocation;
1484 } __ast_string_field_empty_buffer;
1486 ast_string_field __ast_string_field_empty = __ast_string_field_empty_buffer.string;
1488 #define ALLOCATOR_OVERHEAD 48
1490 static size_t optimal_alloc_size(size_t size)
1494 size += ALLOCATOR_OVERHEAD;
1496 for (count = 1; size; size >>= 1, count++);
1498 return (1 << count) - ALLOCATOR_OVERHEAD;
1501 /*! \brief add a new block to the pool.
1502 * We can only allocate from the topmost pool, so the
1503 * fields in *mgr reflect the size of that only.
1505 static int add_string_pool(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
1506 size_t size, const char *file, int lineno, const char *func)
1508 struct ast_string_field_pool *pool;
1509 size_t alloc_size = optimal_alloc_size(sizeof(*pool) + size);
1511 #if defined(__AST_DEBUG_MALLOC)
1512 if (!(pool = __ast_calloc(1, alloc_size, file, lineno, func))) {
1516 if (!(pool = ast_calloc(1, alloc_size))) {
1521 pool->prev = *pool_head;
1522 pool->size = alloc_size - sizeof(*pool);
1524 mgr->last_alloc = NULL;
1530 * This is an internal API, code should not use it directly.
1531 * It initializes all fields as empty, then uses 'size' for 3 functions:
1532 * size > 0 means initialize the pool list with a pool of given size.
1533 * This must be called right after allocating the object.
1534 * size = 0 means release all pools except the most recent one.
1535 * If the first pool was allocated via embedding in another
1536 * object, that pool will be preserved instead.
1537 * This is useful to e.g. reset an object to the initial value.
1538 * size < 0 means release all pools.
1539 * This must be done before destroying the object.
1541 int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
1542 int needed, const char *file, int lineno, const char *func)
1544 const char **p = (const char **) pool_head + 1;
1545 struct ast_string_field_pool *cur = NULL;
1546 struct ast_string_field_pool *preserve = NULL;
1548 /* clear fields - this is always necessary */
1549 while ((struct ast_string_field_mgr *) p != mgr) {
1550 *p++ = __ast_string_field_empty;
1553 mgr->last_alloc = NULL;
1554 #if defined(__AST_DEBUG_MALLOC)
1555 mgr->owner_file = file;
1556 mgr->owner_func = func;
1557 mgr->owner_line = lineno;
1559 if (needed > 0) { /* allocate the initial pool */
1561 return add_string_pool(mgr, pool_head, needed, file, lineno, func);
1564 /* if there is an embedded pool, we can't actually release *all*
1565 * pools, we must keep the embedded one. if the caller is about
1566 * to free the structure that contains the stringfield manager
1567 * and embedded pool anyway, it will be freed as part of that
1570 if ((needed < 0) && mgr->embedded_pool) {
1574 if (needed < 0) { /* reset all pools */
1576 } else if (mgr->embedded_pool) { /* preserve the embedded pool */
1577 preserve = mgr->embedded_pool;
1579 } else { /* preserve the last pool */
1580 if (*pool_head == NULL) {
1581 ast_log(LOG_WARNING, "trying to reset empty pool\n");
1584 preserve = *pool_head;
1585 cur = preserve->prev;
1589 preserve->prev = NULL;
1590 preserve->used = preserve->active = 0;
1594 struct ast_string_field_pool *prev = cur->prev;
1596 if (cur != preserve) {
1602 *pool_head = preserve;
1607 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr,
1608 struct ast_string_field_pool **pool_head, size_t needed)
1610 char *result = NULL;
1611 size_t space = (*pool_head)->size - (*pool_head)->used;
1612 size_t to_alloc = needed + sizeof(ast_string_field_allocation);
1614 if (__builtin_expect(to_alloc > space, 0)) {
1615 size_t new_size = (*pool_head)->size;
1617 while (new_size < to_alloc) {
1621 #if defined(__AST_DEBUG_MALLOC)
1622 if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
1625 if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
1630 result = (*pool_head)->base + (*pool_head)->used;
1631 (*pool_head)->used += to_alloc;
1632 (*pool_head)->active += needed;
1633 result += sizeof(ast_string_field_allocation);
1634 AST_STRING_FIELD_ALLOCATION(result) = needed;
1635 mgr->last_alloc = result;
1640 int __ast_string_field_ptr_grow(struct ast_string_field_mgr *mgr,
1641 struct ast_string_field_pool **pool_head, size_t needed,
1642 const ast_string_field *ptr)
1644 ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr);
1645 size_t space = (*pool_head)->size - (*pool_head)->used;
1647 if (*ptr != mgr->last_alloc) {
1655 (*pool_head)->used += grow;
1656 (*pool_head)->active += grow;
1657 AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
1662 void __ast_string_field_release_active(struct ast_string_field_pool *pool_head,
1663 const ast_string_field ptr)
1665 struct ast_string_field_pool *pool, *prev;
1667 if (ptr == __ast_string_field_empty) {
1671 for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) {
1672 if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) {
1673 pool->active -= AST_STRING_FIELD_ALLOCATION(ptr);
1674 if ((pool->active == 0) && prev) {
1675 prev->prev = pool->prev;
1683 void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
1684 struct ast_string_field_pool **pool_head,
1685 ast_string_field *ptr, const char *format, va_list ap1, va_list ap2)
1689 size_t space = (*pool_head)->size - (*pool_head)->used;
1693 /* if the field already has space allocated, try to reuse it;
1694 otherwise, try to use the empty space at the end of the current
1697 if (*ptr != __ast_string_field_empty) {
1698 target = (char *) *ptr;
1699 available = AST_STRING_FIELD_ALLOCATION(*ptr);
1700 if (*ptr == mgr->last_alloc) {
1704 target = (*pool_head)->base + (*pool_head)->used + sizeof(ast_string_field_allocation);
1705 available = space - sizeof(ast_string_field_allocation);
1708 needed = vsnprintf(target, available, format, ap1) + 1;
1712 if (needed > available) {
1713 /* the allocation could not be satisfied using the field's current allocation
1714 (if it has one), or the space available in the pool (if it does not). allocate
1715 space for it, adding a new string pool if necessary.
1717 if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) {
1720 vsprintf(target, format, ap2);
1721 __ast_string_field_release_active(*pool_head, *ptr);
1723 } else if (*ptr != target) {
1724 /* the allocation was satisfied using available space in the pool, but not
1725 using the space already allocated to the field
1727 __ast_string_field_release_active(*pool_head, *ptr);
1728 mgr->last_alloc = *ptr = target;
1729 AST_STRING_FIELD_ALLOCATION(target) = needed;
1730 (*pool_head)->used += needed + sizeof(ast_string_field_allocation);
1731 (*pool_head)->active += needed;
1732 } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) {
1733 /* the allocation was satisfied by using available space in the pool *and*
1734 the field was the last allocated field from the pool, so it grew
1736 (*pool_head)->used += grow;
1737 (*pool_head)->active += grow;
1738 AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
1742 void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
1743 struct ast_string_field_pool **pool_head,
1744 ast_string_field *ptr, const char *format, ...)
1748 va_start(ap1, format);
1749 va_start(ap2, format); /* va_copy does not exist on FreeBSD */
1751 __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2);
1757 void *__ast_calloc_with_stringfields(unsigned int num_structs, size_t struct_size, size_t field_mgr_offset,
1758 size_t field_mgr_pool_offset, size_t pool_size, const char *file,
1759 int lineno, const char *func)
1761 struct ast_string_field_mgr *mgr;
1762 struct ast_string_field_pool *pool;
1763 struct ast_string_field_pool **pool_head;
1764 size_t pool_size_needed = sizeof(*pool) + pool_size;
1765 size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed);
1769 #if defined(__AST_DEBUG_MALLOC)
1770 if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
1774 if (!(allocation = ast_calloc(num_structs, size_to_alloc))) {
1779 for (x = 0; x < num_structs; x++) {
1780 void *base = allocation + (size_to_alloc * x);
1783 mgr = base + field_mgr_offset;
1784 pool_head = base + field_mgr_pool_offset;
1785 pool = base + struct_size;
1787 p = (const char **) pool_head + 1;
1788 while ((struct ast_string_field_mgr *) p != mgr) {
1789 *p++ = __ast_string_field_empty;
1792 mgr->embedded_pool = pool;
1794 pool->size = size_to_alloc - struct_size - sizeof(*pool);
1795 #if defined(__AST_DEBUG_MALLOC)
1796 mgr->owner_file = file;
1797 mgr->owner_func = func;
1798 mgr->owner_line = lineno;
1805 /* end of stringfields support */
1807 AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
1809 int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
1812 ast_mutex_lock(&fetchadd_m);
1815 ast_mutex_unlock(&fetchadd_m);
1820 * get values from config variables.
1822 int ast_get_timeval(const char *src, struct timeval *dst, struct timeval _default, int *consumed)
1824 long double dtv = 0.0;
1832 if (ast_strlen_zero(src))
1835 /* only integer at the moment, but one day we could accept more formats */
1836 if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) {
1838 dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
1840 *consumed = scanned;
1847 * get values from config variables.
1849 int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
1859 if (ast_strlen_zero(src))
1862 /* only integer at the moment, but one day we could accept more formats */
1863 if (sscanf(src, "%30ld%n", &t, &scanned) == 1) {
1866 *consumed = scanned;
1872 void ast_enable_packet_fragmentation(int sock)
1874 #if defined(HAVE_IP_MTU_DISCOVER)
1875 int val = IP_PMTUDISC_DONT;
1877 if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
1878 ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
1879 #endif /* HAVE_IP_MTU_DISCOVER */
1882 int ast_mkdir(const char *path, int mode)
1885 int len = strlen(path), count = 0, x, piececount = 0;
1886 char *tmp = ast_strdupa(path);
1888 char *fullpath = alloca(len + 1);
1891 for (ptr = tmp; *ptr; ptr++) {
1896 /* Count the components to the directory path */
1897 pieces = alloca(count * sizeof(*pieces));
1898 for (ptr = tmp; *ptr; ptr++) {
1901 pieces[piececount++] = ptr + 1;
1906 for (x = 0; x < piececount; x++) {
1907 /* This looks funky, but the buffer is always ideally-sized, so it's fine. */
1908 strcat(fullpath, "/");
1909 strcat(fullpath, pieces[x]);
1910 res = mkdir(fullpath, mode);
1911 if (res && errno != EEXIST)
1917 int ast_utils_init(void)
1919 #ifdef HAVE_DEV_URANDOM
1920 dev_urandom_fd = open("/dev/urandom", O_RDONLY);
1923 #ifdef DEBUG_THREADS
1924 #if !defined(LOW_MEMORY)
1925 ast_cli_register_multiple(utils_cli, ARRAY_LEN(utils_cli));
1933 *\brief Parse digest authorization header.
1934 *\return Returns -1 if we have no auth or something wrong with digest.
1935 *\note This function may be used for Digest request and responce header.
1936 * request arg is set to nonzero, if we parse Digest Request.
1937 * pedantic arg can be set to nonzero if we need to do addition Digest check.
1939 int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic) {
1941 char *c, key[512], val[512], tmp[512];
1942 struct ast_str *str = ast_str_create(16);
1944 if (ast_strlen_zero(digest) || !d || !str) {
1949 ast_str_set(&str, 0, "%s", digest);
1951 c = ast_skip_blanks(ast_str_buffer(str));
1953 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
1954 ast_log(LOG_WARNING, "Missing Digest.\n");
1958 c += strlen("Digest ");
1960 /* lookup for keys/value pair */
1961 while (*c && *(c = ast_skip_blanks(c))) {
1964 while (*c && *c != '=' && *c != ',' && !isspace(*c)) {
1968 c = ast_skip_blanks(c);
1970 c = ast_skip_blanks(++c);
1973 /* in quotes. Skip first and look for last */
1975 while (*c && *c != '\"') {
1976 if (*c == '\\' && c[1] != '\0') { /* unescape chars */
1983 while (*c && *c != ',' && !isspace(*c)) {
1990 while (*c && *c != ',') {
1997 if (!strcasecmp(key, "username")) {
1998 ast_string_field_set(d, username, val);
1999 } else if (!strcasecmp(key, "realm")) {
2000 ast_string_field_set(d, realm, val);
2001 } else if (!strcasecmp(key, "nonce")) {
2002 ast_string_field_set(d, nonce, val);
2003 } else if (!strcasecmp(key, "uri")) {
2004 ast_string_field_set(d, uri, val);
2005 } else if (!strcasecmp(key, "domain")) {
2006 ast_string_field_set(d, domain, val);
2007 } else if (!strcasecmp(key, "response")) {
2008 ast_string_field_set(d, response, val);
2009 } else if (!strcasecmp(key, "algorithm")) {
2010 if (strcasecmp(val, "MD5")) {
2011 ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", val);
2014 } else if (!strcasecmp(key, "cnonce")) {
2015 ast_string_field_set(d, cnonce, val);
2016 } else if (!strcasecmp(key, "opaque")) {
2017 ast_string_field_set(d, opaque, val);
2018 } else if (!strcasecmp(key, "qop") && !strcasecmp(val, "auth")) {
2020 } else if (!strcasecmp(key, "nc")) {
2022 if (sscanf(val, "%30lx", &u) != 1) {
2023 ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", val);
2026 ast_string_field_set(d, nc, val);
2031 /* Digest checkout */
2032 if (ast_strlen_zero(d->realm) || ast_strlen_zero(d->nonce)) {
2033 /* "realm" and "nonce" MUST be always exist */
2038 /* Additional check for Digest response */
2039 if (ast_strlen_zero(d->username) || ast_strlen_zero(d->uri) || ast_strlen_zero(d->response)) {
2043 if (pedantic && d->qop && (ast_strlen_zero(d->cnonce) || ast_strlen_zero(d->nc))) {
2051 #ifndef __AST_DEBUG_MALLOC
2052 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...)
2058 if ((res = vasprintf(ret, fmt, ap)) == -1) {