Thu Apr 28 2011 17:15:25

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 - 2006, 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 "asterisk.h"
00027 
00028 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 302554 $")
00029 
00030 #include <ctype.h>
00031 #include <sys/stat.h>
00032 #include <sys/stat.h>
00033 
00034 #ifdef HAVE_DEV_URANDOM
00035 #include <fcntl.h>
00036 #endif
00037 
00038 #include "asterisk/network.h"
00039 
00040 #define AST_API_MODULE     /* ensure that inlinable API functions will be built in lock.h if required */
00041 #include "asterisk/lock.h"
00042 #include "asterisk/io.h"
00043 #include "asterisk/md5.h"
00044 #include "asterisk/sha1.h"
00045 #include "asterisk/cli.h"
00046 #include "asterisk/linkedlists.h"
00047 
00048 #define AST_API_MODULE     /* ensure that inlinable API functions will be built in this module if required */
00049 #include "asterisk/strings.h"
00050 
00051 #define AST_API_MODULE     /* ensure that inlinable API functions will be built in this module if required */
00052 #include "asterisk/time.h"
00053 
00054 #define AST_API_MODULE     /* ensure that inlinable API functions will be built in this module if required */
00055 #include "asterisk/stringfields.h"
00056 
00057 #define AST_API_MODULE     /* ensure that inlinable API functions will be built in this module if required */
00058 #include "asterisk/utils.h"
00059 
00060 #define AST_API_MODULE
00061 #include "asterisk/threadstorage.h"
00062 
00063 #define AST_API_MODULE
00064 #include "asterisk/config.h"
00065 
00066 static char base64[64];
00067 static char b2a[256];
00068 
00069 AST_THREADSTORAGE(inet_ntoa_buf);
00070 
00071 #if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6)
00072 
00073 #define ERANGE 34 /*!< duh? ERANGE value copied from web... */
00074 #undef gethostbyname
00075 
00076 AST_MUTEX_DEFINE_STATIC(__mutex);
00077 
00078 /*! \brief Reentrant replacement for gethostbyname for BSD-based systems.
00079 \note This
00080 routine is derived from code originally written and placed in the public 
00081 domain by Enzo Michelangeli <em@em.no-ip.com> */
00082 
00083 static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
00084             size_t buflen, struct hostent **result, 
00085             int *h_errnop) 
00086 {
00087    int hsave;
00088    struct hostent *ph;
00089    ast_mutex_lock(&__mutex); /* begin critical area */
00090    hsave = h_errno;
00091 
00092    ph = gethostbyname(name);
00093    *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
00094    if (ph == NULL) {
00095       *result = NULL;
00096    } else {
00097       char **p, **q;
00098       char *pbuf;
00099       int nbytes = 0;
00100       int naddr = 0, naliases = 0;
00101       /* determine if we have enough space in buf */
00102 
00103       /* count how many addresses */
00104       for (p = ph->h_addr_list; *p != 0; p++) {
00105          nbytes += ph->h_length; /* addresses */
00106          nbytes += sizeof(*p); /* pointers */
00107          naddr++;
00108       }
00109       nbytes += sizeof(*p); /* one more for the terminating NULL */
00110 
00111       /* count how many aliases, and total length of strings */
00112       for (p = ph->h_aliases; *p != 0; p++) {
00113          nbytes += (strlen(*p)+1); /* aliases */
00114          nbytes += sizeof(*p);  /* pointers */
00115          naliases++;
00116       }
00117       nbytes += sizeof(*p); /* one more for the terminating NULL */
00118 
00119       /* here nbytes is the number of bytes required in buffer */
00120       /* as a terminator must be there, the minimum value is ph->h_length */
00121       if (nbytes > buflen) {
00122          *result = NULL;
00123          ast_mutex_unlock(&__mutex); /* end critical area */
00124          return ERANGE; /* not enough space in buf!! */
00125       }
00126 
00127       /* There is enough space. Now we need to do a deep copy! */
00128       /* Allocation in buffer:
00129          from [0] to [(naddr-1) * sizeof(*p)]:
00130          pointers to addresses
00131          at [naddr * sizeof(*p)]:
00132          NULL
00133          from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
00134          pointers to aliases
00135          at [(naddr+naliases+1) * sizeof(*p)]:
00136          NULL
00137          then naddr addresses (fixed length), and naliases aliases (asciiz).
00138       */
00139 
00140       *ret = *ph;   /* copy whole structure (not its address!) */
00141 
00142       /* copy addresses */
00143       q = (char **)buf; /* pointer to pointers area (type: char **) */
00144       ret->h_addr_list = q; /* update pointer to address list */
00145       pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
00146       for (p = ph->h_addr_list; *p != 0; p++) {
00147          memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
00148          *q++ = pbuf; /* the pointer is the one inside buf... */
00149          pbuf += ph->h_length; /* advance pbuf */
00150       }
00151       *q++ = NULL; /* address list terminator */
00152 
00153       /* copy aliases */
00154       ret->h_aliases = q; /* update pointer to aliases list */
00155       for (p = ph->h_aliases; *p != 0; p++) {
00156          strcpy(pbuf, *p); /* copy alias strings */
00157          *q++ = pbuf; /* the pointer is the one inside buf... */
00158          pbuf += strlen(*p); /* advance pbuf */
00159          *pbuf++ = 0; /* string terminator */
00160       }
00161       *q++ = NULL; /* terminator */
00162 
00163       strcpy(pbuf, ph->h_name); /* copy alias strings */
00164       ret->h_name = pbuf;
00165       pbuf += strlen(ph->h_name); /* advance pbuf */
00166       *pbuf++ = 0; /* string terminator */
00167 
00168       *result = ret;  /* and let *result point to structure */
00169 
00170    }
00171    h_errno = hsave;  /* restore h_errno */
00172    ast_mutex_unlock(&__mutex); /* end critical area */
00173 
00174    return (*result == NULL); /* return 0 on success, non-zero on error */
00175 }
00176 
00177 
00178 #endif
00179 
00180 /*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the 
00181    standard gethostbyname (which is not thread safe)
00182 */
00183 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
00184 {
00185    int res;
00186    int herrno;
00187    int dots = 0;
00188    const char *s;
00189    struct hostent *result = NULL;
00190    /* Although it is perfectly legitimate to lookup a pure integer, for
00191       the sake of the sanity of people who like to name their peers as
00192       integers, we break with tradition and refuse to look up a
00193       pure integer */
00194    s = host;
00195    res = 0;
00196    while (s && *s) {
00197       if (*s == '.')
00198          dots++;
00199       else if (!isdigit(*s))
00200          break;
00201       s++;
00202    }
00203    if (!s || !*s) {
00204       /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
00205       if (dots != 3)
00206          return NULL;
00207       memset(hp, 0, sizeof(struct ast_hostent));
00208       hp->hp.h_addrtype = AF_INET;
00209       hp->hp.h_addr_list = (void *) hp->buf;
00210       hp->hp.h_addr = hp->buf + sizeof(void *);
00211       /* For AF_INET, this will always be 4 */
00212       hp->hp.h_length = 4;
00213       if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
00214          return &hp->hp;
00215       return NULL;
00216       
00217    }
00218 #ifdef HAVE_GETHOSTBYNAME_R_5
00219    result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
00220 
00221    if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
00222       return NULL;
00223 #else
00224    res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
00225 
00226    if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
00227       return NULL;
00228 #endif
00229    return &hp->hp;
00230 }
00231 
00232 /*! \brief Produce 32 char MD5 hash of value. */
00233 void ast_md5_hash(char *output, char *input)
00234 {
00235    struct MD5Context md5;
00236    unsigned char digest[16];
00237    char *ptr;
00238    int x;
00239 
00240    MD5Init(&md5);
00241    MD5Update(&md5, (unsigned char *)input, strlen(input));
00242    MD5Final(digest, &md5);
00243    ptr = output;
00244    for (x = 0; x < 16; x++)
00245       ptr += sprintf(ptr, "%2.2x", digest[x]);
00246 }
00247 
00248 /*! \brief Produce 40 char SHA1 hash of value. */
00249 void ast_sha1_hash(char *output, char *input)
00250 {
00251    struct SHA1Context sha;
00252    char *ptr;
00253    int x;
00254    uint8_t Message_Digest[20];
00255 
00256    SHA1Reset(&sha);
00257    
00258    SHA1Input(&sha, (const unsigned char *) input, strlen(input));
00259 
00260    SHA1Result(&sha, Message_Digest);
00261    ptr = output;
00262    for (x = 0; x < 20; x++)
00263       ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
00264 }
00265 
00266 /*! \brief decode BASE64 encoded text */
00267 int ast_base64decode(unsigned char *dst, const char *src, int max)
00268 {
00269    int cnt = 0;
00270    unsigned int byte = 0;
00271    unsigned int bits = 0;
00272    int incnt = 0;
00273    while(*src && *src != '=' && (cnt < max)) {
00274       /* Shift in 6 bits of input */
00275       byte <<= 6;
00276       byte |= (b2a[(int)(*src)]) & 0x3f;
00277       bits += 6;
00278       src++;
00279       incnt++;
00280       /* If we have at least 8 bits left over, take that character 
00281          off the top */
00282       if (bits >= 8)  {
00283          bits -= 8;
00284          *dst = (byte >> bits) & 0xff;
00285          dst++;
00286          cnt++;
00287       }
00288    }
00289    /* Dont worry about left over bits, they're extra anyway */
00290    return cnt;
00291 }
00292 
00293 /*! \brief encode text to BASE64 coding */
00294 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
00295 {
00296    int cnt = 0;
00297    int col = 0;
00298    unsigned int byte = 0;
00299    int bits = 0;
00300    int cntin = 0;
00301    /* Reserve space for null byte at end of string */
00302    max--;
00303    while ((cntin < srclen) && (cnt < max)) {
00304       byte <<= 8;
00305       byte |= *(src++);
00306       bits += 8;
00307       cntin++;
00308       if ((bits == 24) && (cnt + 4 <= max)) {
00309          *dst++ = base64[(byte >> 18) & 0x3f];
00310          *dst++ = base64[(byte >> 12) & 0x3f];
00311          *dst++ = base64[(byte >> 6) & 0x3f];
00312          *dst++ = base64[byte & 0x3f];
00313          cnt += 4;
00314          col += 4;
00315          bits = 0;
00316          byte = 0;
00317       }
00318       if (linebreaks && (cnt < max) && (col == 64)) {
00319          *dst++ = '\n';
00320          cnt++;
00321          col = 0;
00322       }
00323    }
00324    if (bits && (cnt + 4 <= max)) {
00325       /* Add one last character for the remaining bits, 
00326          padding the rest with 0 */
00327       byte <<= 24 - bits;
00328       *dst++ = base64[(byte >> 18) & 0x3f];
00329       *dst++ = base64[(byte >> 12) & 0x3f];
00330       if (bits == 16)
00331          *dst++ = base64[(byte >> 6) & 0x3f];
00332       else
00333          *dst++ = '=';
00334       *dst++ = '=';
00335       cnt += 4;
00336    }
00337    if (linebreaks && (cnt < max)) {
00338       *dst++ = '\n';
00339       cnt++;
00340    }
00341    *dst = '\0';
00342    return cnt;
00343 }
00344 
00345 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
00346 {
00347    return ast_base64encode_full(dst, src, srclen, max, 0);
00348 }
00349 
00350 static void base64_init(void)
00351 {
00352    int x;
00353    memset(b2a, -1, sizeof(b2a));
00354    /* Initialize base-64 Conversion table */
00355    for (x = 0; x < 26; x++) {
00356       /* A-Z */
00357       base64[x] = 'A' + x;
00358       b2a['A' + x] = x;
00359       /* a-z */
00360       base64[x + 26] = 'a' + x;
00361       b2a['a' + x] = x + 26;
00362       /* 0-9 */
00363       if (x < 10) {
00364          base64[x + 52] = '0' + x;
00365          b2a['0' + x] = x + 52;
00366       }
00367    }
00368    base64[62] = '+';
00369    base64[63] = '/';
00370    b2a[(int)'+'] = 62;
00371    b2a[(int)'/'] = 63;
00372 }
00373 
00374 /*! \brief  ast_uri_encode: Turn text string to URI-encoded %XX version
00375 \note    At this point, we're converting from ISO-8859-x (8-bit), not UTF8
00376    as in the SIP protocol spec 
00377    If doreserved == 1 we will convert reserved characters also.
00378    RFC 2396, section 2.4
00379    outbuf needs to have more memory allocated than the instring
00380    to have room for the expansion. Every char that is converted
00381    is replaced by three ASCII characters.
00382 
00383    Note: The doreserved option is needed for replaces header in
00384    SIP transfers.
00385 */
00386 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved) 
00387 {
00388    char *reserved = ";/?:@&=+$,# "; /* Reserved chars */
00389 
00390    const char *ptr  = string; /* Start with the string */
00391    char *out = outbuf;
00392 
00393    /* If there's no characters to convert, just go through and copy the string */
00394    while (*ptr && out - outbuf < buflen - 1) {
00395       if ((*ptr < 32) || (doreserved && strchr(reserved, *ptr))) {
00396          if (out - outbuf >= buflen - 3) {
00397             break;
00398          }
00399 
00400          out += sprintf(out, "%%%02x", (unsigned char) *ptr);
00401       } else {
00402          *out = *ptr;   /* copy the character */
00403          out++;
00404       }
00405       ptr++;
00406    }
00407 
00408    if (buflen) {
00409       *out = '\0';
00410    }
00411 
00412    return outbuf;
00413 }
00414 
00415 /*! \brief  ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string)  */
00416 void ast_uri_decode(char *s) 
00417 {
00418    char *o;
00419    unsigned int tmp;
00420 
00421    for (o = s; *s; s++, o++) {
00422       if (*s == '%' && s[1] != '\0' && s[2] != '\0' && sscanf(s + 1, "%2x", &tmp) == 1) {
00423          /* have '%', two chars and correct parsing */
00424          *o = tmp;
00425          s += 2;  /* Will be incremented once more when we break out */
00426       } else /* all other cases, just copy */
00427          *o = *s;
00428    }
00429    *o = '\0';
00430 }
00431 
00432 /*! \brief  ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
00433 const char *ast_inet_ntoa(struct in_addr ia)
00434 {
00435    char *buf;
00436 
00437    if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
00438       return "";
00439 
00440    return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
00441 }
00442 
00443 #ifdef HAVE_DEV_URANDOM
00444 static int dev_urandom_fd;
00445 #endif
00446 
00447 #ifndef __linux__
00448 #undef pthread_create /* For ast_pthread_create function only */
00449 #endif /* !__linux__ */
00450 
00451 #if !defined(LOW_MEMORY)
00452 
00453 #ifdef DEBUG_THREADS
00454 
00455 /*! \brief A reasonable maximum number of locks a thread would be holding ... */
00456 #define AST_MAX_LOCKS 64
00457 
00458 /* Allow direct use of pthread_mutex_t and friends */
00459 #undef pthread_mutex_t
00460 #undef pthread_mutex_lock
00461 #undef pthread_mutex_unlock
00462 #undef pthread_mutex_init
00463 #undef pthread_mutex_destroy
00464 
00465 /*! 
00466  * \brief Keep track of which locks a thread holds 
00467  *
00468  * There is an instance of this struct for every active thread
00469  */
00470 struct thr_lock_info {
00471    /*! The thread's ID */
00472    pthread_t thread_id;
00473    /*! The thread name which includes where the thread was started */
00474    const char *thread_name;
00475    /*! This is the actual container of info for what locks this thread holds */
00476    struct {
00477       const char *file;
00478       int line_num;
00479       const char *func;
00480       const char *lock_name;
00481       void *lock_addr;
00482       int times_locked;
00483       enum ast_lock_type type;
00484       /*! This thread is waiting on this lock */
00485       int pending:2;
00486 #ifdef HAVE_BKTR
00487       struct ast_bt *backtrace;
00488 #endif
00489    } locks[AST_MAX_LOCKS];
00490    /*! This is the number of locks currently held by this thread.
00491     *  The index (num_locks - 1) has the info on the last one in the
00492     *  locks member */
00493    unsigned int num_locks;
00494    /*! Protects the contents of the locks member 
00495     * Intentionally not ast_mutex_t */
00496    pthread_mutex_t lock;
00497    AST_LIST_ENTRY(thr_lock_info) entry;
00498 };
00499 
00500 /*! 
00501  * \brief Locked when accessing the lock_infos list 
00502  */
00503 AST_MUTEX_DEFINE_STATIC(lock_infos_lock);
00504 /*!
00505  * \brief A list of each thread's lock info 
00506  */
00507 static AST_LIST_HEAD_NOLOCK_STATIC(lock_infos, thr_lock_info);
00508 
00509 /*!
00510  * \brief Destroy a thread's lock info
00511  *
00512  * This gets called automatically when the thread stops
00513  */
00514 static void lock_info_destroy(void *data)
00515 {
00516    struct thr_lock_info *lock_info = data;
00517    int i;
00518 
00519    pthread_mutex_lock(&lock_infos_lock.mutex);
00520    AST_LIST_REMOVE(&lock_infos, lock_info, entry);
00521    pthread_mutex_unlock(&lock_infos_lock.mutex);
00522 
00523 
00524    for (i = 0; i < lock_info->num_locks; i++) {
00525       if (lock_info->locks[i].pending == -1) {
00526          /* This just means that the last lock this thread went for was by
00527           * using trylock, and it failed.  This is fine. */
00528          break;
00529       }
00530 
00531       ast_log(LOG_ERROR, 
00532          "Thread '%s' still has a lock! - '%s' (%p) from '%s' in %s:%d!\n", 
00533          lock_info->thread_name,
00534          lock_info->locks[i].lock_name,
00535          lock_info->locks[i].lock_addr,
00536          lock_info->locks[i].func,
00537          lock_info->locks[i].file,
00538          lock_info->locks[i].line_num
00539       );
00540    }
00541 
00542    pthread_mutex_destroy(&lock_info->lock);
00543    if (lock_info->thread_name)
00544       free((void *) lock_info->thread_name);
00545    free(lock_info);
00546 }
00547 
00548 /*!
00549  * \brief The thread storage key for per-thread lock info
00550  */
00551 AST_THREADSTORAGE_CUSTOM(thread_lock_info, NULL, lock_info_destroy);
00552 #ifdef HAVE_BKTR
00553 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
00554    int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
00555 #else
00556 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
00557    int line_num, const char *func, const char *lock_name, void *lock_addr)
00558 #endif
00559 {
00560    struct thr_lock_info *lock_info;
00561    int i;
00562 
00563    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00564       return;
00565 
00566    pthread_mutex_lock(&lock_info->lock);
00567 
00568    for (i = 0; i < lock_info->num_locks; i++) {
00569       if (lock_info->locks[i].lock_addr == lock_addr) {
00570          lock_info->locks[i].times_locked++;
00571 #ifdef HAVE_BKTR
00572          lock_info->locks[i].backtrace = bt;
00573 #endif
00574          pthread_mutex_unlock(&lock_info->lock);
00575          return;
00576       }
00577    }
00578 
00579    if (lock_info->num_locks == AST_MAX_LOCKS) {
00580       /* Can't use ast_log here, because it will cause infinite recursion */
00581       fprintf(stderr, "XXX ERROR XXX A thread holds more locks than '%d'."
00582          "  Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
00583       pthread_mutex_unlock(&lock_info->lock);
00584       return;
00585    }
00586 
00587    if (i && lock_info->locks[i - 1].pending == -1) {
00588       /* The last lock on the list was one that this thread tried to lock but
00589        * failed at doing so.  It has now moved on to something else, so remove
00590        * the old lock from the list. */
00591       i--;
00592       lock_info->num_locks--;
00593       memset(&lock_info->locks[i], 0, sizeof(lock_info->locks[0]));
00594    }
00595 
00596    lock_info->locks[i].file = filename;
00597    lock_info->locks[i].line_num = line_num;
00598    lock_info->locks[i].func = func;
00599    lock_info->locks[i].lock_name = lock_name;
00600    lock_info->locks[i].lock_addr = lock_addr;
00601    lock_info->locks[i].times_locked = 1;
00602    lock_info->locks[i].type = type;
00603    lock_info->locks[i].pending = 1;
00604 #ifdef HAVE_BKTR
00605    lock_info->locks[i].backtrace = bt;
00606 #endif
00607    lock_info->num_locks++;
00608 
00609    pthread_mutex_unlock(&lock_info->lock);
00610 }
00611 
00612 void ast_mark_lock_acquired(void *lock_addr)
00613 {
00614    struct thr_lock_info *lock_info;
00615 
00616    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00617       return;
00618 
00619    pthread_mutex_lock(&lock_info->lock);
00620    if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
00621       lock_info->locks[lock_info->num_locks - 1].pending = 0;
00622    }
00623    pthread_mutex_unlock(&lock_info->lock);
00624 }
00625 
00626 void ast_mark_lock_failed(void *lock_addr)
00627 {
00628    struct thr_lock_info *lock_info;
00629 
00630    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00631       return;
00632 
00633    pthread_mutex_lock(&lock_info->lock);
00634    if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
00635       lock_info->locks[lock_info->num_locks - 1].pending = -1;
00636       lock_info->locks[lock_info->num_locks - 1].times_locked--;
00637    }
00638    pthread_mutex_unlock(&lock_info->lock);
00639 }
00640 
00641 int ast_find_lock_info(void *lock_addr, char *filename, size_t filename_size, int *lineno, char *func, size_t func_size, char *mutex_name, size_t mutex_name_size)
00642 {
00643    struct thr_lock_info *lock_info;
00644    int i = 0;
00645 
00646    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00647       return -1;
00648 
00649    pthread_mutex_lock(&lock_info->lock);
00650 
00651    for (i = lock_info->num_locks - 1; i >= 0; i--) {
00652       if (lock_info->locks[i].lock_addr == lock_addr)
00653          break;
00654    }
00655 
00656    if (i == -1) {
00657       /* Lock not found :( */
00658       pthread_mutex_unlock(&lock_info->lock);
00659       return -1;
00660    }
00661 
00662    ast_copy_string(filename, lock_info->locks[i].file, filename_size);
00663    *lineno = lock_info->locks[i].line_num;
00664    ast_copy_string(func, lock_info->locks[i].func, func_size);
00665    ast_copy_string(mutex_name, lock_info->locks[i].lock_name, mutex_name_size);
00666 
00667    pthread_mutex_unlock(&lock_info->lock);
00668 
00669    return 0;
00670 }
00671 
00672 #ifdef HAVE_BKTR
00673 void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt)
00674 #else
00675 void ast_remove_lock_info(void *lock_addr)
00676 #endif
00677 {
00678    struct thr_lock_info *lock_info;
00679    int i = 0;
00680 
00681    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00682       return;
00683 
00684    pthread_mutex_lock(&lock_info->lock);
00685 
00686    for (i = lock_info->num_locks - 1; i >= 0; i--) {
00687       if (lock_info->locks[i].lock_addr == lock_addr)
00688          break;
00689    }
00690 
00691    if (i == -1) {
00692       /* Lock not found :( */
00693       pthread_mutex_unlock(&lock_info->lock);
00694       return;
00695    }
00696 
00697    if (lock_info->locks[i].times_locked > 1) {
00698       lock_info->locks[i].times_locked--;
00699 #ifdef HAVE_BKTR
00700       lock_info->locks[i].backtrace = bt;
00701 #endif
00702       pthread_mutex_unlock(&lock_info->lock);
00703       return;
00704    }
00705 
00706    if (i < lock_info->num_locks - 1) {
00707       /* Not the last one ... *should* be rare! */
00708       memmove(&lock_info->locks[i], &lock_info->locks[i + 1], 
00709          (lock_info->num_locks - (i + 1)) * sizeof(lock_info->locks[0]));
00710    }
00711 
00712    lock_info->num_locks--;
00713 
00714    pthread_mutex_unlock(&lock_info->lock);
00715 }
00716 
00717 static const char *locktype2str(enum ast_lock_type type)
00718 {
00719    switch (type) {
00720    case AST_MUTEX:
00721       return "MUTEX";
00722    case AST_RDLOCK:
00723       return "RDLOCK";
00724    case AST_WRLOCK:
00725       return "WRLOCK";
00726    }
00727 
00728    return "UNKNOWN";
00729 }
00730 
00731 #ifdef HAVE_BKTR
00732 static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt)
00733 {
00734    char **symbols;
00735 
00736    if (!bt) {
00737       ast_str_append(str, 0, "\tNo backtrace to print\n");
00738       return;
00739    }
00740 
00741    if ((symbols = ast_bt_get_symbols(bt->addresses, bt->num_frames))) {
00742       int frame_iterator;
00743       
00744       for (frame_iterator = 0; frame_iterator < bt->num_frames; ++frame_iterator) {
00745          ast_str_append(str, 0, "\t%s\n", symbols[frame_iterator]);
00746       }
00747 
00748       free(symbols);
00749    } else {
00750       ast_str_append(str, 0, "\tCouldn't retrieve backtrace symbols\n");
00751    }
00752 }
00753 #endif
00754 
00755 static void append_lock_information(struct ast_str **str, struct thr_lock_info *lock_info, int i)
00756 {
00757    int j;
00758    ast_mutex_t *lock;
00759    struct ast_lock_track *lt;
00760    
00761    ast_str_append(str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d)\n", 
00762                lock_info->locks[i].pending > 0 ? "Waiting for " : 
00763                lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
00764                lock_info->locks[i].file, 
00765                locktype2str(lock_info->locks[i].type),
00766                lock_info->locks[i].line_num,
00767                lock_info->locks[i].func, lock_info->locks[i].lock_name,
00768                lock_info->locks[i].lock_addr, 
00769                lock_info->locks[i].times_locked);
00770 #ifdef HAVE_BKTR
00771    append_backtrace_information(str, lock_info->locks[i].backtrace);
00772 #endif
00773    
00774    if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
00775       return;
00776    
00777    /* We only have further details for mutexes right now */
00778    if (lock_info->locks[i].type != AST_MUTEX)
00779       return;
00780    
00781    lock = lock_info->locks[i].lock_addr;
00782    lt = &lock->track;
00783    ast_reentrancy_lock(lt);
00784    for (j = 0; *str && j < lt->reentrancy; j++) {
00785       ast_str_append(str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n",
00786                   lt->file[j], lt->lineno[j], lt->func[j]);
00787    }
00788    ast_reentrancy_unlock(lt); 
00789 }
00790 
00791 
00792 /*! This function can help you find highly temporal locks; locks that happen for a 
00793     short time, but at unexpected times, usually at times that create a deadlock,
00794    Why is this thing locked right then? Who is locking it? Who am I fighting
00795     with for this lock? 
00796 
00797    To answer such questions, just call this routine before you would normally try
00798    to aquire a lock. It doesn't do anything if the lock is not acquired. If the
00799    lock is taken, it will publish a line or two to the console via ast_log().
00800 
00801    Sometimes, the lock message is pretty uninformative. For instance, you might
00802    find that the lock is being aquired deep within the astobj2 code; this tells
00803    you little about higher level routines that call the astobj2 routines.
00804    But, using gdb, you can set a break at the ast_log below, and for that
00805    breakpoint, you can set the commands:
00806      where
00807      cont
00808    which will give a stack trace and continue. -- that aught to do the job!
00809 
00810 */
00811 void log_show_lock(void *this_lock_addr)
00812 {
00813    struct thr_lock_info *lock_info;
00814    struct ast_str *str;
00815 
00816    if (!(str = ast_str_create(4096))) {
00817       ast_log(LOG_NOTICE,"Could not create str\n");
00818       return;
00819    }
00820    
00821 
00822    pthread_mutex_lock(&lock_infos_lock.mutex);
00823    AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
00824       int i;
00825       pthread_mutex_lock(&lock_info->lock);
00826       for (i = 0; str && i < lock_info->num_locks; i++) {
00827          /* ONLY show info about this particular lock, if
00828             it's acquired... */
00829          if (lock_info->locks[i].lock_addr == this_lock_addr) {
00830             append_lock_information(&str, lock_info, i);
00831             ast_log(LOG_NOTICE, "%s", ast_str_buffer(str));
00832             break;
00833          }
00834       }
00835       pthread_mutex_unlock(&lock_info->lock);
00836    }
00837    pthread_mutex_unlock(&lock_infos_lock.mutex);
00838    ast_free(str);
00839 }
00840 
00841 
00842 static char *handle_show_locks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
00843 {
00844    struct thr_lock_info *lock_info;
00845    struct ast_str *str;
00846 
00847    if (!(str = ast_str_create(4096)))
00848       return CLI_FAILURE;
00849 
00850    switch (cmd) {
00851    case CLI_INIT:
00852       e->command = "core show locks";
00853       e->usage =
00854          "Usage: core show locks\n"
00855          "       This command is for lock debugging.  It prints out which locks\n"
00856          "are owned by each active thread.\n";
00857       return NULL;
00858 
00859    case CLI_GENERATE:
00860       return NULL;
00861    }
00862 
00863    ast_str_append(&str, 0, "\n" 
00864                   "=======================================================================\n"
00865                   "=== Currently Held Locks ==============================================\n"
00866                   "=======================================================================\n"
00867                   "===\n"
00868                   "=== <pending> <lock#> (<file>): <lock type> <line num> <function> <lock name> <lock addr> (times locked)\n"
00869                   "===\n");
00870 
00871    if (!str)
00872       return CLI_FAILURE;
00873 
00874    pthread_mutex_lock(&lock_infos_lock.mutex);
00875    AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
00876       int i;
00877       if (lock_info->num_locks) {
00878          ast_str_append(&str, 0, "=== Thread ID: %ld (%s)\n", (long) lock_info->thread_id,
00879             lock_info->thread_name);
00880          pthread_mutex_lock(&lock_info->lock);
00881          for (i = 0; str && i < lock_info->num_locks; i++) {
00882             append_lock_information(&str, lock_info, i);
00883          }
00884          pthread_mutex_unlock(&lock_info->lock);
00885          if (!str)
00886             break;
00887          ast_str_append(&str, 0, "=== -------------------------------------------------------------------\n"
00888                         "===\n");
00889          if (!str)
00890             break;
00891       }
00892    }
00893    pthread_mutex_unlock(&lock_infos_lock.mutex);
00894 
00895    if (!str)
00896       return CLI_FAILURE;
00897 
00898    ast_str_append(&str, 0, "=======================================================================\n"
00899                   "\n");
00900 
00901    if (!str)
00902       return CLI_FAILURE;
00903 
00904    ast_cli(a->fd, "%s", ast_str_buffer(str));
00905 
00906    ast_free(str);
00907 
00908    return CLI_SUCCESS;
00909 }
00910 
00911 static struct ast_cli_entry utils_cli[] = {
00912    AST_CLI_DEFINE(handle_show_locks, "Show which locks are held by which thread"),
00913 };
00914 
00915 #endif /* DEBUG_THREADS */
00916 
00917 /*
00918  * support for 'show threads'. The start routine is wrapped by
00919  * dummy_start(), so that ast_register_thread() and
00920  * ast_unregister_thread() know the thread identifier.
00921  */
00922 struct thr_arg {
00923    void *(*start_routine)(void *);
00924    void *data;
00925    char *name;
00926 };
00927 
00928 /*
00929  * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
00930  * are odd macros which start and end a block, so they _must_ be
00931  * used in pairs (the latter with a '1' argument to call the
00932  * handler on exit.
00933  * On BSD we don't need this, but we keep it for compatibility.
00934  */
00935 static void *dummy_start(void *data)
00936 {
00937    void *ret;
00938    struct thr_arg a = *((struct thr_arg *) data);  /* make a local copy */
00939 #ifdef DEBUG_THREADS
00940    struct thr_lock_info *lock_info;
00941    pthread_mutexattr_t mutex_attr;
00942 #endif
00943 
00944    /* note that even though data->name is a pointer to allocated memory,
00945       we are not freeing it here because ast_register_thread is going to
00946       keep a copy of the pointer and then ast_unregister_thread will
00947       free the memory
00948    */
00949    ast_free(data);
00950    ast_register_thread(a.name);
00951    pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());
00952 
00953 #ifdef DEBUG_THREADS
00954    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00955       return NULL;
00956 
00957    lock_info->thread_id = pthread_self();
00958    lock_info->thread_name = strdup(a.name);
00959 
00960    pthread_mutexattr_init(&mutex_attr);
00961    pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND);
00962    pthread_mutex_init(&lock_info->lock, &mutex_attr);
00963    pthread_mutexattr_destroy(&mutex_attr);
00964 
00965    pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
00966    AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry);
00967    pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
00968 #endif /* DEBUG_THREADS */
00969 
00970    ret = a.start_routine(a.data);
00971 
00972    pthread_cleanup_pop(1);
00973 
00974    return ret;
00975 }
00976 
00977 #endif /* !LOW_MEMORY */
00978 
00979 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
00980               void *data, size_t stacksize, const char *file, const char *caller,
00981               int line, const char *start_fn)
00982 {
00983 #if !defined(LOW_MEMORY)
00984    struct thr_arg *a;
00985 #endif
00986 
00987    if (!attr) {
00988       attr = alloca(sizeof(*attr));
00989       pthread_attr_init(attr);
00990    }
00991 
00992 #ifdef __linux__
00993    /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
00994       which is kind of useless. Change this here to
00995       PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
00996       priority will propagate down to new threads by default.
00997       This does mean that callers cannot set a different priority using
00998       PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
00999       the priority afterwards with pthread_setschedparam(). */
01000    if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
01001       ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
01002 #endif
01003 
01004    if (!stacksize)
01005       stacksize = AST_STACKSIZE;
01006 
01007    if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
01008       ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));
01009 
01010 #if !defined(LOW_MEMORY)
01011    if ((a = ast_malloc(sizeof(*a)))) {
01012       a->start_routine = start_routine;
01013       a->data = data;
01014       start_routine = dummy_start;
01015       if (asprintf(&a->name, "%-20s started at [%5d] %s %s()",
01016               start_fn, line, file, caller) < 0) {
01017          ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
01018          a->name = NULL;
01019       }
01020       data = a;
01021    }
01022 #endif /* !LOW_MEMORY */
01023 
01024    return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
01025 }
01026 
01027 
01028 int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
01029               void *data, size_t stacksize, const char *file, const char *caller,
01030               int line, const char *start_fn)
01031 {
01032    unsigned char attr_destroy = 0;
01033    int res;
01034 
01035    if (!attr) {
01036       attr = alloca(sizeof(*attr));
01037       pthread_attr_init(attr);
01038       attr_destroy = 1;
01039    }
01040 
01041    if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
01042       ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno));
01043 
01044    res = ast_pthread_create_stack(thread, attr, start_routine, data, 
01045                                   stacksize, file, caller, line, start_fn);
01046 
01047    if (attr_destroy)
01048       pthread_attr_destroy(attr);
01049 
01050    return res;
01051 }
01052 
01053 int ast_wait_for_input(int fd, int ms)
01054 {
01055    struct pollfd pfd[1];
01056    memset(pfd, 0, sizeof(pfd));
01057    pfd[0].fd = fd;
01058    pfd[0].events = POLLIN|POLLPRI;
01059    return ast_poll(pfd, 1, ms);
01060 }
01061 
01062 static int ast_wait_for_output(int fd, int timeoutms)
01063 {
01064    struct pollfd pfd = {
01065       .fd = fd,
01066       .events = POLLOUT,
01067    };
01068    int res;
01069    struct timeval start = ast_tvnow();
01070    int elapsed = 0;
01071 
01072    /* poll() until the fd is writable without blocking */
01073    while ((res = ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
01074       if (res == 0) {
01075          /* timed out. */
01076 #ifndef STANDALONE
01077          ast_debug(1, "Timed out trying to write\n");
01078 #endif
01079          return -1;
01080       } else if (res == -1) {
01081          /* poll() returned an error, check to see if it was fatal */
01082 
01083          if (errno == EINTR || errno == EAGAIN) {
01084             elapsed = ast_tvdiff_ms(ast_tvnow(), start);
01085             if (elapsed >= timeoutms) {
01086                return -1;
01087             }
01088             /* This was an acceptable error, go back into poll() */
01089             continue;
01090          }
01091 
01092          /* Fatal error, bail. */
01093          ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno));
01094 
01095          return -1;
01096       }
01097       elapsed = ast_tvdiff_ms(ast_tvnow(), start);
01098       if (elapsed >= timeoutms) {
01099          return -1;
01100       }
01101    }
01102 
01103    return 0;
01104 }
01105 
01106 /*!
01107  * Try to write string, but wait no more than ms milliseconds before timing out.
01108  *
01109  * \note The code assumes that the file descriptor has NONBLOCK set,
01110  * so there is only one system call made to do a write, unless we actually
01111  * have a need to wait.  This way, we get better performance.
01112  * If the descriptor is blocking, all assumptions on the guaranteed
01113  * detail do not apply anymore.
01114  */
01115 int ast_carefulwrite(int fd, char *s, int len, int timeoutms) 
01116 {
01117    struct timeval start = ast_tvnow();
01118    int res = 0;
01119    int elapsed = 0;
01120 
01121    while (len) {
01122       if (ast_wait_for_output(fd, timeoutms - elapsed)) {
01123          return -1;
01124       }
01125 
01126       res = write(fd, s, len);
01127 
01128       if (res < 0 && errno != EAGAIN && errno != EINTR) {
01129          /* fatal error from write() */
01130          ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
01131          return -1;
01132       }
01133 
01134       if (res < 0) {
01135          /* It was an acceptable error */
01136          res = 0;
01137       }
01138 
01139       /* Update how much data we have left to write */
01140       len -= res;
01141       s += res;
01142       res = 0;
01143 
01144       elapsed = ast_tvdiff_ms(ast_tvnow(), start);
01145       if (elapsed >= timeoutms) {
01146          /* We've taken too long to write 
01147           * This is only an error condition if we haven't finished writing. */
01148          res = len ? -1 : 0;
01149          break;
01150       }
01151    }
01152 
01153    return res;
01154 }
01155 
01156 int ast_careful_fwrite(FILE *f, int fd, const char *src, size_t len, int timeoutms)
01157 {
01158    struct timeval start = ast_tvnow();
01159    int n = 0;
01160    int elapsed = 0;
01161 
01162    while (len) {
01163       if (ast_wait_for_output(fd, timeoutms - elapsed)) {
01164          /* poll returned a fatal error, so bail out immediately. */
01165          return -1;
01166       }
01167 
01168       /* Clear any errors from a previous write */
01169       clearerr(f);
01170 
01171       n = fwrite(src, 1, len, f);
01172 
01173       if (ferror(f) && errno != EINTR && errno != EAGAIN) {
01174          /* fatal error from fwrite() */
01175          if (!feof(f)) {
01176             /* Don't spam the logs if it was just that the connection is closed. */
01177             ast_log(LOG_ERROR, "fwrite() returned error: %s\n", strerror(errno));
01178          }
01179          n = -1;
01180          break;
01181       }
01182 
01183       /* Update for data already written to the socket */
01184       len -= n;
01185       src += n;
01186 
01187       elapsed = ast_tvdiff_ms(ast_tvnow(), start);
01188       if (elapsed >= timeoutms) {
01189          /* We've taken too long to write 
01190           * This is only an error condition if we haven't finished writing. */
01191          n = len ? -1 : 0;
01192          break;
01193       }
01194    }
01195 
01196    while (fflush(f)) {
01197       if (errno == EAGAIN || errno == EINTR) {
01198          continue;
01199       }
01200       if (!feof(f)) {
01201          /* Don't spam the logs if it was just that the connection is closed. */
01202          ast_log(LOG_ERROR, "fflush() returned error: %s\n", strerror(errno));
01203       }
01204       n = -1;
01205       break;
01206    }
01207 
01208    return n < 0 ? -1 : 0;
01209 }
01210 
01211 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
01212 {
01213    char *e;
01214    char *q;
01215 
01216    s = ast_strip(s);
01217    if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
01218       e = s + strlen(s) - 1;
01219       if (*e == *(end_quotes + (q - beg_quotes))) {
01220          s++;
01221          *e = '\0';
01222       }
01223    }
01224 
01225    return s;
01226 }
01227 
01228 char *ast_unescape_semicolon(char *s)
01229 {
01230    char *e;
01231    char *work = s;
01232 
01233    while ((e = strchr(work, ';'))) {
01234       if ((e > work) && (*(e-1) == '\\')) {
01235          memmove(e - 1, e, strlen(e) + 1);
01236          work = e;
01237       } else {
01238          work = e + 1;
01239       }
01240    }
01241 
01242    return s;
01243 }
01244 
01245 /* !\brief unescape some C sequences in place, return pointer to the original string.
01246  */
01247 char *ast_unescape_c(char *src)
01248 {
01249    char c, *ret, *dst;
01250 
01251    if (src == NULL)
01252       return NULL;
01253    for (ret = dst = src; (c = *src++); *dst++ = c ) {
01254       if (c != '\\')
01255          continue;   /* copy char at the end of the loop */
01256       switch ((c = *src++)) {
01257       case '\0':  /* special, trailing '\' */
01258          c = '\\';
01259          break;
01260       case 'b':   /* backspace */
01261          c = '\b';
01262          break;
01263       case 'f':   /* form feed */
01264          c = '\f';
01265          break;
01266       case 'n':
01267          c = '\n';
01268          break;
01269       case 'r':
01270          c = '\r';
01271          break;
01272       case 't':
01273          c = '\t';
01274          break;
01275       }
01276       /* default, use the char literally */
01277    }
01278    *dst = '\0';
01279    return ret;
01280 }
01281 
01282 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
01283 {
01284    int result;
01285 
01286    if (!buffer || !*buffer || !space || !*space)
01287       return -1;
01288 
01289    result = vsnprintf(*buffer, *space, fmt, ap);
01290 
01291    if (result < 0)
01292       return -1;
01293    else if (result > *space)
01294       result = *space;
01295 
01296    *buffer += result;
01297    *space -= result;
01298    return 0;
01299 }
01300 
01301 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
01302 {
01303    va_list ap;
01304    int result;
01305 
01306    va_start(ap, fmt);
01307    result = ast_build_string_va(buffer, space, fmt, ap);
01308    va_end(ap);
01309 
01310    return result;
01311 }
01312 
01313 int ast_true(const char *s)
01314 {
01315    if (ast_strlen_zero(s))
01316       return 0;
01317 
01318    /* Determine if this is a true value */
01319    if (!strcasecmp(s, "yes") ||
01320        !strcasecmp(s, "true") ||
01321        !strcasecmp(s, "y") ||
01322        !strcasecmp(s, "t") ||
01323        !strcasecmp(s, "1") ||
01324        !strcasecmp(s, "on"))
01325       return -1;
01326 
01327    return 0;
01328 }
01329 
01330 int ast_false(const char *s)
01331 {
01332    if (ast_strlen_zero(s))
01333       return 0;
01334 
01335    /* Determine if this is a false value */
01336    if (!strcasecmp(s, "no") ||
01337        !strcasecmp(s, "false") ||
01338        !strcasecmp(s, "n") ||
01339        !strcasecmp(s, "f") ||
01340        !strcasecmp(s, "0") ||
01341        !strcasecmp(s, "off"))
01342       return -1;
01343 
01344    return 0;
01345 }
01346 
01347 #define ONE_MILLION  1000000
01348 /*
01349  * put timeval in a valid range. usec is 0..999999
01350  * negative values are not allowed and truncated.
01351  */
01352 static struct timeval tvfix(struct timeval a)
01353 {
01354    if (a.tv_usec >= ONE_MILLION) {
01355       ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
01356          (long)a.tv_sec, (long int) a.tv_usec);
01357       a.tv_sec += a.tv_usec / ONE_MILLION;
01358       a.tv_usec %= ONE_MILLION;
01359    } else if (a.tv_usec < 0) {
01360       ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
01361          (long)a.tv_sec, (long int) a.tv_usec);
01362       a.tv_usec = 0;
01363    }
01364    return a;
01365 }
01366 
01367 struct timeval ast_tvadd(struct timeval a, struct timeval b)
01368 {
01369    /* consistency checks to guarantee usec in 0..999999 */
01370    a = tvfix(a);
01371    b = tvfix(b);
01372    a.tv_sec += b.tv_sec;
01373    a.tv_usec += b.tv_usec;
01374    if (a.tv_usec >= ONE_MILLION) {
01375       a.tv_sec++;
01376       a.tv_usec -= ONE_MILLION;
01377    }
01378    return a;
01379 }
01380 
01381 struct timeval ast_tvsub(struct timeval a, struct timeval b)
01382 {
01383    /* consistency checks to guarantee usec in 0..999999 */
01384    a = tvfix(a);
01385    b = tvfix(b);
01386    a.tv_sec -= b.tv_sec;
01387    a.tv_usec -= b.tv_usec;
01388    if (a.tv_usec < 0) {
01389       a.tv_sec-- ;
01390       a.tv_usec += ONE_MILLION;
01391    }
01392    return a;
01393 }
01394 #undef ONE_MILLION
01395 
01396 /*! \brief glibc puts a lock inside random(3), so that the results are thread-safe.
01397  * BSD libc (and others) do not. */
01398 
01399 #ifndef linux
01400 AST_MUTEX_DEFINE_STATIC(randomlock);
01401 #endif
01402 
01403 long int ast_random(void)
01404 {
01405    long int res;
01406 #ifdef HAVE_DEV_URANDOM
01407    if (dev_urandom_fd >= 0) {
01408       int read_res = read(dev_urandom_fd, &res, sizeof(res));
01409       if (read_res > 0) {
01410          long int rm = RAND_MAX;
01411          res = res < 0 ? ~res : res;
01412          rm++;
01413          return res % rm;
01414       }
01415    }
01416 #endif
01417 #ifdef linux
01418    res = random();
01419 #else
01420    ast_mutex_lock(&randomlock);
01421    res = random();
01422    ast_mutex_unlock(&randomlock);
01423 #endif
01424    return res;
01425 }
01426 
01427 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
01428 {
01429    char *dataPut = start;
01430    int inEscape = 0;
01431    int inQuotes = 0;
01432 
01433    for (; *start; start++) {
01434       if (inEscape) {
01435          *dataPut++ = *start;       /* Always goes verbatim */
01436          inEscape = 0;
01437       } else {
01438          if (*start == '\\') {
01439             inEscape = 1;      /* Do not copy \ into the data */
01440          } else if (*start == '\'') {
01441             inQuotes = 1 - inQuotes;   /* Do not copy ' into the data */
01442          } else {
01443             /* Replace , with |, unless in quotes */
01444             *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
01445          }
01446       }
01447    }
01448    if (start != dataPut)
01449       *dataPut = 0;
01450    return dataPut;
01451 }
01452 
01453 void ast_join(char *s, size_t len, char * const w[])
01454 {
01455    int x, ofs = 0;
01456    const char *src;
01457 
01458    /* Join words into a string */
01459    if (!s)
01460       return;
01461    for (x = 0; ofs < len && w[x]; x++) {
01462       if (x > 0)
01463          s[ofs++] = ' ';
01464       for (src = w[x]; *src && ofs < len; src++)
01465          s[ofs++] = *src;
01466    }
01467    if (ofs == len)
01468       ofs--;
01469    s[ofs] = '\0';
01470 }
01471 
01472 /*
01473  * stringfields support routines.
01474  */
01475 
01476 const char __ast_string_field_empty[] = ""; /*!< the empty string */
01477 
01478 /*! \brief add a new block to the pool.
01479  * We can only allocate from the topmost pool, so the
01480  * fields in *mgr reflect the size of that only.
01481  */
01482 static int add_string_pool(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
01483             size_t size, const char *file, int lineno, const char *func)
01484 {
01485    struct ast_string_field_pool *pool;
01486 
01487 #if defined(__AST_DEBUG_MALLOC)
01488    if (!(pool = __ast_calloc(1, sizeof(*pool) + size, file, lineno, func))) {
01489       return -1;
01490    }
01491 #else
01492    if (!(pool = ast_calloc(1, sizeof(*pool) + size))) {
01493       return -1;
01494    }
01495 #endif
01496 
01497    pool->prev = *pool_head;
01498    *pool_head = pool;
01499    mgr->size = size;
01500    mgr->used = 0;
01501    mgr->last_alloc = NULL;
01502 
01503    return 0;
01504 }
01505 
01506 /*
01507  * This is an internal API, code should not use it directly.
01508  * It initializes all fields as empty, then uses 'size' for 3 functions:
01509  * size > 0 means initialize the pool list with a pool of given size.
01510  * This must be called right after allocating the object.
01511  * size = 0 means release all pools except the most recent one.
01512  * This is useful to e.g. reset an object to the initial value.
01513  * size < 0 means release all pools.
01514  * This must be done before destroying the object.
01515  */
01516 int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
01517              int needed, const char *file, int lineno, const char *func)
01518 {
01519    const char **p = (const char **) pool_head + 1;
01520    struct ast_string_field_pool *cur = NULL;
01521    struct ast_string_field_pool *preserve = NULL;
01522 
01523    /* clear fields - this is always necessary */
01524    while ((struct ast_string_field_mgr *) p != mgr)
01525       *p++ = __ast_string_field_empty;
01526    mgr->last_alloc = NULL;
01527 #if defined(__AST_DEBUG_MALLOC)
01528    mgr->owner_file = file;
01529    mgr->owner_func = func;
01530    mgr->owner_line = lineno;
01531 #endif
01532    if (needed > 0) {    /* allocate the initial pool */
01533       *pool_head = NULL;
01534       return add_string_pool(mgr, pool_head, needed, file, lineno, func);
01535    }
01536    if (needed < 0) {    /* reset all pools */
01537       if (*pool_head == NULL) {
01538          ast_log(LOG_WARNING, "trying to reset empty pool\n");
01539          return -1;
01540       }
01541       cur = *pool_head;
01542    } else {       /* preserve the last pool */
01543       if (*pool_head == NULL) {
01544          ast_log(LOG_WARNING, "trying to reset empty pool\n");
01545          return -1;
01546       }
01547       mgr->used = 0;
01548       preserve = *pool_head;
01549       cur = preserve->prev;
01550    }
01551 
01552    if (preserve) {
01553       preserve->prev = NULL;
01554    }
01555 
01556    while (cur) {
01557       struct ast_string_field_pool *prev = cur->prev;
01558 
01559       if (cur != preserve) {
01560          ast_free(cur);
01561       }
01562       cur = prev;
01563    }
01564 
01565    *pool_head = preserve;
01566 
01567    return 0;
01568 }
01569 
01570 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr,
01571                   struct ast_string_field_pool **pool_head, size_t needed)
01572 {
01573    char *result = NULL;
01574    size_t space = mgr->size - mgr->used;
01575 
01576    if (__builtin_expect(needed > space, 0)) {
01577       size_t new_size = mgr->size * 2;
01578 
01579       while (new_size < needed)
01580          new_size *= 2;
01581 
01582 #if defined(__AST_DEBUG_MALLOC)
01583       if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
01584          return NULL;
01585 #else
01586       if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
01587          return NULL;
01588 #endif
01589    }
01590 
01591    result = (*pool_head)->base + mgr->used;
01592    mgr->used += needed;
01593    mgr->last_alloc = result;
01594    return result;
01595 }
01596 
01597 int __ast_string_field_ptr_grow(struct ast_string_field_mgr *mgr, size_t needed,
01598             const ast_string_field *ptr)
01599 {
01600    int grow = needed - (strlen(*ptr) + 1);
01601    size_t space = mgr->size - mgr->used;
01602 
01603    if (grow <= 0) {
01604       return 0;
01605    }
01606 
01607    if (*ptr != mgr->last_alloc) {
01608       return 1;
01609    }
01610 
01611    if (space < grow) {
01612       return 1;
01613    }
01614 
01615    mgr->used += grow;
01616 
01617    return 0;
01618 }
01619 
01620 void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
01621                  struct ast_string_field_pool **pool_head,
01622                  ast_string_field *ptr, const char *format, va_list ap1, va_list ap2)
01623 {
01624    size_t needed;
01625    size_t available;
01626    size_t space = mgr->size - mgr->used;
01627    char *target;
01628 
01629    /* if the field already has space allocated, try to reuse it;
01630       otherwise, use the empty space at the end of the current
01631       pool
01632    */
01633    if ((*ptr)[0] != '\0') {
01634       target = (char *) *ptr;
01635       available = strlen(target) + 1;
01636    } else {
01637       target = (*pool_head)->base + mgr->used;
01638       available = space;
01639    }
01640 
01641    needed = vsnprintf(target, available, format, ap1) + 1;
01642 
01643    va_end(ap1);
01644 
01645    if (needed > available) {
01646       /* if the space needed can be satisfied by using the current
01647          pool (which could only occur if we tried to use the field's
01648          allocated space and failed), then use that space; otherwise
01649          allocate a new pool
01650       */
01651       if (needed > space) {
01652          size_t new_size = mgr->size * 2;
01653 
01654          while (new_size < needed)
01655             new_size *= 2;
01656          
01657 #if defined(__AST_DEBUG_MALLOC)
01658          if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
01659             return;
01660 #else
01661          if (add_string_pool(mgr, pool_head, new_size, NULL, 0, NULL))
01662             return;
01663 #endif
01664       }
01665 
01666       target = (*pool_head)->base + mgr->used;
01667       vsprintf(target, format, ap2);
01668    }
01669 
01670    if (*ptr != target) {
01671       mgr->last_alloc = *ptr = target;
01672       mgr->used += needed;
01673    }
01674 }
01675 
01676 void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
01677               struct ast_string_field_pool **pool_head,
01678               ast_string_field *ptr, const char *format, ...)
01679 {
01680    va_list ap1, ap2;
01681 
01682    va_start(ap1, format);
01683    va_start(ap2, format);     /* va_copy does not exist on FreeBSD */
01684 
01685    __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2);
01686 
01687    va_end(ap1);
01688    va_end(ap2);
01689 }
01690 /* end of stringfields support */
01691 
01692 AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
01693 
01694 int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
01695 {
01696    int ret;
01697    ast_mutex_lock(&fetchadd_m);
01698    ret = *p;
01699    *p += v;
01700    ast_mutex_unlock(&fetchadd_m);
01701    return ret;
01702 }
01703 
01704 /*! \brief
01705  * get values from config variables.
01706  */
01707 int ast_get_timeval(const char *src, struct timeval *dst, struct timeval _default, int *consumed)
01708 {
01709    long double dtv = 0.0;
01710    int scanned;
01711 
01712    if (dst == NULL)
01713       return -1;
01714 
01715    *dst = _default;
01716 
01717    if (ast_strlen_zero(src))
01718       return -1;
01719 
01720    /* only integer at the moment, but one day we could accept more formats */
01721    if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) {
01722       dst->tv_sec = dtv;
01723       dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
01724       if (consumed)
01725          *consumed = scanned;
01726       return 0;
01727    } else
01728       return -1;
01729 }
01730 
01731 /*! \brief
01732  * get values from config variables.
01733  */
01734 int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
01735 {
01736    long t;
01737    int scanned;
01738 
01739    if (dst == NULL)
01740       return -1;
01741 
01742    *dst = _default;
01743 
01744    if (ast_strlen_zero(src))
01745       return -1;
01746 
01747    /* only integer at the moment, but one day we could accept more formats */
01748    if (sscanf(src, "%30ld%n", &t, &scanned) == 1) {
01749       *dst = t;
01750       if (consumed)
01751          *consumed = scanned;
01752       return 0;
01753    } else
01754       return -1;
01755 }
01756 
01757 void ast_enable_packet_fragmentation(int sock)
01758 {
01759 #if defined(HAVE_IP_MTU_DISCOVER)
01760    int val = IP_PMTUDISC_DONT;
01761    
01762    if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
01763       ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
01764 #endif /* HAVE_IP_MTU_DISCOVER */
01765 }
01766 
01767 int ast_mkdir(const char *path, int mode)
01768 {
01769    char *ptr;
01770    int len = strlen(path), count = 0, x, piececount = 0;
01771    char *tmp = ast_strdupa(path);
01772    char **pieces;
01773    char *fullpath = alloca(len + 1);
01774    int res = 0;
01775 
01776    for (ptr = tmp; *ptr; ptr++) {
01777       if (*ptr == '/')
01778          count++;
01779    }
01780 
01781    /* Count the components to the directory path */
01782    pieces = alloca(count * sizeof(*pieces));
01783    for (ptr = tmp; *ptr; ptr++) {
01784       if (*ptr == '/') {
01785          *ptr = '\0';
01786          pieces[piececount++] = ptr + 1;
01787       }
01788    }
01789 
01790    *fullpath = '\0';
01791    for (x = 0; x < piececount; x++) {
01792       /* This looks funky, but the buffer is always ideally-sized, so it's fine. */
01793       strcat(fullpath, "/");
01794       strcat(fullpath, pieces[x]);
01795       res = mkdir(fullpath, mode);
01796       if (res && errno != EEXIST)
01797          return errno;
01798    }
01799    return 0;
01800 }
01801 
01802 int ast_utils_init(void)
01803 {
01804 #ifdef HAVE_DEV_URANDOM
01805    dev_urandom_fd = open("/dev/urandom", O_RDONLY);
01806 #endif
01807    base64_init();
01808 #ifdef DEBUG_THREADS
01809 #if !defined(LOW_MEMORY)
01810    ast_cli_register_multiple(utils_cli, ARRAY_LEN(utils_cli));
01811 #endif
01812 #endif
01813    return 0;
01814 }
01815 
01816 #ifndef __AST_DEBUG_MALLOC
01817 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...)
01818 {
01819    int res;
01820    va_list ap;
01821 
01822    va_start(ap, fmt);
01823    if ((res = vasprintf(ret, fmt, ap)) == -1) {
01824       MALLOC_FAILURE_MSG;
01825    }
01826    va_end(ap);
01827 
01828    return res;
01829 }
01830 #endif
01831 
01832 char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size)
01833 {
01834    const char *envPATH = getenv("PATH");
01835    char *tpath, *path;
01836    struct stat unused;
01837    if (!envPATH) {
01838       return NULL;
01839    }
01840    tpath = ast_strdupa(envPATH);
01841    while ((path = strsep(&tpath, ":"))) {
01842       snprintf(fullpath, fullpath_size, "%s/%s", path, binary);
01843       if (!stat(fullpath, &unused)) {
01844          return fullpath;
01845       }
01846    }
01847    return NULL;
01848 }
01849