Sat Mar 24 23:26:07 2007

Asterisk developer's documentation


utils.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Digium, Inc.
00005  *
00006  * See http://www.asterisk.org for more information about
00007  * the Asterisk project. Please do not directly contact
00008  * any of the maintainers of this project for assistance;
00009  * the project provides a web site, mailing lists and IRC
00010  * channels for your use.
00011  *
00012  * This program is free software, distributed under the terms of
00013  * the GNU General Public License Version 2. See the LICENSE file
00014  * at the top of the source tree.
00015  */
00016 
00017 /*! \file
00018  *
00019  * \brief Utility functions
00020  *
00021  * \note These are important for portability and security,
00022  * so please use them in favour of other routines.
00023  * Please consult the CODING GUIDELINES for more information.
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     /* ensure that inlinable API functions will be built in this module if required */
00050 #include "asterisk/strings.h"
00051 
00052 #define AST_API_MODULE     /* ensure that inlinable API functions will be built in this module if required */
00053 #include "asterisk/time.h"
00054 
00055 #define AST_API_MODULE     /* ensure that inlinable API functions will be built in this module if required */
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 /* duh? ERANGE value copied from web... */
00064 #define ERANGE 34
00065 #undef gethostbyname
00066 
00067 AST_MUTEX_DEFINE_STATIC(__mutex);
00068 
00069 /* Recursive replacement for gethostbyname for BSD-based systems.  This
00070 routine is derived from code originally written and placed in the public 
00071 domain by Enzo Michelangeli <em@em.no-ip.com> */
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); /* begin critical area */
00080    hsave = h_errno;
00081 
00082    ph = gethostbyname(name);
00083    *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
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       /* determine if we have enough space in buf */
00092 
00093       /* count how many addresses */
00094       for (p = ph->h_addr_list; *p != 0; p++) {
00095          nbytes += ph->h_length; /* addresses */
00096          nbytes += sizeof(*p); /* pointers */
00097          naddr++;
00098       }
00099       nbytes += sizeof(*p); /* one more for the terminating NULL */
00100 
00101       /* count how many aliases, and total length of strings */
00102       for (p = ph->h_aliases; *p != 0; p++) {
00103          nbytes += (strlen(*p)+1); /* aliases */
00104          nbytes += sizeof(*p);  /* pointers */
00105          naliases++;
00106       }
00107       nbytes += sizeof(*p); /* one more for the terminating NULL */
00108 
00109       /* here nbytes is the number of bytes required in buffer */
00110       /* as a terminator must be there, the minimum value is ph->h_length */
00111       if(nbytes > buflen) {
00112          *result = NULL;
00113          ast_mutex_unlock(&__mutex); /* end critical area */
00114          return ERANGE; /* not enough space in buf!! */
00115       }
00116 
00117       /* There is enough space. Now we need to do a deep copy! */
00118       /* Allocation in buffer:
00119          from [0] to [(naddr-1) * sizeof(*p)]:
00120          pointers to addresses
00121          at [naddr * sizeof(*p)]:
00122          NULL
00123          from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
00124          pointers to aliases
00125          at [(naddr+naliases+1) * sizeof(*p)]:
00126          NULL
00127          then naddr addresses (fixed length), and naliases aliases (asciiz).
00128       */
00129 
00130       *ret = *ph;   /* copy whole structure (not its address!) */
00131 
00132       /* copy addresses */
00133       q = (char **)buf; /* pointer to pointers area (type: char **) */
00134       ret->h_addr_list = q; /* update pointer to address list */
00135       pbuf = buf + ((naddr+naliases+2)*sizeof(*p)); /* skip that area */
00136       for (p = ph->h_addr_list; *p != 0; p++) {
00137          memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
00138          *q++ = pbuf; /* the pointer is the one inside buf... */
00139          pbuf += ph->h_length; /* advance pbuf */
00140       }
00141       *q++ = NULL; /* address list terminator */
00142 
00143       /* copy aliases */
00144       ret->h_aliases = q; /* update pointer to aliases list */
00145       for (p = ph->h_aliases; *p != 0; p++) {
00146          strcpy(pbuf, *p); /* copy alias strings */
00147          *q++ = pbuf; /* the pointer is the one inside buf... */
00148          pbuf += strlen(*p); /* advance pbuf */
00149          *pbuf++ = 0; /* string terminator */
00150       }
00151       *q++ = NULL; /* terminator */
00152 
00153       strcpy(pbuf, ph->h_name); /* copy alias strings */
00154       ret->h_name = pbuf;
00155       pbuf += strlen(ph->h_name); /* advance pbuf */
00156       *pbuf++ = 0; /* string terminator */
00157 
00158       *result = ret;  /* and let *result point to structure */
00159 
00160    }
00161    h_errno = hsave;  /* restore h_errno */
00162    ast_mutex_unlock(&__mutex); /* end critical area */
00163 
00164    return (*result == NULL); /* return 0 on success, non-zero on error */
00165 }
00166 
00167 
00168 #endif
00169 
00170 /*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the 
00171    standard gethostbyname (which is not thread safe)
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    /* Although it is perfectly legitimate to lookup a pure integer, for
00181       the sake of the sanity of people who like to name their peers as
00182       integers, we break with tradition and refuse to look up a
00183       pure integer */
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       /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
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 /*! \brief This is a regression test for recursive mutexes.
00228    test_for_thread_safety() will return 0 if recursive mutex locks are
00229    working properly, and non-zero if they are not working properly. */
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);          /* return 0 on success. */
00279 }
00280 
00281 /*! \brief ast_md5_hash: Produce 16 char MD5 hash of value. ---*/
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       /* Shift in 6 bits of input */
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       /* If we have at least 8 bits left over, take that character 
00317          off the top */
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    /* Dont worry about left over bits, they're extra anyway */
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    /* Reserve one bit for end */
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          /* We want only the top */
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       /* Add one last character for the remaining bits, 
00370          padding the rest with 0 */
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    /* Initialize base-64 Conversion table */
00385    for (x=0;x<26;x++) {
00386       /* A-Z */
00387       base64[x] = 'A' + x;
00388       b2a['A' + x] = x;
00389       /* a-z */
00390       base64[x + 26] = 'a' + x;
00391       b2a['a' + x] = x + 26;
00392       /* 0-9 */
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 /*! \brief  ast_uri_encode: Turn text string to URI-encoded %XX version ---*/
00413 /*    At this point, we're converting from ISO-8859-x (8-bit), not UTF8
00414    as in the SIP protocol spec 
00415    If doreserved == 1 we will convert reserved characters also.
00416    RFC 2396, section 2.4
00417    outbuf needs to have more memory allocated than the instring
00418    to have room for the expansion. Every char that is converted
00419    is replaced by three ASCII characters.
00420 
00421    Note: The doreserved option is needed for replaces header in
00422    SIP transfers.
00423 */
00424 char *ast_uri_encode(char *string, char *outbuf, int buflen, int doreserved) 
00425 {
00426    char *reserved = ";/?:@&=+$, ";  /* Reserved chars */
00427 
00428    char *ptr  = string; /* Start with the string */
00429    char *out = NULL;
00430    char *buf = NULL;
00431 
00432    strncpy(outbuf, string, buflen);
00433 
00434    /* If there's no characters to convert, just go through and don't do anything */
00435    while (*ptr) {
00436       if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
00437          /* Oops, we need to start working here */
00438          if (!buf) {
00439             buf = outbuf;
00440             out = buf + (ptr - string) ;  /* Set output ptr */
00441          }
00442          out += sprintf(out, "%%%02x", (unsigned char) *ptr);
00443       } else if (buf) {
00444          *out = *ptr;   /* Continue copying the string */
00445          out++;
00446       } 
00447       ptr++;
00448    }
00449    if (buf)
00450       *out = '\0';
00451    return outbuf;
00452 }
00453 
00454 /*! \brief  ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string)  ---*/
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          /* have '%', two chars and correct parsing */
00463          *o = tmp;
00464          s += 2;  /* Will be incremented once more when we break out */
00465       } else /* all other cases, just copy */
00466          *o = *s;
00467    }
00468    *o = '\0';
00469 }
00470 
00471 /*! \brief  ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
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 /* For ast_pthread_create function only */
00485 #endif /* !__linux__ */
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    /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
00496       which is kind of useless. Change this here to
00497       PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
00498       priority will propagate down to new threads by default.
00499       This does mean that callers cannot set a different priority using
00500       PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
00501       the priority afterwards with pthread_setschedparam(). */
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); /* We're in ast_pthread_create, so it's okay */
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    /* Determine if this is a true value */
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    /* Determine if this is a false value */
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  * put timeval in a valid range. usec is 0..999999
00609  * negative values are not allowed and truncated.
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    /* consistency checks to guarantee usec in 0..999999 */
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    /* consistency checks to guarantee usec in 0..999999 */
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          /* Needle bigger than haystack */
00681          return NULL;
00682       }
00683       offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
00684       if (offset) {
00685          /* Return the offset into the original string */
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 /* !HAVE_STRCASESTR */
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 /* !HAVE_STRNLEN */
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 /* !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC) */
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 /* !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
00743 
00744 #ifndef HAVE_STRTOQ
00745 #ifndef LONG_MIN
00746 #define LONG_MIN        (-9223372036854775807L-1L)
00747                                     /* min value of a "long int" */
00748 #endif
00749 #ifndef LONG_MAX
00750 #define LONG_MAX        9223372036854775807L
00751                                     /* max value of a "long int" */
00752 #endif
00753 
00754 /*
00755  * Convert a string to a quad integer.
00756  *
00757  * Ignores `locale' stuff.  Assumes that the upper and lower case
00758  * alphabets and digits are each contiguous.
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      * Skip white space and pick up leading +/- sign if any.
00770      * If base is 0, allow 0x for hex and 0 for octal, else
00771      * assume decimal; if base is already 16, allow 0x.
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      * Compute the cutoff value between legal numbers and illegal
00796      * numbers.  That is the largest legal value, divided by the
00797      * base.  An input number that is greater than this value, if
00798      * followed by a legal input character, is too big.  One that
00799      * is equal to this value may be valid or not; the limit
00800      * between valid and invalid numbers is then based on the last
00801      * digit.  For instance, if the range for quads is
00802      * [-9223372036854775808..9223372036854775807] and the input base
00803      * is 10, cutoff will be set to 922337203685477580 and cutlim to
00804      * either 7 (neg==0) or 8 (neg==1), meaning that if we have
00805      * accumulated a value > 922337203685477580, or equal but the
00806      * next digit is > 7 (or 8), the number is too big, and we will
00807      * return a range error.
00808      *
00809      * Set any if any `digits' consumed; make it negative to indicate
00810      * overflow.
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 /* !HAVE_STRTOQ */
00844 
00845 #ifndef HAVE_GETLOADAVG
00846 #ifdef linux
00847 /* Alternative method of getting load avg on Linux only */
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 /* !linux */
00867 /* Return something that won't cancel the call, but still return -1, in case
00868  * we correct the implementation to check return value */
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 /* linux */
00879 #endif /* !defined(_BSD_SOURCE) */
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;       /* Always goes verbatim */
00890          inEscape = 0;
00891          } else {
00892          if (*start == '\\') {
00893             inEscape = 1;      /* Do not copy \ into the data */
00894          } else if (*start == '\'') {
00895             inQuotes = 1-inQuotes;   /* Do not copy ' into the data */
00896          } else {
00897             /* Replace , with |, unless in quotes */
00898             *dataPut++ = inQuotes ? *start : ((*start==find) ? replace_with : *start);
00899          }
00900       }
00901    }
00902    if (start != dataPut)
00903       *dataPut = 0;
00904    return dataPut;
00905 }

Generated on Sat Mar 24 23:26:07 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.6