document usage of 'transfer' configuration option for ISDN PRI switch-side transfers
[asterisk-bristuff.git] / main / utils.c
blob07669692fc058a8af838263025b9c5e4cde69708
1 /*
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.
17 /*! \file
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.
26 #include "asterisk.h"
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
30 #include <ctype.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <errno.h>
35 #include <stdarg.h>
36 #include <stdio.h>
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #include <netinet/in.h>
40 #include <arpa/inet.h>
42 #define AST_API_MODULE /* ensure that inlinable API functions will be built in lock.h if required */
43 #include "asterisk/lock.h"
44 #include "asterisk/io.h"
45 #include "asterisk/logger.h"
46 #include "asterisk/md5.h"
47 #include "asterisk/sha1.h"
48 #include "asterisk/options.h"
49 #include "asterisk/cli.h"
50 #include "asterisk/linkedlists.h"
52 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
53 #include "asterisk/strings.h"
55 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
56 #include "asterisk/time.h"
58 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
59 #include "asterisk/stringfields.h"
61 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
62 #include "asterisk/utils.h"
64 #define AST_API_MODULE
65 #include "asterisk/threadstorage.h"
67 static char base64[64];
68 static char b2a[256];
70 AST_THREADSTORAGE(inet_ntoa_buf, inet_ntoa_buf_init);
72 #if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6)
74 #define ERANGE 34 /*!< duh? ERANGE value copied from web... */
75 #undef gethostbyname
77 AST_MUTEX_DEFINE_STATIC(__mutex);
79 /*! \brief Reentrant replacement for gethostbyname for BSD-based systems.
80 \note This
81 routine is derived from code originally written and placed in the public
82 domain by Enzo Michelangeli <em@em.no-ip.com> */
84 static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
85 size_t buflen, struct hostent **result,
86 int *h_errnop)
88 int hsave;
89 struct hostent *ph;
90 ast_mutex_lock(&__mutex); /* begin critical area */
91 hsave = h_errno;
93 ph = gethostbyname(name);
94 *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
95 if (ph == NULL) {
96 *result = NULL;
97 } else {
98 char **p, **q;
99 char *pbuf;
100 int nbytes=0;
101 int naddr=0, naliases=0;
102 /* determine if we have enough space in buf */
104 /* count how many addresses */
105 for (p = ph->h_addr_list; *p != 0; p++) {
106 nbytes += ph->h_length; /* addresses */
107 nbytes += sizeof(*p); /* pointers */
108 naddr++;
110 nbytes += sizeof(*p); /* one more for the terminating NULL */
112 /* count how many aliases, and total length of strings */
113 for (p = ph->h_aliases; *p != 0; p++) {
114 nbytes += (strlen(*p)+1); /* aliases */
115 nbytes += sizeof(*p); /* pointers */
116 naliases++;
118 nbytes += sizeof(*p); /* one more for the terminating NULL */
120 /* here nbytes is the number of bytes required in buffer */
121 /* as a terminator must be there, the minimum value is ph->h_length */
122 if (nbytes > buflen) {
123 *result = NULL;
124 ast_mutex_unlock(&__mutex); /* end critical area */
125 return ERANGE; /* not enough space in buf!! */
128 /* There is enough space. Now we need to do a deep copy! */
129 /* Allocation in buffer:
130 from [0] to [(naddr-1) * sizeof(*p)]:
131 pointers to addresses
132 at [naddr * sizeof(*p)]:
133 NULL
134 from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
135 pointers to aliases
136 at [(naddr+naliases+1) * sizeof(*p)]:
137 NULL
138 then naddr addresses (fixed length), and naliases aliases (asciiz).
141 *ret = *ph; /* copy whole structure (not its address!) */
143 /* copy addresses */
144 q = (char **)buf; /* pointer to pointers area (type: char **) */
145 ret->h_addr_list = q; /* update pointer to address list */
146 pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
147 for (p = ph->h_addr_list; *p != 0; p++) {
148 memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
149 *q++ = pbuf; /* the pointer is the one inside buf... */
150 pbuf += ph->h_length; /* advance pbuf */
152 *q++ = NULL; /* address list terminator */
154 /* copy aliases */
155 ret->h_aliases = q; /* update pointer to aliases list */
156 for (p = ph->h_aliases; *p != 0; p++) {
157 strcpy(pbuf, *p); /* copy alias strings */
158 *q++ = pbuf; /* the pointer is the one inside buf... */
159 pbuf += strlen(*p); /* advance pbuf */
160 *pbuf++ = 0; /* string terminator */
162 *q++ = NULL; /* terminator */
164 strcpy(pbuf, ph->h_name); /* copy alias strings */
165 ret->h_name = pbuf;
166 pbuf += strlen(ph->h_name); /* advance pbuf */
167 *pbuf++ = 0; /* string terminator */
169 *result = ret; /* and let *result point to structure */
172 h_errno = hsave; /* restore h_errno */
173 ast_mutex_unlock(&__mutex); /* end critical area */
175 return (*result == NULL); /* return 0 on success, non-zero on error */
179 #endif
181 /*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the
182 standard gethostbyname (which is not thread safe)
184 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
186 int res;
187 int herrno;
188 int dots=0;
189 const char *s;
190 struct hostent *result = NULL;
191 /* Although it is perfectly legitimate to lookup a pure integer, for
192 the sake of the sanity of people who like to name their peers as
193 integers, we break with tradition and refuse to look up a
194 pure integer */
195 s = host;
196 res = 0;
197 while(s && *s) {
198 if (*s == '.')
199 dots++;
200 else if (!isdigit(*s))
201 break;
202 s++;
204 if (!s || !*s) {
205 /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
206 if (dots != 3)
207 return NULL;
208 memset(hp, 0, sizeof(struct ast_hostent));
209 hp->hp.h_addrtype = AF_INET;
210 hp->hp.h_addr_list = (void *) hp->buf;
211 hp->hp.h_addr = hp->buf + sizeof(void *);
212 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
213 return &hp->hp;
214 return NULL;
217 #ifdef HAVE_GETHOSTBYNAME_R_5
218 result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
220 if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
221 return NULL;
222 #else
223 res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
225 if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
226 return NULL;
227 #endif
228 return &hp->hp;
233 AST_MUTEX_DEFINE_STATIC(test_lock);
234 AST_MUTEX_DEFINE_STATIC(test_lock2);
235 static pthread_t test_thread;
236 static int lock_count = 0;
237 static int test_errors = 0;
239 /*! \brief This is a regression test for recursive mutexes.
240 test_for_thread_safety() will return 0 if recursive mutex locks are
241 working properly, and non-zero if they are not working properly. */
242 static void *test_thread_body(void *data)
244 ast_mutex_lock(&test_lock);
245 lock_count += 10;
246 if (lock_count != 10)
247 test_errors++;
248 ast_mutex_lock(&test_lock);
249 lock_count += 10;
250 if (lock_count != 20)
251 test_errors++;
252 ast_mutex_lock(&test_lock2);
253 ast_mutex_unlock(&test_lock);
254 lock_count -= 10;
255 if (lock_count != 10)
256 test_errors++;
257 ast_mutex_unlock(&test_lock);
258 lock_count -= 10;
259 ast_mutex_unlock(&test_lock2);
260 if (lock_count != 0)
261 test_errors++;
262 return NULL;
265 int test_for_thread_safety(void)
267 ast_mutex_lock(&test_lock2);
268 ast_mutex_lock(&test_lock);
269 lock_count += 1;
270 ast_mutex_lock(&test_lock);
271 lock_count += 1;
272 ast_pthread_create(&test_thread, NULL, test_thread_body, NULL);
273 usleep(100);
274 if (lock_count != 2)
275 test_errors++;
276 ast_mutex_unlock(&test_lock);
277 lock_count -= 1;
278 usleep(100);
279 if (lock_count != 1)
280 test_errors++;
281 ast_mutex_unlock(&test_lock);
282 lock_count -= 1;
283 if (lock_count != 0)
284 test_errors++;
285 ast_mutex_unlock(&test_lock2);
286 usleep(100);
287 if (lock_count != 0)
288 test_errors++;
289 pthread_join(test_thread, NULL);
290 return(test_errors); /* return 0 on success. */
293 /*! \brief Produce 32 char MD5 hash of value. */
294 void ast_md5_hash(char *output, char *input)
296 struct MD5Context md5;
297 unsigned char digest[16];
298 char *ptr;
299 int x;
301 MD5Init(&md5);
302 MD5Update(&md5, (unsigned char *)input, strlen(input));
303 MD5Final(digest, &md5);
304 ptr = output;
305 for (x = 0; x < 16; x++)
306 ptr += sprintf(ptr, "%2.2x", digest[x]);
309 /*! \brief Produce 40 char SHA1 hash of value. */
310 void ast_sha1_hash(char *output, char *input)
312 struct SHA1Context sha;
313 char *ptr;
314 int x;
315 uint8_t Message_Digest[20];
317 SHA1Reset(&sha);
319 SHA1Input(&sha, (const unsigned char *) input, strlen(input));
321 SHA1Result(&sha, Message_Digest);
322 ptr = output;
323 for (x = 0; x < 20; x++)
324 ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
327 /*! \brief decode BASE64 encoded text */
328 int ast_base64decode(unsigned char *dst, const char *src, int max)
330 int cnt = 0;
331 unsigned int byte = 0;
332 unsigned int bits = 0;
333 int incnt = 0;
334 while(*src && (cnt < max)) {
335 /* Shift in 6 bits of input */
336 byte <<= 6;
337 byte |= (b2a[(int)(*src)]) & 0x3f;
338 bits += 6;
339 src++;
340 incnt++;
341 /* If we have at least 8 bits left over, take that character
342 off the top */
343 if (bits >= 8) {
344 bits -= 8;
345 *dst = (byte >> bits) & 0xff;
346 dst++;
347 cnt++;
350 /* Dont worry about left over bits, they're extra anyway */
351 return cnt;
354 /*! \brief encode text to BASE64 coding */
355 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
357 int cnt = 0;
358 int col = 0;
359 unsigned int byte = 0;
360 int bits = 0;
361 int cntin = 0;
362 /* Reserve space for null byte at end of string */
363 max--;
364 while ((cntin < srclen) && (cnt < max)) {
365 byte <<= 8;
366 byte |= *(src++);
367 bits += 8;
368 cntin++;
369 if ((bits == 24) && (cnt + 4 <= max)) {
370 *dst++ = base64[(byte >> 18) & 0x3f];
371 *dst++ = base64[(byte >> 12) & 0x3f];
372 *dst++ = base64[(byte >> 6) & 0x3f];
373 *dst++ = base64[byte & 0x3f];
374 cnt += 4;
375 col += 4;
376 bits = 0;
377 byte = 0;
379 if (linebreaks && (cnt < max) && (col == 64)) {
380 *dst++ = '\n';
381 cnt++;
382 col = 0;
385 if (bits && (cnt + 4 <= max)) {
386 /* Add one last character for the remaining bits,
387 padding the rest with 0 */
388 byte <<= 24 - bits;
389 *dst++ = base64[(byte >> 18) & 0x3f];
390 *dst++ = base64[(byte >> 12) & 0x3f];
391 if (bits == 16)
392 *dst++ = base64[(byte >> 6) & 0x3f];
393 else
394 *dst++ = '=';
395 *dst++ = '=';
396 cnt += 4;
398 if (linebreaks && (cnt < max)) {
399 *dst++ = '\n';
400 cnt++;
402 *dst = '\0';
403 return cnt;
406 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
408 return ast_base64encode_full(dst, src, srclen, max, 0);
411 static void base64_init(void)
413 int x;
414 memset(b2a, -1, sizeof(b2a));
415 /* Initialize base-64 Conversion table */
416 for (x = 0; x < 26; x++) {
417 /* A-Z */
418 base64[x] = 'A' + x;
419 b2a['A' + x] = x;
420 /* a-z */
421 base64[x + 26] = 'a' + x;
422 b2a['a' + x] = x + 26;
423 /* 0-9 */
424 if (x < 10) {
425 base64[x + 52] = '0' + x;
426 b2a['0' + x] = x + 52;
429 base64[62] = '+';
430 base64[63] = '/';
431 b2a[(int)'+'] = 62;
432 b2a[(int)'/'] = 63;
435 /*! \brief ast_uri_encode: Turn text string to URI-encoded %XX version
436 \note At this point, we're converting from ISO-8859-x (8-bit), not UTF8
437 as in the SIP protocol spec
438 If doreserved == 1 we will convert reserved characters also.
439 RFC 2396, section 2.4
440 outbuf needs to have more memory allocated than the instring
441 to have room for the expansion. Every char that is converted
442 is replaced by three ASCII characters.
444 Note: The doreserved option is needed for replaces header in
445 SIP transfers.
447 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved)
449 char *reserved = ";/?:@&=+$, "; /* Reserved chars */
451 const char *ptr = string; /* Start with the string */
452 char *out = NULL;
453 char *buf = NULL;
455 ast_copy_string(outbuf, string, buflen);
457 /* If there's no characters to convert, just go through and don't do anything */
458 while (*ptr) {
459 if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
460 /* Oops, we need to start working here */
461 if (!buf) {
462 buf = outbuf;
463 out = buf + (ptr - string) ; /* Set output ptr */
465 out += sprintf(out, "%%%02x", (unsigned char) *ptr);
466 } else if (buf) {
467 *out = *ptr; /* Continue copying the string */
468 out++;
470 ptr++;
472 if (buf)
473 *out = '\0';
474 return outbuf;
477 /*! \brief ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string) */
478 void ast_uri_decode(char *s)
480 char *o;
481 unsigned int tmp;
483 for (o = s; *s; s++, o++) {
484 if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
485 /* have '%', two chars and correct parsing */
486 *o = tmp;
487 s += 2; /* Will be incremented once more when we break out */
488 } else /* all other cases, just copy */
489 *o = *s;
491 *o = '\0';
494 /*! \brief ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
495 const char *ast_inet_ntoa(struct in_addr ia)
497 char *buf;
499 if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
500 return "";
502 return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
505 #ifndef __linux__
506 #undef pthread_create /* For ast_pthread_create function only */
507 #endif /* !__linux__ */
509 #if !defined(LOW_MEMORY)
511 #ifdef DEBUG_THREADS
513 /*! \brief A reasonable maximum number of locks a thread would be holding ... */
514 #define AST_MAX_LOCKS 64
516 /* Allow direct use of pthread_mutex_t and friends */
517 #undef pthread_mutex_t
518 #undef pthread_mutex_lock
519 #undef pthread_mutex_unlock
520 #undef pthread_mutex_init
521 #undef pthread_mutex_destroy
523 /*!
524 * \brief Keep track of which locks a thread holds
526 * There is an instance of this struct for every active thread
528 struct thr_lock_info {
529 /*! The thread's ID */
530 pthread_t thread_id;
531 /*! The thread name which includes where the thread was started */
532 const char *thread_name;
533 /*! This is the actual container of info for what locks this thread holds */
534 struct {
535 const char *file;
536 int line_num;
537 const char *func;
538 const char *lock_name;
539 void *lock_addr;
540 int times_locked;
541 enum ast_lock_type type;
542 /*! This thread is waiting on this lock */
543 int pending:2;
544 } locks[AST_MAX_LOCKS];
545 /*! This is the number of locks currently held by this thread.
546 * The index (num_locks - 1) has the info on the last one in the
547 * locks member */
548 unsigned int num_locks;
549 /*! Protects the contents of the locks member
550 * Intentionally not ast_mutex_t */
551 pthread_mutex_t lock;
552 AST_LIST_ENTRY(thr_lock_info) entry;
555 /*!
556 * \brief Locked when accessing the lock_infos list
558 AST_MUTEX_DEFINE_STATIC(lock_infos_lock);
560 * \brief A list of each thread's lock info
562 static AST_LIST_HEAD_NOLOCK_STATIC(lock_infos, thr_lock_info);
565 * \brief Destroy a thread's lock info
567 * This gets called automatically when the thread stops
569 static void lock_info_destroy(void *data)
571 struct thr_lock_info *lock_info = data;
573 pthread_mutex_lock(&lock_infos_lock.mutex);
574 AST_LIST_REMOVE(&lock_infos, lock_info, entry);
575 pthread_mutex_unlock(&lock_infos_lock.mutex);
577 pthread_mutex_destroy(&lock_info->lock);
578 free((void *) lock_info->thread_name);
579 free(lock_info);
583 * \brief The thread storage key for per-thread lock info
585 AST_THREADSTORAGE_CUSTOM(thread_lock_info, thread_lock_info_init, lock_info_destroy);
587 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
588 int line_num, const char *func, const char *lock_name, void *lock_addr)
590 struct thr_lock_info *lock_info;
591 int i;
593 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
594 return;
596 pthread_mutex_lock(&lock_info->lock);
598 for (i = 0; i < lock_info->num_locks; i++) {
599 if (lock_info->locks[i].lock_addr == lock_addr) {
600 lock_info->locks[i].times_locked++;
601 pthread_mutex_unlock(&lock_info->lock);
602 return;
606 if (lock_info->num_locks == AST_MAX_LOCKS) {
607 /* Can't use ast_log here, because it will cause infinite recursion */
608 fprintf(stderr, "XXX ERROR XXX A thread holds more locks than '%d'."
609 " Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
610 pthread_mutex_unlock(&lock_info->lock);
611 return;
614 lock_info->locks[i].file = filename;
615 lock_info->locks[i].line_num = line_num;
616 lock_info->locks[i].func = func;
617 lock_info->locks[i].lock_name = lock_name;
618 lock_info->locks[i].lock_addr = lock_addr;
619 lock_info->locks[i].times_locked = 1;
620 lock_info->locks[i].type = type;
621 lock_info->locks[i].pending = 1;
622 lock_info->num_locks++;
624 pthread_mutex_unlock(&lock_info->lock);
627 void ast_mark_lock_acquired(void)
629 struct thr_lock_info *lock_info;
631 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
632 return;
634 pthread_mutex_lock(&lock_info->lock);
635 lock_info->locks[lock_info->num_locks - 1].pending = 0;
636 pthread_mutex_unlock(&lock_info->lock);
639 void ast_mark_lock_failed(void)
641 struct thr_lock_info *lock_info;
643 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
644 return;
646 pthread_mutex_lock(&lock_info->lock);
647 lock_info->locks[lock_info->num_locks - 1].pending = -1;
648 lock_info->locks[lock_info->num_locks - 1].times_locked--;
649 pthread_mutex_unlock(&lock_info->lock);
652 void ast_remove_lock_info(void *lock_addr)
654 struct thr_lock_info *lock_info;
655 int i = 0;
657 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
658 return;
660 pthread_mutex_lock(&lock_info->lock);
662 for (i = lock_info->num_locks - 1; i >= 0; i--) {
663 if (lock_info->locks[i].lock_addr == lock_addr)
664 break;
667 if (i == -1) {
668 /* Lock not found :( */
669 pthread_mutex_unlock(&lock_info->lock);
670 return;
673 if (lock_info->locks[i].times_locked > 1) {
674 lock_info->locks[i].times_locked--;
675 pthread_mutex_unlock(&lock_info->lock);
676 return;
679 if (i < lock_info->num_locks - 1) {
680 /* Not the last one ... *should* be rare! */
681 memmove(&lock_info->locks[i], &lock_info->locks[i + 1],
682 (lock_info->num_locks - (i + 1)) * sizeof(lock_info->locks[0]));
685 lock_info->num_locks--;
687 pthread_mutex_unlock(&lock_info->lock);
690 static const char *locktype2str(enum ast_lock_type type)
692 switch (type) {
693 case AST_MUTEX:
694 return "MUTEX";
695 case AST_RDLOCK:
696 return "RDLOCK";
697 case AST_WRLOCK:
698 return "WRLOCK";
701 return "UNKNOWN";
704 static int handle_show_locks(int fd, int argc, char *argv[])
706 struct thr_lock_info *lock_info;
707 struct ast_dynamic_str *str;
709 if (!(str = ast_dynamic_str_create(4096)))
710 return RESULT_FAILURE;
712 ast_dynamic_str_append(&str, 0, "\n"
713 "=======================================================================\n"
714 "=== Currently Held Locks ==============================================\n"
715 "=======================================================================\n"
716 "===\n"
717 "=== <file> <line num> <function> <lock name> <lock addr> (times locked)\n"
718 "===\n");
720 if (!str)
721 return RESULT_FAILURE;
723 pthread_mutex_lock(&lock_infos_lock.mutex);
724 AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
725 int i;
726 ast_dynamic_str_append(&str, 0, "=== Thread ID: %u (%s)\n", (int) lock_info->thread_id,
727 lock_info->thread_name);
728 pthread_mutex_lock(&lock_info->lock);
729 for (i = 0; str && i < lock_info->num_locks; i++) {
730 int j;
731 ast_mutex_t *lock;
733 ast_dynamic_str_append(&str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d)\n",
734 lock_info->locks[i].pending > 0 ? "Waiting for " :
735 lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
736 lock_info->locks[i].file,
737 locktype2str(lock_info->locks[i].type),
738 lock_info->locks[i].line_num,
739 lock_info->locks[i].func, lock_info->locks[i].lock_name,
740 lock_info->locks[i].lock_addr,
741 lock_info->locks[i].times_locked);
743 if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
744 continue;
746 /* We only have further details for mutexes right now */
747 if (lock_info->locks[i].type != AST_MUTEX)
748 continue;
750 lock = lock_info->locks[i].lock_addr;
752 ast_reentrancy_lock(lock);
753 for (j = 0; str && j < lock->reentrancy; j++) {
754 ast_dynamic_str_append(&str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n",
755 lock->file[j], lock->lineno[j], lock->func[j]);
757 ast_reentrancy_unlock(lock);
759 pthread_mutex_unlock(&lock_info->lock);
760 if (!str)
761 break;
762 ast_dynamic_str_append(&str, 0, "=== -------------------------------------------------------------------\n"
763 "===\n");
764 if (!str)
765 break;
767 pthread_mutex_unlock(&lock_infos_lock.mutex);
769 if (!str)
770 return RESULT_FAILURE;
772 ast_dynamic_str_append(&str, 0, "=======================================================================\n"
773 "\n");
775 if (!str)
776 return RESULT_FAILURE;
778 ast_cli(fd, "%s", str->str);
780 free(str);
782 return RESULT_SUCCESS;
785 static char show_locks_help[] =
786 "Usage: core show locks\n"
787 " This command is for lock debugging. It prints out which locks\n"
788 "are owned by each active thread.\n";
790 static struct ast_cli_entry utils_cli[] = {
791 { { "core", "show", "locks", NULL }, handle_show_locks,
792 "Show which locks are locked by which thread", show_locks_help },
795 #endif /* DEBUG_THREADS */
800 * support for 'show threads'. The start routine is wrapped by
801 * dummy_start(), so that ast_register_thread() and
802 * ast_unregister_thread() know the thread identifier.
804 struct thr_arg {
805 void *(*start_routine)(void *);
806 void *data;
807 char *name;
811 * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
812 * are odd macros which start and end a block, so they _must_ be
813 * used in pairs (the latter with a '1' argument to call the
814 * handler on exit.
815 * On BSD we don't need this, but we keep it for compatibility.
817 static void *dummy_start(void *data)
819 void *ret;
820 struct thr_arg a = *((struct thr_arg *) data); /* make a local copy */
821 #ifdef DEBUG_THREADS
822 struct thr_lock_info *lock_info;
823 pthread_mutexattr_t mutex_attr;
824 #endif
826 /* note that even though data->name is a pointer to allocated memory,
827 we are not freeing it here because ast_register_thread is going to
828 keep a copy of the pointer and then ast_unregister_thread will
829 free the memory
831 free(data);
832 ast_register_thread(a.name);
833 pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());
835 #ifdef DEBUG_THREADS
836 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
837 return NULL;
839 lock_info->thread_id = pthread_self();
840 lock_info->thread_name = strdup(a.name);
842 pthread_mutexattr_init(&mutex_attr);
843 pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND);
844 pthread_mutex_init(&lock_info->lock, &mutex_attr);
845 pthread_mutexattr_destroy(&mutex_attr);
847 pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
848 AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry);
849 pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
850 #endif /* DEBUG_THREADS */
852 ret = a.start_routine(a.data);
854 pthread_cleanup_pop(1);
856 return ret;
859 #endif /* !LOW_MEMORY */
861 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
862 void *data, size_t stacksize, const char *file, const char *caller,
863 int line, const char *start_fn)
865 #if !defined(LOW_MEMORY)
866 struct thr_arg *a;
867 #endif
869 if (!attr) {
870 attr = alloca(sizeof(*attr));
871 pthread_attr_init(attr);
874 #ifdef __linux__
875 /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
876 which is kind of useless. Change this here to
877 PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
878 priority will propagate down to new threads by default.
879 This does mean that callers cannot set a different priority using
880 PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
881 the priority afterwards with pthread_setschedparam(). */
882 if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
883 ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
884 #endif
886 if (!stacksize)
887 stacksize = AST_STACKSIZE;
889 if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
890 ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));
892 #if !defined(LOW_MEMORY)
893 if ((a = ast_malloc(sizeof(*a)))) {
894 a->start_routine = start_routine;
895 a->data = data;
896 start_routine = dummy_start;
897 asprintf(&a->name, "%-20s started at [%5d] %s %s()",
898 start_fn, line, file, caller);
899 data = a;
901 #endif /* !LOW_MEMORY */
903 return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
906 int ast_wait_for_input(int fd, int ms)
908 struct pollfd pfd[1];
909 memset(pfd, 0, sizeof(pfd));
910 pfd[0].fd = fd;
911 pfd[0].events = POLLIN|POLLPRI;
912 return poll(pfd, 1, ms);
915 int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
917 /* Try to write string, but wait no more than ms milliseconds
918 before timing out */
919 int res = 0;
920 struct pollfd fds[1];
921 while (len) {
922 res = write(fd, s, len);
923 if ((res < 0) && (errno != EAGAIN)) {
924 return -1;
926 if (res < 0)
927 res = 0;
928 len -= res;
929 s += res;
930 res = 0;
931 if (len) {
932 fds[0].fd = fd;
933 fds[0].events = POLLOUT;
934 /* Wait until writable again */
935 res = poll(fds, 1, timeoutms);
936 if (res < 1)
937 return -1;
940 return res;
943 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
945 char *e;
946 char *q;
948 s = ast_strip(s);
949 if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
950 e = s + strlen(s) - 1;
951 if (*e == *(end_quotes + (q - beg_quotes))) {
952 s++;
953 *e = '\0';
957 return s;
960 char *ast_unescape_semicolon(char *s)
962 char *e;
963 char *work = s;
965 while ((e = strchr(work, ';'))) {
966 if ((e > work) && (*(e-1) == '\\')) {
967 memmove(e - 1, e, strlen(e) + 1);
968 work = e;
969 } else {
970 work = e + 1;
974 return s;
977 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
979 int result;
981 if (!buffer || !*buffer || !space || !*space)
982 return -1;
984 result = vsnprintf(*buffer, *space, fmt, ap);
986 if (result < 0)
987 return -1;
988 else if (result > *space)
989 result = *space;
991 *buffer += result;
992 *space -= result;
993 return 0;
996 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
998 va_list ap;
999 int result;
1001 va_start(ap, fmt);
1002 result = ast_build_string_va(buffer, space, fmt, ap);
1003 va_end(ap);
1005 return result;
1008 int ast_true(const char *s)
1010 if (ast_strlen_zero(s))
1011 return 0;
1013 /* Determine if this is a true value */
1014 if (!strcasecmp(s, "yes") ||
1015 !strcasecmp(s, "true") ||
1016 !strcasecmp(s, "y") ||
1017 !strcasecmp(s, "t") ||
1018 !strcasecmp(s, "1") ||
1019 !strcasecmp(s, "on"))
1020 return -1;
1022 return 0;
1025 int ast_false(const char *s)
1027 if (ast_strlen_zero(s))
1028 return 0;
1030 /* Determine if this is a false value */
1031 if (!strcasecmp(s, "no") ||
1032 !strcasecmp(s, "false") ||
1033 !strcasecmp(s, "n") ||
1034 !strcasecmp(s, "f") ||
1035 !strcasecmp(s, "0") ||
1036 !strcasecmp(s, "off"))
1037 return -1;
1039 return 0;
1042 #define ONE_MILLION 1000000
1044 * put timeval in a valid range. usec is 0..999999
1045 * negative values are not allowed and truncated.
1047 static struct timeval tvfix(struct timeval a)
1049 if (a.tv_usec >= ONE_MILLION) {
1050 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
1051 a.tv_sec, (long int) a.tv_usec);
1052 a.tv_sec += a.tv_usec / ONE_MILLION;
1053 a.tv_usec %= ONE_MILLION;
1054 } else if (a.tv_usec < 0) {
1055 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
1056 a.tv_sec, (long int) a.tv_usec);
1057 a.tv_usec = 0;
1059 return a;
1062 struct timeval ast_tvadd(struct timeval a, struct timeval b)
1064 /* consistency checks to guarantee usec in 0..999999 */
1065 a = tvfix(a);
1066 b = tvfix(b);
1067 a.tv_sec += b.tv_sec;
1068 a.tv_usec += b.tv_usec;
1069 if (a.tv_usec >= ONE_MILLION) {
1070 a.tv_sec++;
1071 a.tv_usec -= ONE_MILLION;
1073 return a;
1076 struct timeval ast_tvsub(struct timeval a, struct timeval b)
1078 /* consistency checks to guarantee usec in 0..999999 */
1079 a = tvfix(a);
1080 b = tvfix(b);
1081 a.tv_sec -= b.tv_sec;
1082 a.tv_usec -= b.tv_usec;
1083 if (a.tv_usec < 0) {
1084 a.tv_sec-- ;
1085 a.tv_usec += ONE_MILLION;
1087 return a;
1089 #undef ONE_MILLION
1091 /*! \brief glibc puts a lock inside random(3), so that the results are thread-safe.
1092 * BSD libc (and others) do not. */
1093 #ifndef linux
1095 AST_MUTEX_DEFINE_STATIC(randomlock);
1097 long int ast_random(void)
1099 long int res;
1100 ast_mutex_lock(&randomlock);
1101 res = random();
1102 ast_mutex_unlock(&randomlock);
1103 return res;
1105 #endif
1107 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
1109 char *dataPut = start;
1110 int inEscape = 0;
1111 int inQuotes = 0;
1113 for (; *start; start++) {
1114 if (inEscape) {
1115 *dataPut++ = *start; /* Always goes verbatim */
1116 inEscape = 0;
1117 } else {
1118 if (*start == '\\') {
1119 inEscape = 1; /* Do not copy \ into the data */
1120 } else if (*start == '\'') {
1121 inQuotes = 1 - inQuotes; /* Do not copy ' into the data */
1122 } else {
1123 /* Replace , with |, unless in quotes */
1124 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
1128 if (start != dataPut)
1129 *dataPut = 0;
1130 return dataPut;
1133 void ast_join(char *s, size_t len, char * const w[])
1135 int x, ofs = 0;
1136 const char *src;
1138 /* Join words into a string */
1139 if (!s)
1140 return;
1141 for (x = 0; ofs < len && w[x]; x++) {
1142 if (x > 0)
1143 s[ofs++] = ' ';
1144 for (src = w[x]; *src && ofs < len; src++)
1145 s[ofs++] = *src;
1147 if (ofs == len)
1148 ofs--;
1149 s[ofs] = '\0';
1152 const char __ast_string_field_empty[] = "";
1154 static int add_string_pool(struct ast_string_field_mgr *mgr, size_t size)
1156 struct ast_string_field_pool *pool;
1158 if (!(pool = ast_calloc(1, sizeof(*pool) + size)))
1159 return -1;
1161 pool->prev = mgr->pool;
1162 mgr->pool = pool;
1163 mgr->size = size;
1164 mgr->space = size;
1165 mgr->used = 0;
1167 return 0;
1170 int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
1171 ast_string_field *fields, int num_fields)
1173 int index;
1175 if (add_string_pool(mgr, size))
1176 return -1;
1178 for (index = 0; index < num_fields; index++)
1179 fields[index] = __ast_string_field_empty;
1181 return 0;
1184 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr, size_t needed,
1185 ast_string_field *fields, int num_fields)
1187 char *result = NULL;
1189 if (__builtin_expect(needed > mgr->space, 0)) {
1190 size_t new_size = mgr->size * 2;
1192 while (new_size < needed)
1193 new_size *= 2;
1195 if (add_string_pool(mgr, new_size))
1196 return NULL;
1199 result = mgr->pool->base + mgr->used;
1200 mgr->used += needed;
1201 mgr->space -= needed;
1202 return result;
1205 void __ast_string_field_index_build_va(struct ast_string_field_mgr *mgr,
1206 ast_string_field *fields, int num_fields,
1207 int index, const char *format, va_list ap1, va_list ap2)
1209 size_t needed;
1211 needed = vsnprintf(mgr->pool->base + mgr->used, mgr->space, format, ap1) + 1;
1213 va_end(ap1);
1215 if (needed > mgr->space) {
1216 size_t new_size = mgr->size * 2;
1218 while (new_size < needed)
1219 new_size *= 2;
1221 if (add_string_pool(mgr, new_size))
1222 return;
1224 vsprintf(mgr->pool->base + mgr->used, format, ap2);
1227 fields[index] = mgr->pool->base + mgr->used;
1228 mgr->used += needed;
1229 mgr->space -= needed;
1232 void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
1233 ast_string_field *fields, int num_fields,
1234 int index, const char *format, ...)
1236 va_list ap1, ap2;
1238 va_start(ap1, format);
1239 va_start(ap2, format); /* va_copy does not exist on FreeBSD */
1241 __ast_string_field_index_build_va(mgr, fields, num_fields, index, format, ap1, ap2);
1243 va_end(ap1);
1244 va_end(ap2);
1247 AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
1249 int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
1251 int ret;
1252 ast_mutex_lock(&fetchadd_m);
1253 ret = *p;
1254 *p += v;
1255 ast_mutex_unlock(&fetchadd_m);
1256 return ret;
1259 /*! \brief
1260 * get values from config variables.
1262 int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
1264 long t;
1265 int scanned;
1267 if (dst == NULL)
1268 return -1;
1270 *dst = _default;
1272 if (ast_strlen_zero(src))
1273 return -1;
1275 /* only integer at the moment, but one day we could accept more formats */
1276 if (sscanf(src, "%ld%n", &t, &scanned) == 1) {
1277 *dst = t;
1278 if (consumed)
1279 *consumed = scanned;
1280 return 0;
1281 } else
1282 return -1;
1285 int ast_dynamic_str_thread_build_va(struct ast_dynamic_str **buf, size_t max_len,
1286 struct ast_threadstorage *ts, int append, const char *fmt, va_list ap)
1288 int res;
1289 int offset = (append && (*buf)->len) ? strlen((*buf)->str) : 0;
1290 #if defined(DEBUG_THREADLOCALS)
1291 struct ast_dynamic_str *old_buf = *buf;
1292 #endif /* defined(DEBUG_THREADLOCALS) */
1294 res = vsnprintf((*buf)->str + offset, (*buf)->len - offset, fmt, ap);
1296 /* Check to see if there was not enough space in the string buffer to prepare
1297 * the string. Also, if a maximum length is present, make sure the current
1298 * length is less than the maximum before increasing the size. */
1299 if ((res + offset + 1) > (*buf)->len && (max_len ? ((*buf)->len < max_len) : 1)) {
1300 /* Set the new size of the string buffer to be the size needed
1301 * to hold the resulting string (res) plus one byte for the
1302 * terminating '\0'. If this size is greater than the max, set
1303 * the new length to be the maximum allowed. */
1304 if (max_len)
1305 (*buf)->len = ((res + offset + 1) < max_len) ? (res + offset + 1) : max_len;
1306 else
1307 (*buf)->len = res + offset + 1;
1309 if (!(*buf = ast_realloc(*buf, (*buf)->len + sizeof(*(*buf)))))
1310 return AST_DYNSTR_BUILD_FAILED;
1312 if (append)
1313 (*buf)->str[offset] = '\0';
1315 if (ts) {
1316 pthread_setspecific(ts->key, *buf);
1317 #if defined(DEBUG_THREADLOCALS)
1318 __ast_threadstorage_object_replace(old_buf, *buf, (*buf)->len + sizeof(*(*buf)));
1319 #endif /* defined(DEBUG_THREADLOCALS) */
1322 /* va_end() and va_start() must be done before calling
1323 * vsnprintf() again. */
1324 return AST_DYNSTR_BUILD_RETRY;
1327 return res;
1330 void ast_enable_packet_fragmentation(int sock)
1332 #if defined(HAVE_IP_MTU_DISCOVER)
1333 int val = IP_PMTUDISC_DONT;
1335 if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
1336 ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
1337 #endif /* HAVE_IP_MTU_DISCOVER */
1340 int ast_utils_init(void)
1342 base64_init();
1343 #ifdef DEBUG_THREADS
1344 ast_cli_register_multiple(utils_cli, sizeof(utils_cli) / sizeof(utils_cli[0]));
1345 #endif
1346 return 0;