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