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$")
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 #define AST_API_MODULE
63 #include "asterisk/threadstorage.h"
65 static char base64[64];
68 AST_THREADSTORAGE(inet_ntoa_buf, inet_ntoa_buf_init);
70 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) || defined(__CYGWIN__)
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_addr_list = (void *) hp->buf;
208 hp->hp.h_addr = hp->buf + sizeof(void *);
209 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
215 result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
217 if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
220 res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
222 if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
230 AST_MUTEX_DEFINE_STATIC(test_lock);
231 AST_MUTEX_DEFINE_STATIC(test_lock2);
232 static pthread_t test_thread;
233 static int lock_count = 0;
234 static int test_errors = 0;
236 /*! \brief This is a regression test for recursive mutexes.
237 test_for_thread_safety() will return 0 if recursive mutex locks are
238 working properly, and non-zero if they are not working properly. */
239 static void *test_thread_body(void *data)
241 ast_mutex_lock(&test_lock);
243 if (lock_count != 10)
245 ast_mutex_lock(&test_lock);
247 if (lock_count != 20)
249 ast_mutex_lock(&test_lock2);
250 ast_mutex_unlock(&test_lock);
252 if (lock_count != 10)
254 ast_mutex_unlock(&test_lock);
256 ast_mutex_unlock(&test_lock2);
262 int test_for_thread_safety(void)
264 ast_mutex_lock(&test_lock2);
265 ast_mutex_lock(&test_lock);
267 ast_mutex_lock(&test_lock);
269 ast_pthread_create(&test_thread, NULL, test_thread_body, NULL);
273 ast_mutex_unlock(&test_lock);
278 ast_mutex_unlock(&test_lock);
282 ast_mutex_unlock(&test_lock2);
286 pthread_join(test_thread, NULL);
287 return(test_errors); /* return 0 on success. */
290 /*! \brief Produce 32 char MD5 hash of value. */
291 void ast_md5_hash(char *output, char *input)
293 struct MD5Context md5;
294 unsigned char digest[16];
299 MD5Update(&md5, (unsigned char *)input, strlen(input));
300 MD5Final(digest, &md5);
302 for (x = 0; x < 16; x++)
303 ptr += sprintf(ptr, "%2.2x", digest[x]);
306 /*! \brief Produce 40 char SHA1 hash of value. */
307 void ast_sha1_hash(char *output, char *input)
309 struct SHA1Context sha;
312 uint8_t Message_Digest[20];
316 SHA1Input(&sha, (const unsigned char *) input, strlen(input));
318 SHA1Result(&sha, Message_Digest);
320 for (x = 0; x < 20; x++)
321 ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
324 /*! \brief decode BASE64 encoded text */
325 int ast_base64decode(unsigned char *dst, const char *src, int max)
328 unsigned int byte = 0;
329 unsigned int bits = 0;
331 while(*src && (cnt < max)) {
332 /* Shift in 6 bits of input */
334 byte |= (b2a[(int)(*src)]) & 0x3f;
338 /* If we have at least 8 bits left over, take that character
342 *dst = (byte >> bits) & 0xff;
347 /* Dont worry about left over bits, they're extra anyway */
351 /*! \brief encode text to BASE64 coding */
352 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
356 unsigned int byte = 0;
359 /* Reserve space for null byte at end of string */
361 while ((cntin < srclen) && (cnt < max)) {
366 if ((bits == 24) && (cnt + 4 <= max)) {
367 *dst++ = base64[(byte >> 18) & 0x3f];
368 *dst++ = base64[(byte >> 12) & 0x3f];
369 *dst++ = base64[(byte >> 6) & 0x3f];
370 *dst++ = base64[byte & 0x3f];
376 if (linebreaks && (cnt < max) && (col == 64)) {
382 if (bits && (cnt + 4 <= max)) {
383 /* Add one last character for the remaining bits,
384 padding the rest with 0 */
386 *dst++ = base64[(byte >> 18) & 0x3f];
387 *dst++ = base64[(byte >> 12) & 0x3f];
389 *dst++ = base64[(byte >> 6) & 0x3f];
395 if (linebreaks && (cnt < max)) {
403 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
405 return ast_base64encode_full(dst, src, srclen, max, 0);
408 static void base64_init(void)
411 memset(b2a, -1, sizeof(b2a));
412 /* Initialize base-64 Conversion table */
413 for (x = 0; x < 26; x++) {
418 base64[x + 26] = 'a' + x;
419 b2a['a' + x] = x + 26;
422 base64[x + 52] = '0' + x;
423 b2a['0' + x] = x + 52;
432 /*! \brief ast_uri_encode: Turn text string to URI-encoded %XX version
433 \note At this point, we're converting from ISO-8859-x (8-bit), not UTF8
434 as in the SIP protocol spec
435 If doreserved == 1 we will convert reserved characters also.
436 RFC 2396, section 2.4
437 outbuf needs to have more memory allocated than the instring
438 to have room for the expansion. Every char that is converted
439 is replaced by three ASCII characters.
441 Note: The doreserved option is needed for replaces header in
444 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved)
446 char *reserved = ";/?:@&=+$, "; /* Reserved chars */
448 const char *ptr = string; /* Start with the string */
452 strncpy(outbuf, string, buflen);
454 /* If there's no characters to convert, just go through and don't do anything */
456 if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
457 /* Oops, we need to start working here */
460 out = buf + (ptr - string) ; /* Set output ptr */
462 out += sprintf(out, "%%%02x", (unsigned char) *ptr);
464 *out = *ptr; /* Continue copying the string */
474 /*! \brief ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string) */
475 void ast_uri_decode(char *s)
480 for (o = s; *s; s++, o++) {
481 if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
482 /* have '%', two chars and correct parsing */
484 s += 2; /* Will be incremented once more when we break out */
485 } else /* all other cases, just copy */
491 /*! \brief ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
492 const char *ast_inet_ntoa(struct in_addr ia)
496 if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
499 return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
502 int ast_utils_init(void)
509 #undef pthread_create /* For ast_pthread_create function only */
510 #endif /* !__linux__ */
513 * support for 'show threads'. The start routine is wrapped by
514 * dummy_start(), so that ast_register_thread() and
515 * ast_unregister_thread() know the thread identifier.
518 void *(*start_routine)(void *);
524 * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
525 * are odd macros which start and end a block, so they _must_ be
526 * used in pairs (the latter with a '1' argument to call the
528 * On BSD we don't need this, but we keep it for compatibility with the MAC.
530 static void *dummy_start(void *data)
533 struct thr_arg a = *((struct thr_arg *)data); /* make a local copy */
536 ast_register_thread(a.name);
537 pthread_cleanup_push(ast_unregister_thread, (void *)pthread_self()); /* on unregister */
538 ret = a.start_routine(a.data);
539 pthread_cleanup_pop(1);
543 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize,
544 const char *file, const char *caller, int line, const char *start_fn)
548 pthread_attr_t lattr;
550 pthread_attr_init(&lattr);
554 /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
555 which is kind of useless. Change this here to
556 PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
557 priority will propagate down to new threads by default.
558 This does mean that callers cannot set a different priority using
559 PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
560 the priority afterwards with pthread_setschedparam(). */
561 errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED);
563 ast_log(LOG_WARNING, "pthread_attr_setinheritsched returned non-zero: %s\n", strerror(errno));
567 stacksize = AST_STACKSIZE;
568 errno = pthread_attr_setstacksize(attr, stacksize);
570 ast_log(LOG_WARNING, "pthread_attr_setstacksize returned non-zero: %s\n", strerror(errno));
571 a = ast_malloc(sizeof(*a));
573 ast_log(LOG_WARNING, "no memory, thread %s will not be listed\n", start_fn);
574 else { /* remap parameters */
575 a->start_routine = start_routine;
577 start_routine = dummy_start;
578 asprintf(&a->name, "%-20s started at [%5d] %s %s()",
579 start_fn, line, file, caller);
582 return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
585 int ast_wait_for_input(int fd, int ms)
587 struct pollfd pfd[1];
588 memset(pfd, 0, sizeof(pfd));
590 pfd[0].events = POLLIN|POLLPRI;
591 return poll(pfd, 1, ms);
594 int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
596 /* Try to write string, but wait no more than ms milliseconds
599 struct pollfd fds[1];
601 res = write(fd, s, len);
602 if ((res < 0) && (errno != EAGAIN)) {
612 fds[0].events = POLLOUT;
613 /* Wait until writable again */
614 res = poll(fds, 1, timeoutms);
622 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
628 if ((q = strchr(beg_quotes, *s))) {
629 e = s + strlen(s) - 1;
630 if (*e == *(end_quotes + (q - beg_quotes))) {
639 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
643 if (!buffer || !*buffer || !space || !*space)
646 result = vsnprintf(*buffer, *space, fmt, ap);
650 else if (result > *space)
658 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
664 result = ast_build_string_va(buffer, space, fmt, ap);
670 int ast_true(const char *s)
672 if (ast_strlen_zero(s))
675 /* Determine if this is a true value */
676 if (!strcasecmp(s, "yes") ||
677 !strcasecmp(s, "true") ||
678 !strcasecmp(s, "y") ||
679 !strcasecmp(s, "t") ||
680 !strcasecmp(s, "1") ||
681 !strcasecmp(s, "on"))
687 int ast_false(const char *s)
689 if (ast_strlen_zero(s))
692 /* Determine if this is a false value */
693 if (!strcasecmp(s, "no") ||
694 !strcasecmp(s, "false") ||
695 !strcasecmp(s, "n") ||
696 !strcasecmp(s, "f") ||
697 !strcasecmp(s, "0") ||
698 !strcasecmp(s, "off"))
704 #define ONE_MILLION 1000000
706 * put timeval in a valid range. usec is 0..999999
707 * negative values are not allowed and truncated.
709 static struct timeval tvfix(struct timeval a)
711 if (a.tv_usec >= ONE_MILLION) {
712 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
713 a.tv_sec, (long int) a.tv_usec);
714 a.tv_sec += a.tv_usec / ONE_MILLION;
715 a.tv_usec %= ONE_MILLION;
716 } else if (a.tv_usec < 0) {
717 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
718 a.tv_sec, (long int) a.tv_usec);
724 struct timeval ast_tvadd(struct timeval a, struct timeval b)
726 /* consistency checks to guarantee usec in 0..999999 */
729 a.tv_sec += b.tv_sec;
730 a.tv_usec += b.tv_usec;
731 if (a.tv_usec >= ONE_MILLION) {
733 a.tv_usec -= ONE_MILLION;
738 struct timeval ast_tvsub(struct timeval a, struct timeval b)
740 /* consistency checks to guarantee usec in 0..999999 */
743 a.tv_sec -= b.tv_sec;
744 a.tv_usec -= b.tv_usec;
747 a.tv_usec += ONE_MILLION;
753 #ifndef HAVE_STRCASESTR
754 static char *upper(const char *orig, char *buf, int bufsize)
758 while (i < (bufsize - 1) && orig[i]) {
759 buf[i] = toupper(orig[i]);
768 char *strcasestr(const char *haystack, const char *needle)
771 int u1len = strlen(haystack) + 1, u2len = strlen(needle) + 1;
778 /* Needle bigger than haystack */
781 offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
783 /* Return the offset into the original string */
784 return ((char *)((unsigned long)haystack + (unsigned long)(offset - u1)));
789 ast_log(LOG_ERROR, "Out of memory\n");
793 #endif /* !HAVE_STRCASESTR */
796 size_t strnlen(const char *s, size_t n)
800 for (len = 0; len < n; len++)
806 #endif /* !HAVE_STRNLEN */
808 #if !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC)
809 char *strndup(const char *s, size_t n)
811 size_t len = strnlen(s, n);
812 char *new = ast_malloc(len + 1);
818 return memcpy(new, s, len);
820 #endif /* !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC) */
822 #if !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC)
823 int vasprintf(char **strp, const char *fmt, va_list ap)
831 size = vsnprintf(&s, 1, fmt, ap2);
833 *strp = ast_malloc(size + 1);
836 vsnprintf(*strp, size + 1, fmt, ap);
840 #endif /* !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
843 * Based on Code from bsd-asprintf from OpenSSH
844 * Copyright (c) 2004 Darren Tucker.
846 * Based originally on asprintf.c from OpenBSD:
847 * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
849 * Permission to use, copy, modify, and distribute this software for any
850 * purpose with or without fee is hereby granted, provided that the above
851 * copyright notice and this permission notice appear in all copies.
853 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
854 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
855 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
856 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
857 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
858 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
859 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
861 #if !defined(HAVE_ASPRINTF) && !defined(__AST_DEBUG_MALLOC)
862 int asprintf(char **str, const char *fmt, ...)
869 ret = vasprintf(str, fmt, ap);
874 #endif /* !defined(HAVE_ASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
878 #define LONG_MIN (-9223372036854775807L-1L)
879 /* min value of a "long int" */
882 #define LONG_MAX 9223372036854775807L
883 /* max value of a "long int" */
887 * Convert a string to a quad integer.
889 * \note Ignores `locale' stuff. Assumes that the upper and lower case
890 * alphabets and digits are each contiguous.
892 uint64_t strtoq(const char *nptr, char **endptr, int base)
897 uint64_t qbase, cutoff;
898 int neg, any, cutlim;
901 * Skip white space and pick up leading +/- sign if any.
902 * If base is 0, allow 0x for hex and 0 for octal, else
903 * assume decimal; if base is already 16, allow 0x.
908 } while (isspace(c));
917 if ((base == 0 || base == 16) &&
918 c == '\0' && (*s == 'x' || *s == 'X')) {
924 base = c == '\0' ? 8 : 10;
927 * Compute the cutoff value between legal numbers and illegal
928 * numbers. That is the largest legal value, divided by the
929 * base. An input number that is greater than this value, if
930 * followed by a legal input character, is too big. One that
931 * is equal to this value may be valid or not; the limit
932 * between valid and invalid numbers is then based on the last
933 * digit. For instance, if the range for quads is
934 * [-9223372036854775808..9223372036854775807] and the input base
935 * is 10, cutoff will be set to 922337203685477580 and cutlim to
936 * either 7 (neg==0) or 8 (neg==1), meaning that if we have
937 * accumulated a value > 922337203685477580, or equal but the
938 * next digit is > 7 (or 8), the number is too big, and we will
939 * return a range error.
941 * Set any if any `digits' consumed; make it negative to indicate
944 qbase = (unsigned)base;
945 cutoff = neg ? (uint64_t)-(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX;
946 cutlim = cutoff % qbase;
948 for (acc = 0, any = 0;; c = *s++) {
954 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
959 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
968 acc = neg ? LONG_MIN : LONG_MAX;
972 *((const char **)endptr) = any ? s - 1 : nptr;
975 #endif /* !HAVE_STRTOQ */
977 #ifndef HAVE_GETLOADAVG
979 /*! \brief Alternative method of getting load avg on Linux only */
980 int getloadavg(double *list, int nelem)
983 double avg[3] = { 0.0, 0.0, 0.0 };
986 if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
987 fscanf(LOADAVG, "%lf %lf %lf", &avg[0], &avg[1], &avg[2]);
992 for (i = 0; (i < nelem) && (i < 3); i++) {
999 /*! \brief Return something that won't cancel the call, but still return -1, in case
1000 * we correct the implementation to check return value */
1001 int getloadavg(double *list, int nelem)
1005 for (i = 0; i < nelem; i++) {
1011 #endif /* !defined(_BSD_SOURCE) */
1013 /*! \brief glibc puts a lock inside random(3), so that the results are thread-safe.
1014 * BSD libc (and others) do not. */
1017 AST_MUTEX_DEFINE_STATIC(randomlock);
1019 long int ast_random(void)
1022 ast_mutex_lock(&randomlock);
1024 ast_mutex_unlock(&randomlock);
1029 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
1031 char *dataPut = start;
1035 for (; *start; start++) {
1037 *dataPut++ = *start; /* Always goes verbatim */
1040 if (*start == '\\') {
1041 inEscape = 1; /* Do not copy \ into the data */
1042 } else if (*start == '\'') {
1043 inQuotes = 1 - inQuotes; /* Do not copy ' into the data */
1045 /* Replace , with |, unless in quotes */
1046 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
1050 if (start != dataPut)
1055 void ast_join(char *s, size_t len, char * const w[])
1060 /* Join words into a string */
1063 for (x = 0; ofs < len && w[x]; x++) {
1066 for (src = w[x]; *src && ofs < len; src++)
1074 const char __ast_string_field_empty[] = "";
1076 static int add_string_pool(struct ast_string_field_mgr *mgr, size_t size)
1078 struct ast_string_field_pool *pool;
1080 if (!(pool = ast_calloc(1, sizeof(*pool) + size)))
1083 pool->prev = mgr->pool;
1092 int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
1093 ast_string_field *fields, int num_fields)
1097 if (add_string_pool(mgr, size))
1100 for (index = 0; index < num_fields; index++)
1101 fields[index] = __ast_string_field_empty;
1106 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr, size_t needed,
1107 ast_string_field *fields, int num_fields)
1109 char *result = NULL;
1111 if (__builtin_expect(needed > mgr->space, 0)) {
1112 size_t new_size = mgr->size * 2;
1114 while (new_size < needed)
1117 if (add_string_pool(mgr, new_size))
1121 result = mgr->pool->base + mgr->used;
1122 mgr->used += needed;
1123 mgr->space -= needed;
1127 void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
1128 ast_string_field *fields, int num_fields,
1129 int index, const char *format, ...)
1134 va_start(ap1, format);
1135 va_start(ap2, format); /* va_copy does not exist on FreeBSD */
1137 needed = vsnprintf(mgr->pool->base + mgr->used, mgr->space, format, ap1) + 1;
1141 if (needed > mgr->space) {
1142 size_t new_size = mgr->size * 2;
1144 while (new_size < needed)
1147 if (add_string_pool(mgr, new_size))
1150 vsprintf(mgr->pool->base + mgr->used, format, ap2);
1153 fields[index] = mgr->pool->base + mgr->used;
1154 mgr->used += needed;
1155 mgr->space -= needed;
1160 AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
1162 int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
1165 ast_mutex_lock(&fetchadd_m);
1168 ast_mutex_unlock(&fetchadd_m);
1173 * get values from config variables.
1175 int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
1185 if (ast_strlen_zero(src))
1188 /* only integer at the moment, but one day we could accept more formats */
1189 if (sscanf(src, "%ld%n", &t, &scanned) == 1) {
1192 *consumed = scanned;
1198 int ast_dynamic_str_thread_build_va(struct ast_dynamic_str **buf, size_t max_len,
1199 struct ast_threadstorage *ts, int append, const char *fmt, va_list ap)
1202 int offset = append ? strlen((*buf)->str) : 0;
1204 res = vsnprintf((*buf)->str + offset, (*buf)->len - offset, fmt, ap);
1206 /* Check to see if there was not enough space in the string buffer to prepare
1207 * the string. Also, if a maximum length is present, make sure the current
1208 * length is less than the maximum before increasing the size. */
1209 if ((res + offset + 1) > (*buf)->len && (max_len ? ((*buf)->len < max_len) : 1)) {
1210 /* Set the new size of the string buffer to be the size needed
1211 * to hold the resulting string (res) plus one byte for the
1212 * terminating '\0'. If this size is greater than the max, set
1213 * the new length to be the maximum allowed. */
1215 (*buf)->len = ((res + offset + 1) < max_len) ? (res + offset + 1) : max_len;
1217 (*buf)->len = res + offset + 1;
1219 if (!(*buf = ast_realloc(*buf, (*buf)->len + sizeof(*(*buf)))))
1220 return AST_DYNSTR_BUILD_FAILED;
1223 pthread_setspecific(ts->key, *buf);
1225 /* va_end() and va_start() must be done before calling
1226 * vsnprintf() again. */
1227 return AST_DYNSTR_BUILD_RETRY;