00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <ctype.h>
00027 #include <string.h>
00028 #include <unistd.h>
00029 #include <stdlib.h>
00030 #include <errno.h>
00031 #include <stdarg.h>
00032 #include <stdio.h>
00033 #include <sys/types.h>
00034 #include <sys/socket.h>
00035 #include <netinet/in.h>
00036 #include <arpa/inet.h>
00037
00038 #include "asterisk.h"
00039
00040 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 215958 $")
00041
00042 #define AST_API_MODULE
00043 #include "asterisk/lock.h"
00044
00045 #include "asterisk/io.h"
00046 #include "asterisk/logger.h"
00047 #include "asterisk/md5.h"
00048 #include "asterisk/sha1.h"
00049 #include "asterisk/options.h"
00050 #include "asterisk/compat.h"
00051
00052 #define AST_API_MODULE
00053 #include "asterisk/strings.h"
00054
00055 #define AST_API_MODULE
00056 #include "asterisk/time.h"
00057
00058 #define AST_API_MODULE
00059 #include "asterisk/utils.h"
00060
00061 static char base64[64];
00062 static char b2a[256];
00063
00064 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) || defined(__CYGWIN__)
00065
00066
00067 #define ERANGE 34
00068 #undef gethostbyname
00069
00070 AST_MUTEX_DEFINE_STATIC(__mutex);
00071
00072
00073
00074
00075
00076 static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
00077 size_t buflen, struct hostent **result,
00078 int *h_errnop)
00079 {
00080 int hsave;
00081 struct hostent *ph;
00082 ast_mutex_lock(&__mutex);
00083 hsave = h_errno;
00084
00085 ph = gethostbyname(name);
00086 *h_errnop = h_errno;
00087 if (ph == NULL) {
00088 *result = NULL;
00089 } else {
00090 char **p, **q;
00091 char *pbuf;
00092 int nbytes=0;
00093 int naddr=0, naliases=0;
00094
00095
00096
00097 for (p = ph->h_addr_list; *p != 0; p++) {
00098 nbytes += ph->h_length;
00099 nbytes += sizeof(*p);
00100 naddr++;
00101 }
00102 nbytes += sizeof(*p);
00103
00104
00105 for (p = ph->h_aliases; *p != 0; p++) {
00106 nbytes += (strlen(*p)+1);
00107 nbytes += sizeof(*p);
00108 naliases++;
00109 }
00110 nbytes += sizeof(*p);
00111
00112
00113
00114 if(nbytes > buflen) {
00115 *result = NULL;
00116 ast_mutex_unlock(&__mutex);
00117 return ERANGE;
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 *ret = *ph;
00134
00135
00136 q = (char **)buf;
00137 ret->h_addr_list = q;
00138 pbuf = buf + ((naddr+naliases+2)*sizeof(*p));
00139 for (p = ph->h_addr_list; *p != 0; p++) {
00140 memcpy(pbuf, *p, ph->h_length);
00141 *q++ = pbuf;
00142 pbuf += ph->h_length;
00143 }
00144 *q++ = NULL;
00145
00146
00147 ret->h_aliases = q;
00148 for (p = ph->h_aliases; *p != 0; p++) {
00149 strcpy(pbuf, *p);
00150 *q++ = pbuf;
00151 pbuf += strlen(*p);
00152 *pbuf++ = 0;
00153 }
00154 *q++ = NULL;
00155
00156 strcpy(pbuf, ph->h_name);
00157 ret->h_name = pbuf;
00158 pbuf += strlen(ph->h_name);
00159 *pbuf++ = 0;
00160
00161 *result = ret;
00162
00163 }
00164 h_errno = hsave;
00165 ast_mutex_unlock(&__mutex);
00166
00167 return (*result == NULL);
00168 }
00169
00170
00171 #endif
00172
00173
00174
00175
00176 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
00177 {
00178 int res;
00179 int herrno;
00180 int dots=0;
00181 const char *s;
00182 struct hostent *result = NULL;
00183
00184
00185
00186
00187 s = host;
00188 res = 0;
00189 while(s && *s) {
00190 if (*s == '.')
00191 dots++;
00192 else if (!isdigit(*s))
00193 break;
00194 s++;
00195 }
00196 if (!s || !*s) {
00197
00198 if (dots != 3)
00199 return NULL;
00200 memset(hp, 0, sizeof(struct ast_hostent));
00201 hp->hp.h_addrtype = AF_INET;
00202 hp->hp.h_addr_list = (void *) hp->buf;
00203 hp->hp.h_addr = hp->buf + sizeof(void *);
00204 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
00205 return &hp->hp;
00206 return NULL;
00207
00208 }
00209 #ifdef SOLARIS
00210 result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
00211
00212 if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
00213 return NULL;
00214 #else
00215 res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
00216
00217 if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
00218 return NULL;
00219 #endif
00220 return &hp->hp;
00221 }
00222
00223
00224
00225 AST_MUTEX_DEFINE_STATIC(test_lock);
00226 AST_MUTEX_DEFINE_STATIC(test_lock2);
00227 static pthread_t test_thread;
00228 static int lock_count = 0;
00229 static int test_errors = 0;
00230
00231
00232
00233
00234 static void *test_thread_body(void *data)
00235 {
00236 ast_mutex_lock(&test_lock);
00237 lock_count += 10;
00238 if (lock_count != 10)
00239 test_errors++;
00240 ast_mutex_lock(&test_lock);
00241 lock_count += 10;
00242 if (lock_count != 20)
00243 test_errors++;
00244 ast_mutex_lock(&test_lock2);
00245 ast_mutex_unlock(&test_lock);
00246 lock_count -= 10;
00247 if (lock_count != 10)
00248 test_errors++;
00249 ast_mutex_unlock(&test_lock);
00250 lock_count -= 10;
00251 ast_mutex_unlock(&test_lock2);
00252 if (lock_count != 0)
00253 test_errors++;
00254 return NULL;
00255 }
00256
00257 int test_for_thread_safety(void)
00258 {
00259 ast_mutex_lock(&test_lock2);
00260 ast_mutex_lock(&test_lock);
00261 lock_count += 1;
00262 ast_mutex_lock(&test_lock);
00263 lock_count += 1;
00264 ast_pthread_create(&test_thread, NULL, test_thread_body, NULL);
00265 usleep(100);
00266 if (lock_count != 2)
00267 test_errors++;
00268 ast_mutex_unlock(&test_lock);
00269 lock_count -= 1;
00270 usleep(100);
00271 if (lock_count != 1)
00272 test_errors++;
00273 ast_mutex_unlock(&test_lock);
00274 lock_count -= 1;
00275 if (lock_count != 0)
00276 test_errors++;
00277 ast_mutex_unlock(&test_lock2);
00278 usleep(100);
00279 if (lock_count != 0)
00280 test_errors++;
00281 pthread_join(test_thread, NULL);
00282 return(test_errors);
00283 }
00284
00285
00286 void ast_md5_hash(char *output, char *input)
00287 {
00288 struct MD5Context md5;
00289 unsigned char digest[16];
00290 char *ptr;
00291 int x;
00292
00293 MD5Init(&md5);
00294 MD5Update(&md5, (unsigned char *)input, strlen(input));
00295 MD5Final(digest, &md5);
00296 ptr = output;
00297 for (x=0; x<16; x++)
00298 ptr += sprintf(ptr, "%2.2x", digest[x]);
00299 }
00300
00301
00302 void ast_sha1_hash(char *output, char *input)
00303 {
00304 struct SHA1Context sha;
00305 char *ptr;
00306 int x;
00307 uint8_t Message_Digest[20];
00308
00309 SHA1Reset(&sha);
00310
00311 SHA1Input(&sha, (const unsigned char *) input, strlen(input));
00312
00313 SHA1Result(&sha, Message_Digest);
00314 ptr = output;
00315 for (x = 0; x < 20; x++)
00316 ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
00317 }
00318
00319 int ast_base64decode(unsigned char *dst, const char *src, int max)
00320 {
00321 int cnt = 0;
00322 unsigned int byte = 0;
00323 unsigned int bits = 0;
00324 int incnt = 0;
00325 #if 0
00326 unsigned char *odst = dst;
00327 #endif
00328 while(*src && (cnt < max)) {
00329
00330 byte <<= 6;
00331 byte |= (b2a[(int)(*src)]) & 0x3f;
00332 bits += 6;
00333 #if 0
00334 printf("Add: %c %s\n", *src, binary(b2a[(int)(*src)] & 0x3f, 6));
00335 #endif
00336 src++;
00337 incnt++;
00338
00339
00340 if (bits >= 8) {
00341 bits -= 8;
00342 *dst = (byte >> bits) & 0xff;
00343 #if 0
00344 printf("Remove: %02x %s\n", *dst, binary(*dst, 8));
00345 #endif
00346 dst++;
00347 cnt++;
00348 }
00349 }
00350 #if 0
00351 dump(odst, cnt);
00352 #endif
00353
00354 return cnt;
00355 }
00356
00357 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
00358 {
00359 int cnt = 0;
00360 unsigned int byte = 0;
00361 int bits = 0;
00362 int index;
00363 int cntin = 0;
00364 #if 0
00365 char *odst = dst;
00366 dump(src, srclen);
00367 #endif
00368
00369 max--;
00370 while((cntin < srclen) && (cnt < max)) {
00371 byte <<= 8;
00372 #if 0
00373 printf("Add: %02x %s\n", *src, binary(*src, 8));
00374 #endif
00375 byte |= *(src++);
00376 bits += 8;
00377 cntin++;
00378 while((bits >= 6) && (cnt < max)) {
00379 bits -= 6;
00380
00381 index = (byte >> bits) & 0x3f;
00382 *dst = base64[index];
00383 #if 0
00384 printf("Remove: %c %s\n", *dst, binary(index, 6));
00385 #endif
00386 dst++;
00387 cnt++;
00388 }
00389 }
00390 if (bits && (cnt < max)) {
00391
00392
00393 byte <<= (6 - bits);
00394 index = (byte) & 0x3f;
00395 *(dst++) = base64[index];
00396 cnt++;
00397 }
00398 *dst = '\0';
00399 return cnt;
00400 }
00401
00402 static void base64_init(void)
00403 {
00404 int x;
00405 memset(b2a, -1, sizeof(b2a));
00406
00407 for (x=0;x<26;x++) {
00408
00409 base64[x] = 'A' + x;
00410 b2a['A' + x] = x;
00411
00412 base64[x + 26] = 'a' + x;
00413 b2a['a' + x] = x + 26;
00414
00415 if (x < 10) {
00416 base64[x + 52] = '0' + x;
00417 b2a['0' + x] = x + 52;
00418 }
00419 }
00420 base64[62] = '+';
00421 base64[63] = '/';
00422 b2a[(int)'+'] = 62;
00423 b2a[(int)'/'] = 63;
00424 }
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 char *ast_uri_encode(char *string, char *outbuf, int buflen, int doreserved)
00439 {
00440 char *reserved = ";/?:@&=+$, ";
00441
00442 char *ptr = string;
00443 char *out = NULL;
00444 char *buf = NULL;
00445
00446 strncpy(outbuf, string, buflen);
00447
00448
00449 while (*ptr) {
00450 if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
00451
00452 if (!buf) {
00453 buf = outbuf;
00454 out = buf + (ptr - string) ;
00455 }
00456 out += sprintf(out, "%%%02x", (unsigned char) *ptr);
00457 } else if (buf) {
00458 *out = *ptr;
00459 out++;
00460 }
00461 ptr++;
00462 }
00463 if (buf)
00464 *out = '\0';
00465 return outbuf;
00466 }
00467
00468
00469 void ast_uri_decode(char *s)
00470 {
00471 char *o;
00472 unsigned int tmp;
00473
00474 for (o = s; *s; s++, o++) {
00475 if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
00476
00477 *o = tmp;
00478 s += 2;
00479 } else
00480 *o = *s;
00481 }
00482 *o = '\0';
00483 }
00484
00485
00486 const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia)
00487 {
00488 return inet_ntop(AF_INET, &ia, buf, bufsiz);
00489 }
00490
00491 int ast_utils_init(void)
00492 {
00493 base64_init();
00494 return 0;
00495 }
00496
00497 #ifndef __linux__
00498 #undef pthread_create
00499 #endif
00500
00501 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize)
00502 {
00503 pthread_attr_t lattr;
00504 if (!attr) {
00505 pthread_attr_init(&lattr);
00506 attr = &lattr;
00507 }
00508 #ifdef __linux__
00509
00510
00511
00512
00513
00514
00515
00516 errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED);
00517 if (errno)
00518 ast_log(LOG_WARNING, "pthread_attr_setinheritsched returned non-zero: %s\n", strerror(errno));
00519 #endif
00520
00521 if (!stacksize)
00522 stacksize = AST_STACKSIZE;
00523 errno = pthread_attr_setstacksize(attr, stacksize);
00524 if (errno)
00525 ast_log(LOG_WARNING, "pthread_attr_setstacksize returned non-zero: %s\n", strerror(errno));
00526 return pthread_create(thread, attr, start_routine, data);
00527 }
00528
00529 int ast_wait_for_input(int fd, int ms)
00530 {
00531 struct pollfd pfd[1];
00532 memset(pfd, 0, sizeof(pfd));
00533 pfd[0].fd = fd;
00534 pfd[0].events = POLLIN|POLLPRI;
00535 return poll(pfd, 1, ms);
00536 }
00537
00538 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
00539 {
00540 char *e;
00541 char *q;
00542
00543 s = ast_strip(s);
00544 if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
00545 e = s + strlen(s) - 1;
00546 if (*e == *(end_quotes + (q - beg_quotes))) {
00547 s++;
00548 *e = '\0';
00549 }
00550 }
00551
00552 return s;
00553 }
00554
00555 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
00556 {
00557 int result;
00558
00559 if (!buffer || !*buffer || !space || !*space)
00560 return -1;
00561
00562 result = vsnprintf(*buffer, *space, fmt, ap);
00563
00564 if (result < 0)
00565 return -1;
00566 else if (result > *space)
00567 result = *space;
00568
00569 *buffer += result;
00570 *space -= result;
00571 return 0;
00572 }
00573
00574 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
00575 {
00576 va_list ap;
00577 int result;
00578
00579 va_start(ap, fmt);
00580 result = ast_build_string_va(buffer, space, fmt, ap);
00581 va_end(ap);
00582
00583 return result;
00584 }
00585
00586 int ast_true(const char *s)
00587 {
00588 if (ast_strlen_zero(s))
00589 return 0;
00590
00591
00592 if (!strcasecmp(s, "yes") ||
00593 !strcasecmp(s, "true") ||
00594 !strcasecmp(s, "y") ||
00595 !strcasecmp(s, "t") ||
00596 !strcasecmp(s, "1") ||
00597 !strcasecmp(s, "on"))
00598 return -1;
00599
00600 return 0;
00601 }
00602
00603 int ast_false(const char *s)
00604 {
00605 if (ast_strlen_zero(s))
00606 return 0;
00607
00608
00609 if (!strcasecmp(s, "no") ||
00610 !strcasecmp(s, "false") ||
00611 !strcasecmp(s, "n") ||
00612 !strcasecmp(s, "f") ||
00613 !strcasecmp(s, "0") ||
00614 !strcasecmp(s, "off"))
00615 return -1;
00616
00617 return 0;
00618 }
00619
00620 #define ONE_MILLION 1000000
00621
00622
00623
00624
00625 static struct timeval tvfix(struct timeval a)
00626 {
00627 if (a.tv_usec >= ONE_MILLION) {
00628 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
00629 a.tv_sec, (long int) a.tv_usec);
00630 a.tv_sec += a.tv_usec / ONE_MILLION;
00631 a.tv_usec %= ONE_MILLION;
00632 } else if (a.tv_usec < 0) {
00633 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
00634 a.tv_sec, (long int) a.tv_usec);
00635 a.tv_usec = 0;
00636 }
00637 return a;
00638 }
00639
00640 struct timeval ast_tvadd(struct timeval a, struct timeval b)
00641 {
00642
00643 a = tvfix(a);
00644 b = tvfix(b);
00645 a.tv_sec += b.tv_sec;
00646 a.tv_usec += b.tv_usec;
00647 if (a.tv_usec >= ONE_MILLION) {
00648 a.tv_sec++;
00649 a.tv_usec -= ONE_MILLION;
00650 }
00651 return a;
00652 }
00653
00654 struct timeval ast_tvsub(struct timeval a, struct timeval b)
00655 {
00656
00657 a = tvfix(a);
00658 b = tvfix(b);
00659 a.tv_sec -= b.tv_sec;
00660 a.tv_usec -= b.tv_usec;
00661 if (a.tv_usec < 0) {
00662 a.tv_sec-- ;
00663 a.tv_usec += ONE_MILLION;
00664 }
00665 return a;
00666 }
00667 #undef ONE_MILLION
00668
00669 #ifndef HAVE_STRCASESTR
00670 static char *upper(const char *orig, char *buf, int bufsize)
00671 {
00672 int i = 0;
00673
00674 while (i < (bufsize - 1) && orig[i]) {
00675 buf[i] = toupper(orig[i]);
00676 i++;
00677 }
00678
00679 buf[i] = '\0';
00680
00681 return buf;
00682 }
00683
00684 char *strcasestr(const char *haystack, const char *needle)
00685 {
00686 char *u1, *u2;
00687 int u1len = strlen(haystack) + 1, u2len = strlen(needle) + 1;
00688
00689 u1 = alloca(u1len);
00690 u2 = alloca(u2len);
00691 if (u1 && u2) {
00692 char *offset;
00693 if (u2len > u1len) {
00694
00695 return NULL;
00696 }
00697 offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
00698 if (offset) {
00699
00700 return ((char *)((unsigned long)haystack + (unsigned long)(offset - u1)));
00701 } else {
00702 return NULL;
00703 }
00704 } else {
00705 ast_log(LOG_ERROR, "Out of memory\n");
00706 return NULL;
00707 }
00708 }
00709 #endif
00710
00711 #ifndef HAVE_STRNLEN
00712 size_t strnlen(const char *s, size_t n)
00713 {
00714 size_t len;
00715
00716 for (len=0; len < n; len++)
00717 if (s[len] == '\0')
00718 break;
00719
00720 return len;
00721 }
00722 #endif
00723
00724 #if !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC)
00725 char *strndup(const char *s, size_t n)
00726 {
00727 size_t len = strnlen(s, n);
00728 char *new = malloc(len + 1);
00729
00730 if (!new)
00731 return NULL;
00732
00733 new[len] = '\0';
00734 return memcpy(new, s, len);
00735 }
00736 #endif
00737
00738 #if !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC)
00739 int vasprintf(char **strp, const char *fmt, va_list ap)
00740 {
00741 int size;
00742 va_list ap2;
00743 char s;
00744
00745 *strp = NULL;
00746 va_copy(ap2, ap);
00747 size = vsnprintf(&s, 1, fmt, ap2);
00748 va_end(ap2);
00749 *strp = malloc(size + 1);
00750 if (!*strp)
00751 return -1;
00752 vsnprintf(*strp, size + 1, fmt, ap);
00753
00754 return size;
00755 }
00756 #endif
00757
00758 #ifndef HAVE_STRTOQ
00759 #ifndef LONG_MIN
00760 #define LONG_MIN (-9223372036854775807L-1L)
00761
00762 #endif
00763 #ifndef LONG_MAX
00764 #define LONG_MAX 9223372036854775807L
00765
00766 #endif
00767
00768
00769
00770
00771
00772
00773
00774 uint64_t strtoq(const char *nptr, char **endptr, int base)
00775 {
00776 const char *s;
00777 uint64_t acc;
00778 unsigned char c;
00779 uint64_t qbase, cutoff;
00780 int neg, any, cutlim;
00781
00782
00783
00784
00785
00786
00787 s = nptr;
00788 do {
00789 c = *s++;
00790 } while (isspace(c));
00791 if (c == '-') {
00792 neg = 1;
00793 c = *s++;
00794 } else {
00795 neg = 0;
00796 if (c == '+')
00797 c = *s++;
00798 }
00799 if ((base == 0 || base == 16) &&
00800 c == '\0' && (*s == 'x' || *s == 'X')) {
00801 c = s[1];
00802 s += 2;
00803 base = 16;
00804 }
00805 if (base == 0)
00806 base = c == '\0' ? 8 : 10;
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826 qbase = (unsigned)base;
00827 cutoff = neg ? (uint64_t)-(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX;
00828 cutlim = cutoff % qbase;
00829 cutoff /= qbase;
00830 for (acc = 0, any = 0;; c = *s++) {
00831 if (!isascii(c))
00832 break;
00833 if (isdigit(c))
00834 c -= '\0';
00835 else if (isalpha(c))
00836 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
00837 else
00838 break;
00839 if (c >= base)
00840 break;
00841 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
00842 any = -1;
00843 else {
00844 any = 1;
00845 acc *= qbase;
00846 acc += c;
00847 }
00848 }
00849 if (any < 0) {
00850 acc = neg ? LONG_MIN : LONG_MAX;
00851 } else if (neg)
00852 acc = -acc;
00853 if (endptr != 0)
00854 *((const char **)endptr) = any ? s - 1 : nptr;
00855 return acc;
00856 }
00857 #endif
00858
00859 #ifndef HAVE_GETLOADAVG
00860 #ifdef linux
00861
00862 int getloadavg(double *list, int nelem)
00863 {
00864 FILE *LOADAVG;
00865 double avg[3] = { 0.0, 0.0, 0.0 };
00866 int i, res = -1;
00867
00868 if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
00869 fscanf(LOADAVG, "%lf %lf %lf", &avg[0], &avg[1], &avg[2]);
00870 res = 0;
00871 fclose(LOADAVG);
00872 }
00873
00874 for (i = 0; (i < nelem) && (i < 3); i++) {
00875 list[i] = avg[i];
00876 }
00877
00878 return res;
00879 }
00880 #else
00881
00882
00883 int getloadavg(double *list, int nelem)
00884 {
00885 int i;
00886
00887 for (i = 0; i < nelem; i++) {
00888 list[i] = 0.1;
00889 }
00890 return -1;
00891 }
00892 #endif
00893 #endif
00894
00895 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
00896 {
00897 char *dataPut = start;
00898 int inEscape = 0;
00899 int inQuotes = 0;
00900
00901 for (; *start; start++) {
00902 if (inEscape) {
00903 *dataPut++ = *start;
00904 inEscape = 0;
00905 } else {
00906 if (*start == '\\') {
00907 inEscape = 1;
00908 } else if (*start == '\'') {
00909 inQuotes = 1-inQuotes;
00910 } else {
00911
00912 *dataPut++ = inQuotes ? *start : ((*start==find) ? replace_with : *start);
00913 }
00914 }
00915 }
00916 if (start != dataPut)
00917 *dataPut = 0;
00918 return dataPut;
00919 }
00920
00921 void ast_enable_packet_fragmentation(int sock)
00922 {
00923 #ifdef __linux__
00924 int val = IP_PMTUDISC_DONT;
00925
00926 if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
00927 ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
00928 #endif
00929 }
00930
00931 AST_MUTEX_DEFINE_STATIC(fetchadd_m);
00932
00933 int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
00934 {
00935 int ret;
00936 ast_mutex_lock(&fetchadd_m);
00937 ret = *p;
00938 *p += v;
00939 ast_mutex_unlock(&fetchadd_m);
00940 return ret;
00941 }