Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:47:56 2009

## Asterisk developer's documentation

- Main Page
- Related Pages
- Modules
- Data Structures
- Files
- Directories

# 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: 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     /* ensure that inlinable API functions will be built in this module if required */
    00053 #include "asterisk/strings.h"
    00054
    00055 #define AST_API_MODULE     /* ensure that inlinable API functions will be built in this module if required */
    00056 #include "asterisk/time.h"
    00057
    00058 #define AST_API_MODULE     /* ensure that inlinable API functions will be built in this module if required */
    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 /* duh? ERANGE value copied from web... */
    00067 #define ERANGE 34
    00068 #undef gethostbyname
    00069
    00070 AST_MUTEX_DEFINE_STATIC(__mutex);
    00071
    00072 /* Recursive replacement for gethostbyname for BSD-based systems.  This
    00073 routine is derived from code originally written and placed in the public
    00074 domain by Enzo Michelangeli <em@em.no-ip.com> */
    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); /* begin critical area */
    00083    hsave = h_errno;
    00084
    00085    ph = gethostbyname(name);
    00086    *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
    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       /* determine if we have enough space in buf */
    00095
    00096       /* count how many addresses */
    00097       for (p = ph->h_addr_list; *p != 0; p++) {
    00098          nbytes += ph->h_length; /* addresses */
    00099          nbytes += sizeof(*p); /* pointers */
    00100          naddr++;
    00101       }
    00102       nbytes += sizeof(*p); /* one more for the terminating NULL */
    00103
    00104       /* count how many aliases, and total length of strings */
    00105       for (p = ph->h_aliases; *p != 0; p++) {
    00106          nbytes += (strlen(*p)+1); /* aliases */
    00107          nbytes += sizeof(*p);  /* pointers */
    00108          naliases++;
    00109       }
    00110       nbytes += sizeof(*p); /* one more for the terminating NULL */
    00111
    00112       /* here nbytes is the number of bytes required in buffer */
    00113       /* as a terminator must be there, the minimum value is ph->h_length */
    00114       if(nbytes > buflen) {
    00115          *result = NULL;
    00116          ast_mutex_unlock(&__mutex); /* end critical area */
    00117          return ERANGE; /* not enough space in buf!! */
    00118       }
    00119
    00120       /* There is enough space. Now we need to do a deep copy! */
    00121       /* Allocation in buffer:
    00122          from [0] to [(naddr-1) * sizeof(*p)]:
    00123          pointers to addresses
    00124          at [naddr * sizeof(*p)]:
    00125          NULL
    00126          from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
    00127          pointers to aliases
    00128          at [(naddr+naliases+1) * sizeof(*p)]:
    00129          NULL
    00130          then naddr addresses (fixed length), and naliases aliases (asciiz).
    00131       */
    00132
    00133       *ret = *ph;   /* copy whole structure (not its address!) */
    00134
    00135       /* copy addresses */
    00136       q = (char **)buf; /* pointer to pointers area (type: char **) */
    00137       ret->h_addr_list = q; /* update pointer to address list */
    00138       pbuf = buf + ((naddr+naliases+2)*sizeof(*p)); /* skip that area */
    00139       for (p = ph->h_addr_list; *p != 0; p++) {
    00140          memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
    00141          *q++ = pbuf; /* the pointer is the one inside buf... */
    00142          pbuf += ph->h_length; /* advance pbuf */
    00143       }
    00144       *q++ = NULL; /* address list terminator */
    00145
    00146       /* copy aliases */
    00147       ret->h_aliases = q; /* update pointer to aliases list */
    00148       for (p = ph->h_aliases; *p != 0; p++) {
    00149          strcpy(pbuf, *p); /* copy alias strings */
    00150          *q++ = pbuf; /* the pointer is the one inside buf... */
    00151          pbuf += strlen(*p); /* advance pbuf */
    00152          *pbuf++ = 0; /* string terminator */
    00153       }
    00154       *q++ = NULL; /* terminator */
    00155
    00156       strcpy(pbuf, ph->h_name); /* copy alias strings */
    00157       ret->h_name = pbuf;
    00158       pbuf += strlen(ph->h_name); /* advance pbuf */
    00159       *pbuf++ = 0; /* string terminator */
    00160
    00161       *result = ret;  /* and let *result point to structure */
    00162
    00163    }
    00164    h_errno = hsave;  /* restore h_errno */
    00165    ast_mutex_unlock(&__mutex); /* end critical area */
    00166
    00167    return (*result == NULL); /* return 0 on success, non-zero on error */
    00168 }
    00169
    00170
    00171 #endif
    00172
    00173 /*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the
    00174    standard gethostbyname (which is not thread safe)
    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    /* Although it is perfectly legitimate to lookup a pure integer, for
    00184       the sake of the sanity of people who like to name their peers as
    00185       integers, we break with tradition and refuse to look up a
    00186       pure integer */
    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       /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
    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 /*! \brief This is a regression test for recursive mutexes.
    00232    test_for_thread_safety() will return 0 if recursive mutex locks are
    00233    working properly, and non-zero if they are not working properly. */
    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);          /* return 0 on success. */
    00283 }
    00284
    00285 /*! \brief ast_md5_hash: Produce 16 char MD5 hash of value. ---*/
    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 /*! \brief Produce 40 char SHA1 hash of value. */
    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       /* Shift in 6 bits of input */
    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       /* If we have at least 8 bits left over, take that character
    00339          off the top */
    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    /* Dont worry about left over bits, they're extra anyway */
    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    /* Reserve one bit for end */
    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          /* We want only the top */
    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       /* Add one last character for the remaining bits,
    00392          padding the rest with 0 */
    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    /* Initialize base-64 Conversion table */
    00407    for (x=0;x<26;x++) {
    00408       /* A-Z */
    00409       base64[x] = 'A' + x;
    00410       b2a['A' + x] = x;
    00411       /* a-z */
    00412       base64[x + 26] = 'a' + x;
    00413       b2a['a' + x] = x + 26;
    00414       /* 0-9 */
    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 /*! \brief  ast_uri_encode: Turn text string to URI-encoded %XX version ---*/
    00427 /*    At this point, we're converting from ISO-8859-x (8-bit), not UTF8
    00428    as in the SIP protocol spec
    00429    If doreserved == 1 we will convert reserved characters also.
    00430    RFC 2396, section 2.4
    00431    outbuf needs to have more memory allocated than the instring
    00432    to have room for the expansion. Every char that is converted
    00433    is replaced by three ASCII characters.
    00434
    00435    Note: The doreserved option is needed for replaces header in
    00436    SIP transfers.
    00437 */
    00438 char *ast_uri_encode(char *string, char *outbuf, int buflen, int doreserved)
    00439 {
    00440    char *reserved = ";/?:@&=+$, ";  /* Reserved chars */
    00441
    00442    char *ptr  = string; /* Start with the string */
    00443    char *out = NULL;
    00444    char *buf = NULL;
    00445
    00446    strncpy(outbuf, string, buflen);
    00447
    00448    /* If there's no characters to convert, just go through and don't do anything */
    00449    while (*ptr) {
    00450       if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
    00451          /* Oops, we need to start working here */
    00452          if (!buf) {
    00453             buf = outbuf;
    00454             out = buf + (ptr - string) ;  /* Set output ptr */
    00455          }
    00456          out += sprintf(out, "%%%02x", (unsigned char) *ptr);
    00457       } else if (buf) {
    00458          *out = *ptr;   /* Continue copying the string */
    00459          out++;
    00460       }
    00461       ptr++;
    00462    }
    00463    if (buf)
    00464       *out = '\0';
    00465    return outbuf;
    00466 }
    00467
    00468 /*! \brief  ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string)  ---*/
    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          /* have '%', two chars and correct parsing */
    00477          *o = tmp;
    00478          s += 2;  /* Will be incremented once more when we break out */
    00479       } else /* all other cases, just copy */
    00480          *o = *s;
    00481    }
    00482    *o = '\0';
    00483 }
    00484
    00485 /*! \brief  ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
    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 /* For ast_pthread_create function only */
    00499 #endif /* !__linux__ */
    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    /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
    00510       which is kind of useless. Change this here to
    00511       PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
    00512       priority will propagate down to new threads by default.
    00513       This does mean that callers cannot set a different priority using
    00514       PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
    00515       the priority afterwards with pthread_setschedparam(). */
    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); /* We're in ast_pthread_create, so it's okay */
    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    /* Determine if this is a true value */
    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    /* Determine if this is a false value */
    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  * put timeval in a valid range. usec is 0..999999
    00623  * negative values are not allowed and truncated.
    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    /* 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 >= 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    /* consistency checks to guarantee usec in 0..999999 */
    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          /* Needle bigger than haystack */
    00695          return NULL;
    00696       }
    00697       offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
    00698       if (offset) {
    00699          /* Return the offset into the original string */
    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 /* !HAVE_STRCASESTR */
    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 /* !HAVE_STRNLEN */
    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 /* !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC) */
    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 /* !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
    00757
    00758 #ifndef HAVE_STRTOQ
    00759 #ifndef LONG_MIN
    00760 #define LONG_MIN        (-9223372036854775807L-1L)
    00761                                     /* min value of a "long int" */
    00762 #endif
    00763 #ifndef LONG_MAX
    00764 #define LONG_MAX        9223372036854775807L
    00765                                     /* max value of a "long int" */
    00766 #endif
    00767
    00768 /*
    00769  * Convert a string to a quad integer.
    00770  *
    00771  * Ignores `locale' stuff.  Assumes that the upper and lower case
    00772  * alphabets and digits are each contiguous.
    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      * Skip white space and pick up leading +/- sign if any.
    00784      * If base is 0, allow 0x for hex and 0 for octal, else
    00785      * assume decimal; if base is already 16, allow 0x.
    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      * Compute the cutoff value between legal numbers and illegal
    00810      * numbers.  That is the largest legal value, divided by the
    00811      * base.  An input number that is greater than this value, if
    00812      * followed by a legal input character, is too big.  One that
    00813      * is equal to this value may be valid or not; the limit
    00814      * between valid and invalid numbers is then based on the last
    00815      * digit.  For instance, if the range for quads is
    00816      * [-9223372036854775808..9223372036854775807] and the input base
    00817      * is 10, cutoff will be set to 922337203685477580 and cutlim to
    00818      * either 7 (neg==0) or 8 (neg==1), meaning that if we have
    00819      * accumulated a value > 922337203685477580, or equal but the
    00820      * next digit is > 7 (or 8), the number is too big, and we will
    00821      * return a range error.
    00822      *
    00823      * Set any if any `digits' consumed; make it negative to indicate
    00824      * overflow.
    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 /* !HAVE_STRTOQ */
    00858
    00859 #ifndef HAVE_GETLOADAVG
    00860 #ifdef linux
    00861 /* Alternative method of getting load avg on Linux only */
    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 /* !linux */
    00881 /* Return something that won't cancel the call, but still return -1, in case
    00882  * we correct the implementation to check return value */
    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 /* linux */
    00893 #endif /* !defined(_BSD_SOURCE) */
    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;       /* Always goes verbatim */
    00904          inEscape = 0;
    00905          } else {
    00906          if (*start == '\\') {
    00907             inEscape = 1;      /* Do not copy \ into the data */
    00908          } else if (*start == '\'') {
    00909             inQuotes = 1-inQuotes;   /* Do not copy ' into the data */
    00910          } else {
    00911             /* Replace , with |, unless in quotes */
    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); /* used for all fetc&add ops */
    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 }