update cleancount because the channel structure changed today
[asterisk-bristuff.git] / utils.c
blobef251bfa96ddb668b2b15b1b129f2a1ab27dd203
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"
50 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
51 #include "asterisk/strings.h"
53 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
54 #include "asterisk/time.h"
56 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
57 #include "asterisk/stringfields.h"
59 #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */
60 #include "asterisk/utils.h"
62 static char base64[64];
63 static char b2a[256];
65 static pthread_key_t inet_ntoa_buf_key;
66 static pthread_once_t inet_ntoa_buf_once = PTHREAD_ONCE_INIT;
68 #ifdef __AST_DEBUG_MALLOC
69 static void FREE(void *ptr)
71 free(ptr);
73 #else
74 #define FREE free
75 #endif
77 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) || defined(__CYGWIN__)
79 #define ERANGE 34 /*!< duh? ERANGE value copied from web... */
80 #undef gethostbyname
82 AST_MUTEX_DEFINE_STATIC(__mutex);
84 /*! \brief Reentrant replacement for gethostbyname for BSD-based systems.
85 \note This
86 routine is derived from code originally written and placed in the public
87 domain by Enzo Michelangeli <em@em.no-ip.com> */
89 static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
90 size_t buflen, struct hostent **result,
91 int *h_errnop)
93 int hsave;
94 struct hostent *ph;
95 ast_mutex_lock(&__mutex); /* begin critical area */
96 hsave = h_errno;
98 ph = gethostbyname(name);
99 *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
100 if (ph == NULL) {
101 *result = NULL;
102 } else {
103 char **p, **q;
104 char *pbuf;
105 int nbytes=0;
106 int naddr=0, naliases=0;
107 /* determine if we have enough space in buf */
109 /* count how many addresses */
110 for (p = ph->h_addr_list; *p != 0; p++) {
111 nbytes += ph->h_length; /* addresses */
112 nbytes += sizeof(*p); /* pointers */
113 naddr++;
115 nbytes += sizeof(*p); /* one more for the terminating NULL */
117 /* count how many aliases, and total length of strings */
118 for (p = ph->h_aliases; *p != 0; p++) {
119 nbytes += (strlen(*p)+1); /* aliases */
120 nbytes += sizeof(*p); /* pointers */
121 naliases++;
123 nbytes += sizeof(*p); /* one more for the terminating NULL */
125 /* here nbytes is the number of bytes required in buffer */
126 /* as a terminator must be there, the minimum value is ph->h_length */
127 if (nbytes > buflen) {
128 *result = NULL;
129 ast_mutex_unlock(&__mutex); /* end critical area */
130 return ERANGE; /* not enough space in buf!! */
133 /* There is enough space. Now we need to do a deep copy! */
134 /* Allocation in buffer:
135 from [0] to [(naddr-1) * sizeof(*p)]:
136 pointers to addresses
137 at [naddr * sizeof(*p)]:
138 NULL
139 from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
140 pointers to aliases
141 at [(naddr+naliases+1) * sizeof(*p)]:
142 NULL
143 then naddr addresses (fixed length), and naliases aliases (asciiz).
146 *ret = *ph; /* copy whole structure (not its address!) */
148 /* copy addresses */
149 q = (char **)buf; /* pointer to pointers area (type: char **) */
150 ret->h_addr_list = q; /* update pointer to address list */
151 pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
152 for (p = ph->h_addr_list; *p != 0; p++) {
153 memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
154 *q++ = pbuf; /* the pointer is the one inside buf... */
155 pbuf += ph->h_length; /* advance pbuf */
157 *q++ = NULL; /* address list terminator */
159 /* copy aliases */
160 ret->h_aliases = q; /* update pointer to aliases list */
161 for (p = ph->h_aliases; *p != 0; p++) {
162 strcpy(pbuf, *p); /* copy alias strings */
163 *q++ = pbuf; /* the pointer is the one inside buf... */
164 pbuf += strlen(*p); /* advance pbuf */
165 *pbuf++ = 0; /* string terminator */
167 *q++ = NULL; /* terminator */
169 strcpy(pbuf, ph->h_name); /* copy alias strings */
170 ret->h_name = pbuf;
171 pbuf += strlen(ph->h_name); /* advance pbuf */
172 *pbuf++ = 0; /* string terminator */
174 *result = ret; /* and let *result point to structure */
177 h_errno = hsave; /* restore h_errno */
178 ast_mutex_unlock(&__mutex); /* end critical area */
180 return (*result == NULL); /* return 0 on success, non-zero on error */
184 #endif
186 /*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the
187 standard gethostbyname (which is not thread safe)
189 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
191 int res;
192 int herrno;
193 int dots=0;
194 const char *s;
195 struct hostent *result = NULL;
196 /* Although it is perfectly legitimate to lookup a pure integer, for
197 the sake of the sanity of people who like to name their peers as
198 integers, we break with tradition and refuse to look up a
199 pure integer */
200 s = host;
201 res = 0;
202 while(s && *s) {
203 if (*s == '.')
204 dots++;
205 else if (!isdigit(*s))
206 break;
207 s++;
209 if (!s || !*s) {
210 /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
211 if (dots != 3)
212 return NULL;
213 memset(hp, 0, sizeof(struct ast_hostent));
214 hp->hp.h_addr_list = (void *) hp->buf;
215 hp->hp.h_addr = hp->buf + sizeof(void *);
216 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
217 return &hp->hp;
218 return NULL;
221 #ifdef SOLARIS
222 result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
224 if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
225 return NULL;
226 #else
227 res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
229 if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
230 return NULL;
231 #endif
232 return &hp->hp;
237 AST_MUTEX_DEFINE_STATIC(test_lock);
238 AST_MUTEX_DEFINE_STATIC(test_lock2);
239 static pthread_t test_thread;
240 static int lock_count = 0;
241 static int test_errors = 0;
243 /*! \brief This is a regression test for recursive mutexes.
244 test_for_thread_safety() will return 0 if recursive mutex locks are
245 working properly, and non-zero if they are not working properly. */
246 static void *test_thread_body(void *data)
248 ast_mutex_lock(&test_lock);
249 lock_count += 10;
250 if (lock_count != 10)
251 test_errors++;
252 ast_mutex_lock(&test_lock);
253 lock_count += 10;
254 if (lock_count != 20)
255 test_errors++;
256 ast_mutex_lock(&test_lock2);
257 ast_mutex_unlock(&test_lock);
258 lock_count -= 10;
259 if (lock_count != 10)
260 test_errors++;
261 ast_mutex_unlock(&test_lock);
262 lock_count -= 10;
263 ast_mutex_unlock(&test_lock2);
264 if (lock_count != 0)
265 test_errors++;
266 return NULL;
269 int test_for_thread_safety(void)
271 ast_mutex_lock(&test_lock2);
272 ast_mutex_lock(&test_lock);
273 lock_count += 1;
274 ast_mutex_lock(&test_lock);
275 lock_count += 1;
276 ast_pthread_create(&test_thread, NULL, test_thread_body, NULL);
277 usleep(100);
278 if (lock_count != 2)
279 test_errors++;
280 ast_mutex_unlock(&test_lock);
281 lock_count -= 1;
282 usleep(100);
283 if (lock_count != 1)
284 test_errors++;
285 ast_mutex_unlock(&test_lock);
286 lock_count -= 1;
287 if (lock_count != 0)
288 test_errors++;
289 ast_mutex_unlock(&test_lock2);
290 usleep(100);
291 if (lock_count != 0)
292 test_errors++;
293 pthread_join(test_thread, NULL);
294 return(test_errors); /* return 0 on success. */
297 /*! \brief Produce 32 char MD5 hash of value. */
298 void ast_md5_hash(char *output, char *input)
300 struct MD5Context md5;
301 unsigned char digest[16];
302 char *ptr;
303 int x;
305 MD5Init(&md5);
306 MD5Update(&md5, (unsigned char *)input, strlen(input));
307 MD5Final(digest, &md5);
308 ptr = output;
309 for (x = 0; x < 16; x++)
310 ptr += sprintf(ptr, "%2.2x", digest[x]);
313 /*! \brief Produce 40 char SHA1 hash of value. */
314 void ast_sha1_hash(char *output, char *input)
316 struct SHA1Context sha;
317 char *ptr;
318 int x;
319 uint8_t Message_Digest[20];
321 SHA1Reset(&sha);
323 SHA1Input(&sha, (const unsigned char *) input, strlen(input));
325 SHA1Result(&sha, Message_Digest);
326 ptr = output;
327 for (x = 0; x < 20; x++)
328 ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
331 /*! \brief decode BASE64 encoded text */
332 int ast_base64decode(unsigned char *dst, const char *src, int max)
334 int cnt = 0;
335 unsigned int byte = 0;
336 unsigned int bits = 0;
337 int incnt = 0;
338 while(*src && (cnt < max)) {
339 /* Shift in 6 bits of input */
340 byte <<= 6;
341 byte |= (b2a[(int)(*src)]) & 0x3f;
342 bits += 6;
343 src++;
344 incnt++;
345 /* If we have at least 8 bits left over, take that character
346 off the top */
347 if (bits >= 8) {
348 bits -= 8;
349 *dst = (byte >> bits) & 0xff;
350 dst++;
351 cnt++;
354 /* Dont worry about left over bits, they're extra anyway */
355 return cnt;
358 /*! \brief encode text to BASE64 coding */
359 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
361 int cnt = 0;
362 int col = 0;
363 unsigned int byte = 0;
364 int bits = 0;
365 int cntin = 0;
366 /* Reserve space for null byte at end of string */
367 max--;
368 while ((cntin < srclen) && (cnt < max)) {
369 byte <<= 8;
370 byte |= *(src++);
371 bits += 8;
372 cntin++;
373 if ((bits == 24) && (cnt + 4 < max)) {
374 *dst++ = base64[(byte >> 18) & 0x3f];
375 *dst++ = base64[(byte >> 12) & 0x3f];
376 *dst++ = base64[(byte >> 6) & 0x3f];
377 *dst++ = base64[byte & 0x3f];
378 cnt += 4;
379 col += 4;
380 bits = 0;
381 byte = 0;
383 if (linebreaks && (cnt < max) && (col == 64)) {
384 *dst++ = '\n';
385 cnt++;
386 col = 0;
389 if (bits && (cnt + 4 < max)) {
390 /* Add one last character for the remaining bits,
391 padding the rest with 0 */
392 byte <<= 24 - bits;
393 *dst++ = base64[(byte >> 18) & 0x3f];
394 *dst++ = base64[(byte >> 12) & 0x3f];
395 if (bits == 16)
396 *dst++ = base64[(byte >> 6) & 0x3f];
397 else
398 *dst++ = '=';
399 *dst++ = '=';
400 cnt += 4;
402 if (linebreaks && (cnt < max)) {
403 *dst++ = '\n';
404 cnt++;
406 *dst = '\0';
407 return cnt;
410 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
412 return ast_base64encode_full(dst, src, srclen, max, 0);
415 static void base64_init(void)
417 int x;
418 memset(b2a, -1, sizeof(b2a));
419 /* Initialize base-64 Conversion table */
420 for (x = 0; x < 26; x++) {
421 /* A-Z */
422 base64[x] = 'A' + x;
423 b2a['A' + x] = x;
424 /* a-z */
425 base64[x + 26] = 'a' + x;
426 b2a['a' + x] = x + 26;
427 /* 0-9 */
428 if (x < 10) {
429 base64[x + 52] = '0' + x;
430 b2a['0' + x] = x + 52;
433 base64[62] = '+';
434 base64[63] = '/';
435 b2a[(int)'+'] = 62;
436 b2a[(int)'/'] = 63;
439 /*! \brief ast_uri_encode: Turn text string to URI-encoded %XX version
440 \note At this point, we're converting from ISO-8859-x (8-bit), not UTF8
441 as in the SIP protocol spec
442 If doreserved == 1 we will convert reserved characters also.
443 RFC 2396, section 2.4
444 outbuf needs to have more memory allocated than the instring
445 to have room for the expansion. Every char that is converted
446 is replaced by three ASCII characters.
448 Note: The doreserved option is needed for replaces header in
449 SIP transfers.
451 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved)
453 char *reserved = ";/?:@&=+$, "; /* Reserved chars */
455 const char *ptr = string; /* Start with the string */
456 char *out = NULL;
457 char *buf = NULL;
459 strncpy(outbuf, string, buflen);
461 /* If there's no characters to convert, just go through and don't do anything */
462 while (*ptr) {
463 if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
464 /* Oops, we need to start working here */
465 if (!buf) {
466 buf = outbuf;
467 out = buf + (ptr - string) ; /* Set output ptr */
469 out += sprintf(out, "%%%02x", (unsigned char) *ptr);
470 } else if (buf) {
471 *out = *ptr; /* Continue copying the string */
472 out++;
474 ptr++;
476 if (buf)
477 *out = '\0';
478 return outbuf;
481 /*! \brief ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string) */
482 void ast_uri_decode(char *s)
484 char *o;
485 unsigned int tmp;
487 for (o = s; *s; s++, o++) {
488 if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
489 /* have '%', two chars and correct parsing */
490 *o = tmp;
491 s += 2; /* Will be incremented once more when we break out */
492 } else /* all other cases, just copy */
493 *o = *s;
495 *o = '\0';
498 static void inet_ntoa_buf_key_create(void)
500 pthread_key_create(&inet_ntoa_buf_key, FREE);
503 /*! \brief ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
504 const char *ast_inet_ntoa(struct in_addr ia)
506 char *buf;
508 pthread_once(&inet_ntoa_buf_once, inet_ntoa_buf_key_create);
509 if (!(buf = pthread_getspecific(inet_ntoa_buf_key))) {
510 if (!(buf = ast_calloc(1, INET_ADDRSTRLEN)))
511 return NULL;
512 pthread_setspecific(inet_ntoa_buf_key, buf);
515 return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
518 int ast_utils_init(void)
520 base64_init();
521 return 0;
524 #ifndef __linux__
525 #undef pthread_create /* For ast_pthread_create function only */
526 #endif /* !__linux__ */
529 * support for 'show threads'. The start routine is wrapped by
530 * dummy_start(), so that ast_register_thread() and
531 * ast_unregister_thread() know the thread identifier.
533 struct thr_arg {
534 void *(*start_routine)(void *);
535 void *data;
536 char *name;
540 * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
541 * are odd macros which start and end a block, so they _must_ be
542 * used in pairs (the latter with a '1' argument to call the
543 * handler on exit.
544 * On BSD we don't need this, but we keep it for compatibility with the MAC.
546 static void *dummy_start(void *data)
548 void *ret;
549 struct thr_arg a = *((struct thr_arg *)data); /* make a local copy */
551 free(data);
552 ast_register_thread(a.name);
553 pthread_cleanup_push(ast_unregister_thread, (void *)pthread_self()); /* on unregister */
554 ret = a.start_routine(a.data);
555 pthread_cleanup_pop(1);
556 return ret;
559 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize,
560 const char *file, const char *caller, int line, const char *start_fn)
562 struct thr_arg *a;
564 pthread_attr_t lattr;
565 if (!attr) {
566 pthread_attr_init(&lattr);
567 attr = &lattr;
569 #ifdef __linux__
570 /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
571 which is kind of useless. Change this here to
572 PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
573 priority will propagate down to new threads by default.
574 This does mean that callers cannot set a different priority using
575 PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
576 the priority afterwards with pthread_setschedparam(). */
577 errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED);
578 if (errno)
579 ast_log(LOG_WARNING, "pthread_attr_setinheritsched returned non-zero: %s\n", strerror(errno));
580 #endif
582 if (!stacksize)
583 stacksize = AST_STACKSIZE;
584 errno = pthread_attr_setstacksize(attr, stacksize);
585 if (errno)
586 ast_log(LOG_WARNING, "pthread_attr_setstacksize returned non-zero: %s\n", strerror(errno));
587 a = ast_malloc(sizeof(*a));
588 if (!a)
589 ast_log(LOG_WARNING, "no memory, thread %s will not be listed\n", start_fn);
590 else { /* remap parameters */
591 a->start_routine = start_routine;
592 a->data = data;
593 start_routine = dummy_start;
594 asprintf(&a->name, "%-20s started at [%5d] %s %s()",
595 start_fn, line, file, caller);
596 data = a;
598 return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
601 int ast_wait_for_input(int fd, int ms)
603 struct pollfd pfd[1];
604 memset(pfd, 0, sizeof(pfd));
605 pfd[0].fd = fd;
606 pfd[0].events = POLLIN|POLLPRI;
607 return poll(pfd, 1, ms);
610 int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
612 /* Try to write string, but wait no more than ms milliseconds
613 before timing out */
614 int res = 0;
615 struct pollfd fds[1];
616 while (len) {
617 res = write(fd, s, len);
618 if ((res < 0) && (errno != EAGAIN)) {
619 return -1;
621 if (res < 0)
622 res = 0;
623 len -= res;
624 s += res;
625 res = 0;
626 if (len) {
627 fds[0].fd = fd;
628 fds[0].events = POLLOUT;
629 /* Wait until writable again */
630 res = poll(fds, 1, timeoutms);
631 if (res < 1)
632 return -1;
635 return res;
638 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
640 char *e;
641 char *q;
643 s = ast_strip(s);
644 if ((q = strchr(beg_quotes, *s))) {
645 e = s + strlen(s) - 1;
646 if (*e == *(end_quotes + (q - beg_quotes))) {
647 s++;
648 *e = '\0';
652 return s;
655 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
657 int result;
659 if (!buffer || !*buffer || !space || !*space)
660 return -1;
662 result = vsnprintf(*buffer, *space, fmt, ap);
664 if (result < 0)
665 return -1;
666 else if (result > *space)
667 result = *space;
669 *buffer += result;
670 *space -= result;
671 return 0;
674 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
676 va_list ap;
677 int result;
679 va_start(ap, fmt);
680 result = ast_build_string_va(buffer, space, fmt, ap);
681 va_end(ap);
683 return result;
686 int ast_true(const char *s)
688 if (ast_strlen_zero(s))
689 return 0;
691 /* Determine if this is a true value */
692 if (!strcasecmp(s, "yes") ||
693 !strcasecmp(s, "true") ||
694 !strcasecmp(s, "y") ||
695 !strcasecmp(s, "t") ||
696 !strcasecmp(s, "1") ||
697 !strcasecmp(s, "on"))
698 return -1;
700 return 0;
703 int ast_false(const char *s)
705 if (ast_strlen_zero(s))
706 return 0;
708 /* Determine if this is a false value */
709 if (!strcasecmp(s, "no") ||
710 !strcasecmp(s, "false") ||
711 !strcasecmp(s, "n") ||
712 !strcasecmp(s, "f") ||
713 !strcasecmp(s, "0") ||
714 !strcasecmp(s, "off"))
715 return -1;
717 return 0;
720 #define ONE_MILLION 1000000
722 * put timeval in a valid range. usec is 0..999999
723 * negative values are not allowed and truncated.
725 static struct timeval tvfix(struct timeval a)
727 if (a.tv_usec >= ONE_MILLION) {
728 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
729 a.tv_sec, (long int) a.tv_usec);
730 a.tv_sec += a.tv_usec / ONE_MILLION;
731 a.tv_usec %= ONE_MILLION;
732 } else if (a.tv_usec < 0) {
733 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
734 a.tv_sec, (long int) a.tv_usec);
735 a.tv_usec = 0;
737 return a;
740 struct timeval ast_tvadd(struct timeval a, struct timeval b)
742 /* consistency checks to guarantee usec in 0..999999 */
743 a = tvfix(a);
744 b = tvfix(b);
745 a.tv_sec += b.tv_sec;
746 a.tv_usec += b.tv_usec;
747 if (a.tv_usec >= ONE_MILLION) {
748 a.tv_sec++;
749 a.tv_usec -= ONE_MILLION;
751 return a;
754 struct timeval ast_tvsub(struct timeval a, struct timeval b)
756 /* consistency checks to guarantee usec in 0..999999 */
757 a = tvfix(a);
758 b = tvfix(b);
759 a.tv_sec -= b.tv_sec;
760 a.tv_usec -= b.tv_usec;
761 if (a.tv_usec < 0) {
762 a.tv_sec-- ;
763 a.tv_usec += ONE_MILLION;
765 return a;
767 #undef ONE_MILLION
769 #ifndef HAVE_STRCASESTR
770 static char *upper(const char *orig, char *buf, int bufsize)
772 int i = 0;
774 while (i < (bufsize - 1) && orig[i]) {
775 buf[i] = toupper(orig[i]);
776 i++;
779 buf[i] = '\0';
781 return buf;
784 char *strcasestr(const char *haystack, const char *needle)
786 char *u1, *u2;
787 int u1len = strlen(haystack) + 1, u2len = strlen(needle) + 1;
789 u1 = alloca(u1len);
790 u2 = alloca(u2len);
791 if (u1 && u2) {
792 char *offset;
793 if (u2len > u1len) {
794 /* Needle bigger than haystack */
795 return NULL;
797 offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
798 if (offset) {
799 /* Return the offset into the original string */
800 return ((char *)((unsigned long)haystack + (unsigned long)(offset - u1)));
801 } else {
802 return NULL;
804 } else {
805 ast_log(LOG_ERROR, "Out of memory\n");
806 return NULL;
809 #endif /* !HAVE_STRCASESTR */
811 #ifndef HAVE_STRNLEN
812 size_t strnlen(const char *s, size_t n)
814 size_t len;
816 for (len = 0; len < n; len++)
817 if (s[len] == '\0')
818 break;
820 return len;
822 #endif /* !HAVE_STRNLEN */
824 #if !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC)
825 char *strndup(const char *s, size_t n)
827 size_t len = strnlen(s, n);
828 char *new = ast_malloc(len + 1);
830 if (!new)
831 return NULL;
833 new[len] = '\0';
834 return memcpy(new, s, len);
836 #endif /* !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC) */
838 #if !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC)
839 int vasprintf(char **strp, const char *fmt, va_list ap)
841 int size;
842 va_list ap2;
843 char s;
845 *strp = NULL;
846 va_copy(ap2, ap);
847 size = vsnprintf(&s, 1, fmt, ap2);
848 va_end(ap2);
849 *strp = ast_malloc(size + 1);
850 if (!*strp)
851 return -1;
852 vsnprintf(*strp, size + 1, fmt, ap);
854 return size;
856 #endif /* !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
859 * Based on Code from bsd-asprintf from OpenSSH
860 * Copyright (c) 2004 Darren Tucker.
862 * Based originally on asprintf.c from OpenBSD:
863 * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
865 * Permission to use, copy, modify, and distribute this software for any
866 * purpose with or without fee is hereby granted, provided that the above
867 * copyright notice and this permission notice appear in all copies.
869 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
870 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
871 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
872 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
873 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
874 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
875 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
877 #if !defined(HAVE_ASPRINTF) && !defined(__AST_DEBUG_MALLOC)
878 int asprintf(char **str, const char *fmt, ...)
880 va_list ap;
881 int ret;
883 *str = NULL;
884 va_start(ap, fmt);
885 ret = vasprintf(str, fmt, ap);
886 va_end(ap);
888 return ret;
890 #endif /* !defined(HAVE_ASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
892 #ifndef HAVE_STRTOQ
893 #ifndef LONG_MIN
894 #define LONG_MIN (-9223372036854775807L-1L)
895 /* min value of a "long int" */
896 #endif
897 #ifndef LONG_MAX
898 #define LONG_MAX 9223372036854775807L
899 /* max value of a "long int" */
900 #endif
902 /*! \brief
903 * Convert a string to a quad integer.
905 * \note Ignores `locale' stuff. Assumes that the upper and lower case
906 * alphabets and digits are each contiguous.
908 uint64_t strtoq(const char *nptr, char **endptr, int base)
910 const char *s;
911 uint64_t acc;
912 unsigned char c;
913 uint64_t qbase, cutoff;
914 int neg, any, cutlim;
917 * Skip white space and pick up leading +/- sign if any.
918 * If base is 0, allow 0x for hex and 0 for octal, else
919 * assume decimal; if base is already 16, allow 0x.
921 s = nptr;
922 do {
923 c = *s++;
924 } while (isspace(c));
925 if (c == '-') {
926 neg = 1;
927 c = *s++;
928 } else {
929 neg = 0;
930 if (c == '+')
931 c = *s++;
933 if ((base == 0 || base == 16) &&
934 c == '\0' && (*s == 'x' || *s == 'X')) {
935 c = s[1];
936 s += 2;
937 base = 16;
939 if (base == 0)
940 base = c == '\0' ? 8 : 10;
943 * Compute the cutoff value between legal numbers and illegal
944 * numbers. That is the largest legal value, divided by the
945 * base. An input number that is greater than this value, if
946 * followed by a legal input character, is too big. One that
947 * is equal to this value may be valid or not; the limit
948 * between valid and invalid numbers is then based on the last
949 * digit. For instance, if the range for quads is
950 * [-9223372036854775808..9223372036854775807] and the input base
951 * is 10, cutoff will be set to 922337203685477580 and cutlim to
952 * either 7 (neg==0) or 8 (neg==1), meaning that if we have
953 * accumulated a value > 922337203685477580, or equal but the
954 * next digit is > 7 (or 8), the number is too big, and we will
955 * return a range error.
957 * Set any if any `digits' consumed; make it negative to indicate
958 * overflow.
960 qbase = (unsigned)base;
961 cutoff = neg ? (uint64_t)-(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX;
962 cutlim = cutoff % qbase;
963 cutoff /= qbase;
964 for (acc = 0, any = 0;; c = *s++) {
965 if (!isascii(c))
966 break;
967 if (isdigit(c))
968 c -= '\0';
969 else if (isalpha(c))
970 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
971 else
972 break;
973 if (c >= base)
974 break;
975 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
976 any = -1;
977 else {
978 any = 1;
979 acc *= qbase;
980 acc += c;
983 if (any < 0) {
984 acc = neg ? LONG_MIN : LONG_MAX;
985 } else if (neg)
986 acc = -acc;
987 if (endptr != 0)
988 *((const char **)endptr) = any ? s - 1 : nptr;
989 return acc;
991 #endif /* !HAVE_STRTOQ */
993 #ifndef HAVE_GETLOADAVG
994 #ifdef linux
995 /*! \brief Alternative method of getting load avg on Linux only */
996 int getloadavg(double *list, int nelem)
998 FILE *LOADAVG;
999 double avg[3] = { 0.0, 0.0, 0.0 };
1000 int i, res = -1;
1002 if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
1003 fscanf(LOADAVG, "%lf %lf %lf", &avg[0], &avg[1], &avg[2]);
1004 res = 0;
1005 fclose(LOADAVG);
1008 for (i = 0; (i < nelem) && (i < 3); i++) {
1009 list[i] = avg[i];
1012 return res;
1014 #else /* !linux */
1015 /*! \brief Return something that won't cancel the call, but still return -1, in case
1016 * we correct the implementation to check return value */
1017 int getloadavg(double *list, int nelem)
1019 int i;
1021 for (i = 0; i < nelem; i++) {
1022 list[i] = 0.1;
1024 return -1;
1026 #endif /* linux */
1027 #endif /* !defined(_BSD_SOURCE) */
1029 /*! \brief glibc puts a lock inside random(3), so that the results are thread-safe.
1030 * BSD libc (and others) do not. */
1031 #ifndef linux
1033 AST_MUTEX_DEFINE_STATIC(randomlock);
1035 long int ast_random(void)
1037 long int res;
1038 ast_mutex_lock(&randomlock);
1039 res = random();
1040 ast_mutex_unlock(&randomlock);
1041 return res;
1043 #endif
1045 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
1047 char *dataPut = start;
1048 int inEscape = 0;
1049 int inQuotes = 0;
1051 for (; *start; start++) {
1052 if (inEscape) {
1053 *dataPut++ = *start; /* Always goes verbatim */
1054 inEscape = 0;
1055 } else {
1056 if (*start == '\\') {
1057 inEscape = 1; /* Do not copy \ into the data */
1058 } else if (*start == '\'') {
1059 inQuotes = 1 - inQuotes; /* Do not copy ' into the data */
1060 } else {
1061 /* Replace , with |, unless in quotes */
1062 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
1066 if (start != dataPut)
1067 *dataPut = 0;
1068 return dataPut;
1071 void ast_join(char *s, size_t len, char * const w[])
1073 int x, ofs = 0;
1074 const char *src;
1076 /* Join words into a string */
1077 if (!s)
1078 return;
1079 for (x = 0; ofs < len && w[x]; x++) {
1080 if (x > 0)
1081 s[ofs++] = ' ';
1082 for (src = w[x]; *src && ofs < len; src++)
1083 s[ofs++] = *src;
1085 if (ofs == len)
1086 ofs--;
1087 s[ofs] = '\0';
1090 const char __ast_string_field_empty[] = "";
1092 static int add_string_pool(struct ast_string_field_mgr *mgr, size_t size)
1094 struct ast_string_field_pool *pool;
1096 if (!(pool = ast_calloc(1, sizeof(*pool) + size)))
1097 return -1;
1099 pool->prev = mgr->pool;
1100 mgr->pool = pool;
1101 mgr->size = size;
1102 mgr->space = size;
1103 mgr->used = 0;
1105 return 0;
1108 int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
1109 ast_string_field *fields, int num_fields)
1111 int index;
1113 if (add_string_pool(mgr, size))
1114 return -1;
1116 for (index = 0; index < num_fields; index++)
1117 fields[index] = __ast_string_field_empty;
1119 return 0;
1122 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr, size_t needed,
1123 ast_string_field *fields, int num_fields)
1125 char *result = NULL;
1127 if (__builtin_expect(needed > mgr->space, 0)) {
1128 size_t new_size = mgr->size * 2;
1130 while (new_size < needed)
1131 new_size *= 2;
1133 if (add_string_pool(mgr, new_size))
1134 return NULL;
1137 result = mgr->pool->base + mgr->used;
1138 mgr->used += needed;
1139 mgr->space -= needed;
1140 return result;
1143 void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
1144 ast_string_field *fields, int num_fields,
1145 int index, const char *format, ...)
1147 size_t needed;
1148 va_list ap1, ap2;
1150 va_start(ap1, format);
1151 va_start(ap2, format); /* va_copy does not exist on FreeBSD */
1153 needed = vsnprintf(mgr->pool->base + mgr->used, mgr->space, format, ap1) + 1;
1155 va_end(ap1);
1157 if (needed > mgr->space) {
1158 size_t new_size = mgr->size * 2;
1160 while (new_size < needed)
1161 new_size *= 2;
1163 if (add_string_pool(mgr, new_size))
1164 return;
1166 vsprintf(mgr->pool->base + mgr->used, format, ap2);
1169 fields[index] = mgr->pool->base + mgr->used;
1170 mgr->used += needed;
1171 mgr->space -= needed;
1173 va_end(ap2);
1176 AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
1178 int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
1180 int ret;
1181 ast_mutex_lock(&fetchadd_m);
1182 ret = *p;
1183 *p += v;
1184 ast_mutex_unlock(&fetchadd_m);
1185 return ret;
1188 /*! \brief
1189 * get values from config variables.
1191 int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
1193 long t;
1194 int scanned;
1196 if (dst == NULL)
1197 return -1;
1199 *dst = _default;
1201 if (ast_strlen_zero(src))
1202 return -1;
1204 /* only integer at the moment, but one day we could accept more formats */
1205 if (sscanf(src, "%ld%n", &t, &scanned) == 1) {
1206 *dst = t;
1207 if (consumed)
1208 *consumed = scanned;
1209 return 0;
1210 } else
1211 return -1;