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