Sat Apr 26 2014 22:01:42

Asterisk developer's documentation


main/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 /*** MODULEINFO
00027    <support_level>core</support_level>
00028  ***/
00029 
00030 #include "asterisk.h"
00031 
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 401830 $")
00033 
00034 #include <ctype.h>
00035 #include <sys/stat.h>
00036 #include <sys/stat.h>
00037 
00038 #ifdef HAVE_DEV_URANDOM
00039 #include <fcntl.h>
00040 #endif
00041 
00042 #include <sys/syscall.h>
00043 #if defined(__APPLE__)
00044 #include <mach/mach.h>
00045 #elif defined(HAVE_SYS_THR_H)
00046 #include <sys/thr.h>
00047 #endif
00048 
00049 #include "asterisk/network.h"
00050 #include "asterisk/ast_version.h"
00051 
00052 #define AST_API_MODULE     /* ensure that inlinable API functions will be built in lock.h if required */
00053 #include "asterisk/lock.h"
00054 #include "asterisk/io.h"
00055 #include "asterisk/md5.h"
00056 #include "asterisk/sha1.h"
00057 #include "asterisk/cli.h"
00058 #include "asterisk/linkedlists.h"
00059 
00060 #define AST_API_MODULE     /* ensure that inlinable API functions will be built in this module if required */
00061 #include "asterisk/strings.h"
00062 
00063 #define AST_API_MODULE     /* ensure that inlinable API functions will be built in this module if required */
00064 #include "asterisk/time.h"
00065 
00066 #define AST_API_MODULE     /* ensure that inlinable API functions will be built in this module if required */
00067 #include "asterisk/stringfields.h"
00068 
00069 #define AST_API_MODULE     /* ensure that inlinable API functions will be built in this module if required */
00070 #include "asterisk/utils.h"
00071 
00072 #define AST_API_MODULE
00073 #include "asterisk/threadstorage.h"
00074 
00075 #define AST_API_MODULE
00076 #include "asterisk/config.h"
00077 
00078 static char base64[64];
00079 static char b2a[256];
00080 
00081 AST_THREADSTORAGE(inet_ntoa_buf);
00082 
00083 #if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6)
00084 
00085 #define ERANGE 34 /*!< duh? ERANGE value copied from web... */
00086 #undef gethostbyname
00087 
00088 AST_MUTEX_DEFINE_STATIC(__mutex);
00089 
00090 /*! \brief Reentrant replacement for gethostbyname for BSD-based systems.
00091 \note This
00092 routine is derived from code originally written and placed in the public
00093 domain by Enzo Michelangeli <em@em.no-ip.com> */
00094 
00095 static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
00096             size_t buflen, struct hostent **result,
00097             int *h_errnop)
00098 {
00099    int hsave;
00100    struct hostent *ph;
00101    ast_mutex_lock(&__mutex); /* begin critical area */
00102    hsave = h_errno;
00103 
00104    ph = gethostbyname(name);
00105    *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
00106    if (ph == NULL) {
00107       *result = NULL;
00108    } else {
00109       char **p, **q;
00110       char *pbuf;
00111       int nbytes = 0;
00112       int naddr = 0, naliases = 0;
00113       /* determine if we have enough space in buf */
00114 
00115       /* count how many addresses */
00116       for (p = ph->h_addr_list; *p != 0; p++) {
00117          nbytes += ph->h_length; /* addresses */
00118          nbytes += sizeof(*p); /* pointers */
00119          naddr++;
00120       }
00121       nbytes += sizeof(*p); /* one more for the terminating NULL */
00122 
00123       /* count how many aliases, and total length of strings */
00124       for (p = ph->h_aliases; *p != 0; p++) {
00125          nbytes += (strlen(*p)+1); /* aliases */
00126          nbytes += sizeof(*p);  /* pointers */
00127          naliases++;
00128       }
00129       nbytes += sizeof(*p); /* one more for the terminating NULL */
00130 
00131       /* here nbytes is the number of bytes required in buffer */
00132       /* as a terminator must be there, the minimum value is ph->h_length */
00133       if (nbytes > buflen) {
00134          *result = NULL;
00135          ast_mutex_unlock(&__mutex); /* end critical area */
00136          return ERANGE; /* not enough space in buf!! */
00137       }
00138 
00139       /* There is enough space. Now we need to do a deep copy! */
00140       /* Allocation in buffer:
00141          from [0] to [(naddr-1) * sizeof(*p)]:
00142          pointers to addresses
00143          at [naddr * sizeof(*p)]:
00144          NULL
00145          from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
00146          pointers to aliases
00147          at [(naddr+naliases+1) * sizeof(*p)]:
00148          NULL
00149          then naddr addresses (fixed length), and naliases aliases (asciiz).
00150       */
00151 
00152       *ret = *ph;   /* copy whole structure (not its address!) */
00153 
00154       /* copy addresses */
00155       q = (char **)buf; /* pointer to pointers area (type: char **) */
00156       ret->h_addr_list = q; /* update pointer to address list */
00157       pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
00158       for (p = ph->h_addr_list; *p != 0; p++) {
00159          memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
00160          *q++ = pbuf; /* the pointer is the one inside buf... */
00161          pbuf += ph->h_length; /* advance pbuf */
00162       }
00163       *q++ = NULL; /* address list terminator */
00164 
00165       /* copy aliases */
00166       ret->h_aliases = q; /* update pointer to aliases list */
00167       for (p = ph->h_aliases; *p != 0; p++) {
00168          strcpy(pbuf, *p); /* copy alias strings */
00169          *q++ = pbuf; /* the pointer is the one inside buf... */
00170          pbuf += strlen(*p); /* advance pbuf */
00171          *pbuf++ = 0; /* string terminator */
00172       }
00173       *q++ = NULL; /* terminator */
00174 
00175       strcpy(pbuf, ph->h_name); /* copy alias strings */
00176       ret->h_name = pbuf;
00177       pbuf += strlen(ph->h_name); /* advance pbuf */
00178       *pbuf++ = 0; /* string terminator */
00179 
00180       *result = ret;  /* and let *result point to structure */
00181 
00182    }
00183    h_errno = hsave;  /* restore h_errno */
00184    ast_mutex_unlock(&__mutex); /* end critical area */
00185 
00186    return (*result == NULL); /* return 0 on success, non-zero on error */
00187 }
00188 
00189 
00190 #endif
00191 
00192 /*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the
00193    standard gethostbyname (which is not thread safe)
00194 */
00195 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
00196 {
00197    int res;
00198    int herrno;
00199    int dots = 0;
00200    const char *s;
00201    struct hostent *result = NULL;
00202    /* Although it is perfectly legitimate to lookup a pure integer, for
00203       the sake of the sanity of people who like to name their peers as
00204       integers, we break with tradition and refuse to look up a
00205       pure integer */
00206    s = host;
00207    res = 0;
00208    while (s && *s) {
00209       if (*s == '.')
00210          dots++;
00211       else if (!isdigit(*s))
00212          break;
00213       s++;
00214    }
00215    if (!s || !*s) {
00216       /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
00217       if (dots != 3)
00218          return NULL;
00219       memset(hp, 0, sizeof(struct ast_hostent));
00220       hp->hp.h_addrtype = AF_INET;
00221       hp->hp.h_addr_list = (void *) hp->buf;
00222       hp->hp.h_addr = hp->buf + sizeof(void *);
00223       /* For AF_INET, this will always be 4 */
00224       hp->hp.h_length = 4;
00225       if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
00226          return &hp->hp;
00227       return NULL;
00228 
00229    }
00230 #ifdef HAVE_GETHOSTBYNAME_R_5
00231    result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
00232 
00233    if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
00234       return NULL;
00235 #else
00236    res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
00237 
00238    if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
00239       return NULL;
00240 #endif
00241    return &hp->hp;
00242 }
00243 
00244 /*! \brief Produce 32 char MD5 hash of value. */
00245 void ast_md5_hash(char *output, const char *input)
00246 {
00247    struct MD5Context md5;
00248    unsigned char digest[16];
00249    char *ptr;
00250    int x;
00251 
00252    MD5Init(&md5);
00253    MD5Update(&md5, (const unsigned char *) input, strlen(input));
00254    MD5Final(digest, &md5);
00255    ptr = output;
00256    for (x = 0; x < 16; x++)
00257       ptr += sprintf(ptr, "%2.2x", digest[x]);
00258 }
00259 
00260 /*! \brief Produce 40 char SHA1 hash of value. */
00261 void ast_sha1_hash(char *output, const char *input)
00262 {
00263    struct SHA1Context sha;
00264    char *ptr;
00265    int x;
00266    uint8_t Message_Digest[20];
00267 
00268    SHA1Reset(&sha);
00269 
00270    SHA1Input(&sha, (const unsigned char *) input, strlen(input));
00271 
00272    SHA1Result(&sha, Message_Digest);
00273    ptr = output;
00274    for (x = 0; x < 20; x++)
00275       ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
00276 }
00277 
00278 /*! \brief Produce a 20 byte SHA1 hash of value. */
00279 void ast_sha1_hash_uint(uint8_t *digest, const char *input)
00280 {
00281         struct SHA1Context sha;
00282 
00283         SHA1Reset(&sha);
00284 
00285         SHA1Input(&sha, (const unsigned char *) input, strlen(input));
00286 
00287         SHA1Result(&sha, digest);
00288 }
00289 
00290 /*! \brief decode BASE64 encoded text */
00291 int ast_base64decode(unsigned char *dst, const char *src, int max)
00292 {
00293    int cnt = 0;
00294    unsigned int byte = 0;
00295    unsigned int bits = 0;
00296    int incnt = 0;
00297    while(*src && *src != '=' && (cnt < max)) {
00298       /* Shift in 6 bits of input */
00299       byte <<= 6;
00300       byte |= (b2a[(int)(*src)]) & 0x3f;
00301       bits += 6;
00302       src++;
00303       incnt++;
00304       /* If we have at least 8 bits left over, take that character
00305          off the top */
00306       if (bits >= 8)  {
00307          bits -= 8;
00308          *dst = (byte >> bits) & 0xff;
00309          dst++;
00310          cnt++;
00311       }
00312    }
00313    /* Don't worry about left over bits, they're extra anyway */
00314    return cnt;
00315 }
00316 
00317 /*! \brief encode text to BASE64 coding */
00318 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
00319 {
00320    int cnt = 0;
00321    int col = 0;
00322    unsigned int byte = 0;
00323    int bits = 0;
00324    int cntin = 0;
00325    /* Reserve space for null byte at end of string */
00326    max--;
00327    while ((cntin < srclen) && (cnt < max)) {
00328       byte <<= 8;
00329       byte |= *(src++);
00330       bits += 8;
00331       cntin++;
00332       if ((bits == 24) && (cnt + 4 <= max)) {
00333          *dst++ = base64[(byte >> 18) & 0x3f];
00334          *dst++ = base64[(byte >> 12) & 0x3f];
00335          *dst++ = base64[(byte >> 6) & 0x3f];
00336          *dst++ = base64[byte & 0x3f];
00337          cnt += 4;
00338          col += 4;
00339          bits = 0;
00340          byte = 0;
00341       }
00342       if (linebreaks && (cnt < max) && (col == 64)) {
00343          *dst++ = '\n';
00344          cnt++;
00345          col = 0;
00346       }
00347    }
00348    if (bits && (cnt + 4 <= max)) {
00349       /* Add one last character for the remaining bits,
00350          padding the rest with 0 */
00351       byte <<= 24 - bits;
00352       *dst++ = base64[(byte >> 18) & 0x3f];
00353       *dst++ = base64[(byte >> 12) & 0x3f];
00354       if (bits == 16)
00355          *dst++ = base64[(byte >> 6) & 0x3f];
00356       else
00357          *dst++ = '=';
00358       *dst++ = '=';
00359       cnt += 4;
00360    }
00361    if (linebreaks && (cnt < max)) {
00362       *dst++ = '\n';
00363       cnt++;
00364    }
00365    *dst = '\0';
00366    return cnt;
00367 }
00368 
00369 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
00370 {
00371    return ast_base64encode_full(dst, src, srclen, max, 0);
00372 }
00373 
00374 static void base64_init(void)
00375 {
00376    int x;
00377    memset(b2a, -1, sizeof(b2a));
00378    /* Initialize base-64 Conversion table */
00379    for (x = 0; x < 26; x++) {
00380       /* A-Z */
00381       base64[x] = 'A' + x;
00382       b2a['A' + x] = x;
00383       /* a-z */
00384       base64[x + 26] = 'a' + x;
00385       b2a['a' + x] = x + 26;
00386       /* 0-9 */
00387       if (x < 10) {
00388          base64[x + 52] = '0' + x;
00389          b2a['0' + x] = x + 52;
00390       }
00391    }
00392    base64[62] = '+';
00393    base64[63] = '/';
00394    b2a[(int)'+'] = 62;
00395    b2a[(int)'/'] = 63;
00396 }
00397 
00398 const struct ast_flags ast_uri_http = {AST_URI_UNRESERVED};
00399 const struct ast_flags ast_uri_http_legacy = {AST_URI_LEGACY_SPACE | AST_URI_UNRESERVED};
00400 const struct ast_flags ast_uri_sip_user = {AST_URI_UNRESERVED | AST_URI_SIP_USER_UNRESERVED};
00401 
00402 char *ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec)
00403 {
00404    const char *ptr  = string; /* Start with the string */
00405    char *out = outbuf;
00406    const char *mark = "-_.!~*'()"; /* no encode set, RFC 2396 section 2.3, RFC 3261 sec 25 */
00407    const char *user_unreserved = "&=+$,;?/"; /* user-unreserved set, RFC 3261 sec 25 */
00408 
00409    while (*ptr && out - outbuf < buflen - 1) {
00410       if (ast_test_flag(&spec, AST_URI_LEGACY_SPACE) && *ptr == ' ') {
00411          /* for legacy encoding, encode spaces as '+' */
00412          *out = '+';
00413          out++;
00414       } else if (!(ast_test_flag(&spec, AST_URI_MARK)
00415             && strchr(mark, *ptr))
00416          && !(ast_test_flag(&spec, AST_URI_ALPHANUM)
00417             && ((*ptr >= '0' && *ptr <= '9')
00418             || (*ptr >= 'A' && *ptr <= 'Z')
00419             || (*ptr >= 'a' && *ptr <= 'z')))
00420          && !(ast_test_flag(&spec, AST_URI_SIP_USER_UNRESERVED)
00421             && strchr(user_unreserved, *ptr))) {
00422 
00423          if (out - outbuf >= buflen - 3) {
00424             break;
00425          }
00426          out += sprintf(out, "%%%02X", (unsigned char) *ptr);
00427       } else {
00428          *out = *ptr;   /* Continue copying the string */
00429          out++;
00430       }
00431       ptr++;
00432    }
00433 
00434    if (buflen) {
00435       *out = '\0';
00436    }
00437 
00438    return outbuf;
00439 }
00440 
00441 void ast_uri_decode(char *s, struct ast_flags spec)
00442 {
00443    char *o;
00444    unsigned int tmp;
00445 
00446    for (o = s; *s; s++, o++) {
00447       if (ast_test_flag(&spec, AST_URI_LEGACY_SPACE) && *s == '+') {
00448          /* legacy mode, decode '+' as space */
00449          *o = ' ';
00450       } else if (*s == '%' && s[1] != '\0' && s[2] != '\0' && sscanf(s + 1, "%2x", &tmp) == 1) {
00451          /* have '%', two chars and correct parsing */
00452          *o = tmp;
00453          s += 2;  /* Will be incremented once more when we break out */
00454       } else /* all other cases, just copy */
00455          *o = *s;
00456    }
00457    *o = '\0';
00458 }
00459 
00460 char *ast_escape_quoted(const char *string, char *outbuf, int buflen)
00461 {
00462    const char *ptr  = string;
00463    char *out = outbuf;
00464    char *allow = "\t\v !"; /* allow LWS (minus \r and \n) and "!" */
00465 
00466    while (*ptr && out - outbuf < buflen - 1) {
00467       if (!(strchr(allow, *ptr))
00468          && !(*ptr >= '#' && *ptr <= '[') /* %x23 - %x5b */
00469          && !(*ptr >= ']' && *ptr <= '~') /* %x5d - %x7e */
00470          && !((unsigned char) *ptr > 0x7f)) {             /* UTF8-nonascii */
00471 
00472          if (out - outbuf >= buflen - 2) {
00473             break;
00474          }
00475          out += sprintf(out, "\\%c", (unsigned char) *ptr);
00476       } else {
00477          *out = *ptr;
00478          out++;
00479       }
00480       ptr++;
00481    }
00482 
00483    if (buflen) {
00484       *out = '\0';
00485    }
00486 
00487    return outbuf;
00488 }
00489 int ast_xml_escape(const char *string, char * const outbuf, const size_t buflen)
00490 {
00491    char *dst = outbuf;
00492    char *end = outbuf + buflen - 1; /* save one for the null terminator */
00493 
00494    /* Handle the case for the empty output buffer */
00495    if (buflen == 0) {
00496       return -1;
00497    }
00498 
00499    /* Escaping rules from http://www.w3.org/TR/REC-xml/#syntax */
00500    /* This also prevents partial entities at the end of a string */
00501    while (*string && dst < end) {
00502       const char *entity = NULL;
00503       int len = 0;
00504 
00505       switch (*string) {
00506       case '<':
00507          entity = "&lt;";
00508          len = 4;
00509          break;
00510       case '&':
00511          entity = "&amp;";
00512          len = 5;
00513          break;
00514       case '>':
00515          /* necessary if ]]> is in the string; easier to escape them all */
00516          entity = "&gt;";
00517          len = 4;
00518          break;
00519       case '\'':
00520          /* necessary in single-quoted strings; easier to escape them all */
00521          entity = "&apos;";
00522          len = 6;
00523          break;
00524       case '"':
00525          /* necessary in double-quoted strings; easier to escape them all */
00526          entity = "&quot;";
00527          len = 6;
00528          break;
00529       default:
00530          *dst++ = *string++;
00531          break;
00532       }
00533 
00534       if (entity) {
00535          ast_assert(len == strlen(entity));
00536          if (end - dst < len) {
00537             /* no room for the entity; stop */
00538             break;
00539          }
00540          /* just checked for length; strcpy is fine */
00541          strcpy(dst, entity);
00542          dst += len;
00543          ++string;
00544       }
00545    }
00546    /* Write null terminator */
00547    *dst = '\0';
00548    /* If any chars are left in string, return failure */
00549    return *string == '\0' ? 0 : -1;
00550 }
00551 
00552 /*! \brief  ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
00553 const char *ast_inet_ntoa(struct in_addr ia)
00554 {
00555    char *buf;
00556 
00557    if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
00558       return "";
00559 
00560    return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
00561 }
00562 
00563 #ifdef HAVE_DEV_URANDOM
00564 static int dev_urandom_fd;
00565 #endif
00566 
00567 #ifndef __linux__
00568 #undef pthread_create /* For ast_pthread_create function only */
00569 #endif /* !__linux__ */
00570 
00571 #if !defined(LOW_MEMORY)
00572 
00573 #ifdef DEBUG_THREADS
00574 
00575 /*! \brief A reasonable maximum number of locks a thread would be holding ... */
00576 #define AST_MAX_LOCKS 64
00577 
00578 /* Allow direct use of pthread_mutex_t and friends */
00579 #undef pthread_mutex_t
00580 #undef pthread_mutex_lock
00581 #undef pthread_mutex_unlock
00582 #undef pthread_mutex_init
00583 #undef pthread_mutex_destroy
00584 
00585 /*!
00586  * \brief Keep track of which locks a thread holds
00587  *
00588  * There is an instance of this struct for every active thread
00589  */
00590 struct thr_lock_info {
00591    /*! The thread's ID */
00592    pthread_t thread_id;
00593    /*! The thread name which includes where the thread was started */
00594    const char *thread_name;
00595    /*! This is the actual container of info for what locks this thread holds */
00596    struct {
00597       const char *file;
00598       int line_num;
00599       const char *func;
00600       const char *lock_name;
00601       void *lock_addr;
00602       int times_locked;
00603       enum ast_lock_type type;
00604       /*! This thread is waiting on this lock */
00605       int pending:2;
00606       /*! A condition has suspended this lock */
00607       int suspended:1;
00608 #ifdef HAVE_BKTR
00609       struct ast_bt *backtrace;
00610 #endif
00611    } locks[AST_MAX_LOCKS];
00612    /*! This is the number of locks currently held by this thread.
00613     *  The index (num_locks - 1) has the info on the last one in the
00614     *  locks member */
00615    unsigned int num_locks;
00616    /*! Protects the contents of the locks member
00617     * Intentionally not ast_mutex_t */
00618    pthread_mutex_t lock;
00619    AST_LIST_ENTRY(thr_lock_info) entry;
00620 };
00621 
00622 /*!
00623  * \brief Locked when accessing the lock_infos list
00624  */
00625 AST_MUTEX_DEFINE_STATIC(lock_infos_lock);
00626 /*!
00627  * \brief A list of each thread's lock info
00628  */
00629 static AST_LIST_HEAD_NOLOCK_STATIC(lock_infos, thr_lock_info);
00630 
00631 /*!
00632  * \brief Destroy a thread's lock info
00633  *
00634  * This gets called automatically when the thread stops
00635  */
00636 static void lock_info_destroy(void *data)
00637 {
00638    struct thr_lock_info *lock_info = data;
00639    int i;
00640 
00641    pthread_mutex_lock(&lock_infos_lock.mutex);
00642    AST_LIST_REMOVE(&lock_infos, lock_info, entry);
00643    pthread_mutex_unlock(&lock_infos_lock.mutex);
00644 
00645 
00646    for (i = 0; i < lock_info->num_locks; i++) {
00647       if (lock_info->locks[i].pending == -1) {
00648          /* This just means that the last lock this thread went for was by
00649           * using trylock, and it failed.  This is fine. */
00650          break;
00651       }
00652 
00653       ast_log(LOG_ERROR,
00654          "Thread '%s' still has a lock! - '%s' (%p) from '%s' in %s:%d!\n",
00655          lock_info->thread_name,
00656          lock_info->locks[i].lock_name,
00657          lock_info->locks[i].lock_addr,
00658          lock_info->locks[i].func,
00659          lock_info->locks[i].file,
00660          lock_info->locks[i].line_num
00661       );
00662    }
00663 
00664    pthread_mutex_destroy(&lock_info->lock);
00665    if (lock_info->thread_name)
00666       free((void *) lock_info->thread_name);
00667    free(lock_info);
00668 }
00669 
00670 /*!
00671  * \brief The thread storage key for per-thread lock info
00672  */
00673 AST_THREADSTORAGE_CUSTOM(thread_lock_info, NULL, lock_info_destroy);
00674 #ifdef HAVE_BKTR
00675 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
00676    int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
00677 #else
00678 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
00679    int line_num, const char *func, const char *lock_name, void *lock_addr)
00680 #endif
00681 {
00682    struct thr_lock_info *lock_info;
00683    int i;
00684 
00685    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00686       return;
00687 
00688    pthread_mutex_lock(&lock_info->lock);
00689 
00690    for (i = 0; i < lock_info->num_locks; i++) {
00691       if (lock_info->locks[i].lock_addr == lock_addr) {
00692          lock_info->locks[i].times_locked++;
00693 #ifdef HAVE_BKTR
00694          lock_info->locks[i].backtrace = bt;
00695 #endif
00696          pthread_mutex_unlock(&lock_info->lock);
00697          return;
00698       }
00699    }
00700 
00701    if (lock_info->num_locks == AST_MAX_LOCKS) {
00702       /* Can't use ast_log here, because it will cause infinite recursion */
00703       fprintf(stderr, "XXX ERROR XXX A thread holds more locks than '%d'."
00704          "  Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
00705       pthread_mutex_unlock(&lock_info->lock);
00706       return;
00707    }
00708 
00709    if (i && lock_info->locks[i - 1].pending == -1) {
00710       /* The last lock on the list was one that this thread tried to lock but
00711        * failed at doing so.  It has now moved on to something else, so remove
00712        * the old lock from the list. */
00713       i--;
00714       lock_info->num_locks--;
00715       memset(&lock_info->locks[i], 0, sizeof(lock_info->locks[0]));
00716    }
00717 
00718    lock_info->locks[i].file = filename;
00719    lock_info->locks[i].line_num = line_num;
00720    lock_info->locks[i].func = func;
00721    lock_info->locks[i].lock_name = lock_name;
00722    lock_info->locks[i].lock_addr = lock_addr;
00723    lock_info->locks[i].times_locked = 1;
00724    lock_info->locks[i].type = type;
00725    lock_info->locks[i].pending = 1;
00726 #ifdef HAVE_BKTR
00727    lock_info->locks[i].backtrace = bt;
00728 #endif
00729    lock_info->num_locks++;
00730 
00731    pthread_mutex_unlock(&lock_info->lock);
00732 }
00733 
00734 void ast_mark_lock_acquired(void *lock_addr)
00735 {
00736    struct thr_lock_info *lock_info;
00737 
00738    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00739       return;
00740 
00741    pthread_mutex_lock(&lock_info->lock);
00742    if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
00743       lock_info->locks[lock_info->num_locks - 1].pending = 0;
00744    }
00745    pthread_mutex_unlock(&lock_info->lock);
00746 }
00747 
00748 void ast_mark_lock_failed(void *lock_addr)
00749 {
00750    struct thr_lock_info *lock_info;
00751 
00752    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00753       return;
00754 
00755    pthread_mutex_lock(&lock_info->lock);
00756    if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
00757       lock_info->locks[lock_info->num_locks - 1].pending = -1;
00758       lock_info->locks[lock_info->num_locks - 1].times_locked--;
00759    }
00760    pthread_mutex_unlock(&lock_info->lock);
00761 }
00762 
00763 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)
00764 {
00765    struct thr_lock_info *lock_info;
00766    int i = 0;
00767 
00768    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00769       return -1;
00770 
00771    pthread_mutex_lock(&lock_info->lock);
00772 
00773    for (i = lock_info->num_locks - 1; i >= 0; i--) {
00774       if (lock_info->locks[i].lock_addr == lock_addr)
00775          break;
00776    }
00777 
00778    if (i == -1) {
00779       /* Lock not found :( */
00780       pthread_mutex_unlock(&lock_info->lock);
00781       return -1;
00782    }
00783 
00784    ast_copy_string(filename, lock_info->locks[i].file, filename_size);
00785    *lineno = lock_info->locks[i].line_num;
00786    ast_copy_string(func, lock_info->locks[i].func, func_size);
00787    ast_copy_string(mutex_name, lock_info->locks[i].lock_name, mutex_name_size);
00788 
00789    pthread_mutex_unlock(&lock_info->lock);
00790 
00791    return 0;
00792 }
00793 
00794 void ast_suspend_lock_info(void *lock_addr)
00795 {
00796    struct thr_lock_info *lock_info;
00797    int i = 0;
00798 
00799    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info)))) {
00800       return;
00801    }
00802 
00803    pthread_mutex_lock(&lock_info->lock);
00804 
00805    for (i = lock_info->num_locks - 1; i >= 0; i--) {
00806       if (lock_info->locks[i].lock_addr == lock_addr)
00807          break;
00808    }
00809 
00810    if (i == -1) {
00811       /* Lock not found :( */
00812       pthread_mutex_unlock(&lock_info->lock);
00813       return;
00814    }
00815 
00816    lock_info->locks[i].suspended = 1;
00817 
00818    pthread_mutex_unlock(&lock_info->lock);
00819 }
00820 
00821 void ast_restore_lock_info(void *lock_addr)
00822 {
00823    struct thr_lock_info *lock_info;
00824    int i = 0;
00825 
00826    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00827       return;
00828 
00829    pthread_mutex_lock(&lock_info->lock);
00830 
00831    for (i = lock_info->num_locks - 1; i >= 0; i--) {
00832       if (lock_info->locks[i].lock_addr == lock_addr)
00833          break;
00834    }
00835 
00836    if (i == -1) {
00837       /* Lock not found :( */
00838       pthread_mutex_unlock(&lock_info->lock);
00839       return;
00840    }
00841 
00842    lock_info->locks[i].suspended = 0;
00843 
00844    pthread_mutex_unlock(&lock_info->lock);
00845 }
00846 
00847 
00848 #ifdef HAVE_BKTR
00849 void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt)
00850 #else
00851 void ast_remove_lock_info(void *lock_addr)
00852 #endif
00853 {
00854    struct thr_lock_info *lock_info;
00855    int i = 0;
00856 
00857    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00858       return;
00859 
00860    pthread_mutex_lock(&lock_info->lock);
00861 
00862    for (i = lock_info->num_locks - 1; i >= 0; i--) {
00863       if (lock_info->locks[i].lock_addr == lock_addr)
00864          break;
00865    }
00866 
00867    if (i == -1) {
00868       /* Lock not found :( */
00869       pthread_mutex_unlock(&lock_info->lock);
00870       return;
00871    }
00872 
00873    if (lock_info->locks[i].times_locked > 1) {
00874       lock_info->locks[i].times_locked--;
00875 #ifdef HAVE_BKTR
00876       lock_info->locks[i].backtrace = bt;
00877 #endif
00878       pthread_mutex_unlock(&lock_info->lock);
00879       return;
00880    }
00881 
00882    if (i < lock_info->num_locks - 1) {
00883       /* Not the last one ... *should* be rare! */
00884       memmove(&lock_info->locks[i], &lock_info->locks[i + 1],
00885          (lock_info->num_locks - (i + 1)) * sizeof(lock_info->locks[0]));
00886    }
00887 
00888    lock_info->num_locks--;
00889 
00890    pthread_mutex_unlock(&lock_info->lock);
00891 }
00892 
00893 static const char *locktype2str(enum ast_lock_type type)
00894 {
00895    switch (type) {
00896    case AST_MUTEX:
00897       return "MUTEX";
00898    case AST_RDLOCK:
00899       return "RDLOCK";
00900    case AST_WRLOCK:
00901       return "WRLOCK";
00902    }
00903 
00904    return "UNKNOWN";
00905 }
00906 
00907 #ifdef HAVE_BKTR
00908 static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt)
00909 {
00910    char **symbols;
00911    int num_frames;
00912 
00913    if (!bt) {
00914       ast_str_append(str, 0, "\tNo backtrace to print\n");
00915       return;
00916    }
00917 
00918    /* store frame count locally to avoid the memory corruption that
00919     * sometimes happens on virtualized CentOS 6.x systems */
00920    num_frames = bt->num_frames;
00921    if ((symbols = ast_bt_get_symbols(bt->addresses, num_frames))) {
00922       int frame_iterator;
00923 
00924       for (frame_iterator = 0; frame_iterator < num_frames; ++frame_iterator) {
00925          ast_str_append(str, 0, "\t%s\n", symbols[frame_iterator]);
00926       }
00927 
00928       ast_std_free(symbols);
00929    } else {
00930       ast_str_append(str, 0, "\tCouldn't retrieve backtrace symbols\n");
00931    }
00932 }
00933 #endif
00934 
00935 static void append_lock_information(struct ast_str **str, struct thr_lock_info *lock_info, int i)
00936 {
00937    int j;
00938    ast_mutex_t *lock;
00939    struct ast_lock_track *lt;
00940 
00941    ast_str_append(str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d%s)\n",
00942                lock_info->locks[i].pending > 0 ? "Waiting for " :
00943                lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
00944                lock_info->locks[i].file,
00945                locktype2str(lock_info->locks[i].type),
00946                lock_info->locks[i].line_num,
00947                lock_info->locks[i].func, lock_info->locks[i].lock_name,
00948                lock_info->locks[i].lock_addr,
00949                lock_info->locks[i].times_locked,
00950                lock_info->locks[i].suspended ? " - suspended" : "");
00951 #ifdef HAVE_BKTR
00952    append_backtrace_information(str, lock_info->locks[i].backtrace);
00953 #endif
00954 
00955    if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
00956       return;
00957 
00958    /* We only have further details for mutexes right now */
00959    if (lock_info->locks[i].type != AST_MUTEX)
00960       return;
00961 
00962    lock = lock_info->locks[i].lock_addr;
00963    lt = lock->track;
00964    ast_reentrancy_lock(lt);
00965    for (j = 0; *str && j < lt->reentrancy; j++) {
00966       ast_str_append(str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n",
00967                   lt->file[j], lt->lineno[j], lt->func[j]);
00968    }
00969    ast_reentrancy_unlock(lt);
00970 }
00971 
00972 
00973 /*! This function can help you find highly temporal locks; locks that happen for a
00974     short time, but at unexpected times, usually at times that create a deadlock,
00975    Why is this thing locked right then? Who is locking it? Who am I fighting
00976     with for this lock?
00977 
00978    To answer such questions, just call this routine before you would normally try
00979    to aquire a lock. It doesn't do anything if the lock is not acquired. If the
00980    lock is taken, it will publish a line or two to the console via ast_log().
00981 
00982    Sometimes, the lock message is pretty uninformative. For instance, you might
00983    find that the lock is being aquired deep within the astobj2 code; this tells
00984    you little about higher level routines that call the astobj2 routines.
00985    But, using gdb, you can set a break at the ast_log below, and for that
00986    breakpoint, you can set the commands:
00987      where
00988      cont
00989    which will give a stack trace and continue. -- that aught to do the job!
00990 
00991 */
00992 void log_show_lock(void *this_lock_addr)
00993 {
00994    struct thr_lock_info *lock_info;
00995    struct ast_str *str;
00996 
00997    if (!(str = ast_str_create(4096))) {
00998       ast_log(LOG_NOTICE,"Could not create str\n");
00999       return;
01000    }
01001 
01002 
01003    pthread_mutex_lock(&lock_infos_lock.mutex);
01004    AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
01005       int i;
01006       pthread_mutex_lock(&lock_info->lock);
01007       for (i = 0; str && i < lock_info->num_locks; i++) {
01008          /* ONLY show info about this particular lock, if
01009             it's acquired... */
01010          if (lock_info->locks[i].lock_addr == this_lock_addr) {
01011             append_lock_information(&str, lock_info, i);
01012             ast_log(LOG_NOTICE, "%s", ast_str_buffer(str));
01013             break;
01014          }
01015       }
01016       pthread_mutex_unlock(&lock_info->lock);
01017    }
01018    pthread_mutex_unlock(&lock_infos_lock.mutex);
01019    ast_free(str);
01020 }
01021 
01022 
01023 static char *handle_show_locks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01024 {
01025    struct thr_lock_info *lock_info;
01026    struct ast_str *str;
01027 
01028    switch (cmd) {
01029    case CLI_INIT:
01030       e->command = "core show locks";
01031       e->usage =
01032          "Usage: core show locks\n"
01033          "       This command is for lock debugging.  It prints out which locks\n"
01034          "are owned by each active thread.\n";
01035       return NULL;
01036 
01037    case CLI_GENERATE:
01038       return NULL;
01039    }
01040 
01041    if (!(str = ast_str_create(4096)))
01042       return CLI_FAILURE;
01043 
01044    ast_str_append(&str, 0, "\n" 
01045                   "=======================================================================\n"
01046                   "=== %s\n"
01047                   "=== Currently Held Locks\n"
01048                   "=======================================================================\n"
01049                   "===\n"
01050                   "=== <pending> <lock#> (<file>): <lock type> <line num> <function> <lock name> <lock addr> (times locked)\n"
01051                   "===\n", ast_get_version());
01052 
01053    if (!str)
01054       return CLI_FAILURE;
01055 
01056    pthread_mutex_lock(&lock_infos_lock.mutex);
01057    AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
01058       int i;
01059       int header_printed = 0;
01060       pthread_mutex_lock(&lock_info->lock);
01061       for (i = 0; str && i < lock_info->num_locks; i++) {
01062          /* Don't show suspended locks */
01063          if (lock_info->locks[i].suspended) {
01064             continue;
01065          }
01066 
01067          if (!header_printed) {
01068             ast_str_append(&str, 0, "=== Thread ID: 0x%lx (%s)\n", (long) lock_info->thread_id,
01069                lock_info->thread_name);
01070             header_printed = 1;
01071          }
01072 
01073          append_lock_information(&str, lock_info, i);
01074       }
01075       pthread_mutex_unlock(&lock_info->lock);
01076       if (!str) {
01077          break;
01078       }
01079       if (header_printed) {
01080          ast_str_append(&str, 0, "=== -------------------------------------------------------------------\n"
01081             "===\n");
01082       }
01083       if (!str) {
01084          break;
01085       }
01086    }
01087    pthread_mutex_unlock(&lock_infos_lock.mutex);
01088 
01089    if (!str)
01090       return CLI_FAILURE;
01091 
01092    ast_str_append(&str, 0, "=======================================================================\n"
01093                   "\n");
01094 
01095    if (!str)
01096       return CLI_FAILURE;
01097 
01098    ast_cli(a->fd, "%s", ast_str_buffer(str));
01099 
01100    ast_free(str);
01101 
01102    return CLI_SUCCESS;
01103 }
01104 
01105 static struct ast_cli_entry utils_cli[] = {
01106    AST_CLI_DEFINE(handle_show_locks, "Show which locks are held by which thread"),
01107 };
01108 
01109 #endif /* DEBUG_THREADS */
01110 
01111 /*
01112  * support for 'show threads'. The start routine is wrapped by
01113  * dummy_start(), so that ast_register_thread() and
01114  * ast_unregister_thread() know the thread identifier.
01115  */
01116 struct thr_arg {
01117    void *(*start_routine)(void *);
01118    void *data;
01119    char *name;
01120 };
01121 
01122 /*
01123  * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
01124  * are odd macros which start and end a block, so they _must_ be
01125  * used in pairs (the latter with a '1' argument to call the
01126  * handler on exit.
01127  * On BSD we don't need this, but we keep it for compatibility.
01128  */
01129 static void *dummy_start(void *data)
01130 {
01131    void *ret;
01132    struct thr_arg a = *((struct thr_arg *) data);  /* make a local copy */
01133 #ifdef DEBUG_THREADS
01134    struct thr_lock_info *lock_info;
01135    pthread_mutexattr_t mutex_attr;
01136 
01137    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
01138       return NULL;
01139 
01140    lock_info->thread_id = pthread_self();
01141    lock_info->thread_name = strdup(a.name);
01142 
01143    pthread_mutexattr_init(&mutex_attr);
01144    pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND);
01145    pthread_mutex_init(&lock_info->lock, &mutex_attr);
01146    pthread_mutexattr_destroy(&mutex_attr);
01147 
01148    pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
01149    AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry);
01150    pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
01151 #endif /* DEBUG_THREADS */
01152 
01153    /* note that even though data->name is a pointer to allocated memory,
01154       we are not freeing it here because ast_register_thread is going to
01155       keep a copy of the pointer and then ast_unregister_thread will
01156       free the memory
01157    */
01158    ast_free(data);
01159    ast_register_thread(a.name);
01160    pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());
01161 
01162    ret = a.start_routine(a.data);
01163 
01164    pthread_cleanup_pop(1);
01165 
01166    return ret;
01167 }
01168 
01169 #endif /* !LOW_MEMORY */
01170 
01171 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
01172               void *data, size_t stacksize, const char *file, const char *caller,
01173               int line, const char *start_fn)
01174 {
01175 #if !defined(LOW_MEMORY)
01176    struct thr_arg *a;
01177 #endif
01178 
01179    if (!attr) {
01180       attr = ast_alloca(sizeof(*attr));
01181       pthread_attr_init(attr);
01182    }
01183 
01184 #ifdef __linux__
01185    /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
01186       which is kind of useless. Change this here to
01187       PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
01188       priority will propagate down to new threads by default.
01189       This does mean that callers cannot set a different priority using
01190       PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
01191       the priority afterwards with pthread_setschedparam(). */
01192    if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
01193       ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
01194 #endif
01195 
01196    if (!stacksize)
01197       stacksize = AST_STACKSIZE;
01198 
01199    if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
01200       ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));
01201 
01202 #if !defined(LOW_MEMORY)
01203    if ((a = ast_malloc(sizeof(*a)))) {
01204       a->start_routine = start_routine;
01205       a->data = data;
01206       start_routine = dummy_start;
01207       if (ast_asprintf(&a->name, "%-20s started at [%5d] %s %s()",
01208               start_fn, line, file, caller) < 0) {
01209          a->name = NULL;
01210       }
01211       data = a;
01212    }
01213 #endif /* !LOW_MEMORY */
01214 
01215    return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
01216 }
01217 
01218 
01219 int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
01220               void *data, size_t stacksize, const char *file, const char *caller,
01221               int line, const char *start_fn)
01222 {
01223    unsigned char attr_destroy = 0;
01224    int res;
01225 
01226    if (!attr) {
01227       attr = ast_alloca(sizeof(*attr));
01228       pthread_attr_init(attr);
01229       attr_destroy = 1;
01230    }
01231 
01232    if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
01233       ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno));
01234 
01235    res = ast_pthread_create_stack(thread, attr, start_routine, data,
01236                                   stacksize, file, caller, line, start_fn);
01237 
01238    if (attr_destroy)
01239       pthread_attr_destroy(attr);
01240 
01241    return res;
01242 }
01243 
01244 int ast_wait_for_input(int fd, int ms)
01245 {
01246    struct pollfd pfd[1];
01247    memset(pfd, 0, sizeof(pfd));
01248    pfd[0].fd = fd;
01249    pfd[0].events = POLLIN|POLLPRI;
01250    return ast_poll(pfd, 1, ms);
01251 }
01252 
01253 static int ast_wait_for_output(int fd, int timeoutms)
01254 {
01255    struct pollfd pfd = {
01256       .fd = fd,
01257       .events = POLLOUT,
01258    };
01259    int res;
01260    struct timeval start = ast_tvnow();
01261    int elapsed = 0;
01262 
01263    /* poll() until the fd is writable without blocking */
01264    while ((res = ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
01265       if (res == 0) {
01266          /* timed out. */
01267 #ifndef STANDALONE
01268          ast_debug(1, "Timed out trying to write\n");
01269 #endif
01270          return -1;
01271       } else if (res == -1) {
01272          /* poll() returned an error, check to see if it was fatal */
01273 
01274          if (errno == EINTR || errno == EAGAIN) {
01275             elapsed = ast_tvdiff_ms(ast_tvnow(), start);
01276             if (elapsed >= timeoutms) {
01277                return -1;
01278             }
01279             /* This was an acceptable error, go back into poll() */
01280             continue;
01281          }
01282 
01283          /* Fatal error, bail. */
01284          ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno));
01285 
01286          return -1;
01287       }
01288       elapsed = ast_tvdiff_ms(ast_tvnow(), start);
01289       if (elapsed >= timeoutms) {
01290          return -1;
01291       }
01292    }
01293 
01294    return 0;
01295 }
01296 
01297 /*!
01298  * Try to write string, but wait no more than ms milliseconds before timing out.
01299  *
01300  * \note The code assumes that the file descriptor has NONBLOCK set,
01301  * so there is only one system call made to do a write, unless we actually
01302  * have a need to wait.  This way, we get better performance.
01303  * If the descriptor is blocking, all assumptions on the guaranteed
01304  * detail do not apply anymore.
01305  */
01306 int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
01307 {
01308    struct timeval start = ast_tvnow();
01309    int res = 0;
01310    int elapsed = 0;
01311 
01312    while (len) {
01313       if (ast_wait_for_output(fd, timeoutms - elapsed)) {
01314          return -1;
01315       }
01316 
01317       res = write(fd, s, len);
01318 
01319       if (res < 0 && errno != EAGAIN && errno != EINTR) {
01320          /* fatal error from write() */
01321          ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
01322          return -1;
01323       }
01324 
01325       if (res < 0) {
01326          /* It was an acceptable error */
01327          res = 0;
01328       }
01329 
01330       /* Update how much data we have left to write */
01331       len -= res;
01332       s += res;
01333       res = 0;
01334 
01335       elapsed = ast_tvdiff_ms(ast_tvnow(), start);
01336       if (elapsed >= timeoutms) {
01337          /* We've taken too long to write
01338           * This is only an error condition if we haven't finished writing. */
01339          res = len ? -1 : 0;
01340          break;
01341       }
01342    }
01343 
01344    return res;
01345 }
01346 
01347 int ast_careful_fwrite(FILE *f, int fd, const char *src, size_t len, int timeoutms)
01348 {
01349    struct timeval start = ast_tvnow();
01350    int n = 0;
01351    int elapsed = 0;
01352 
01353    while (len) {
01354       if (ast_wait_for_output(fd, timeoutms - elapsed)) {
01355          /* poll returned a fatal error, so bail out immediately. */
01356          return -1;
01357       }
01358 
01359       /* Clear any errors from a previous write */
01360       clearerr(f);
01361 
01362       n = fwrite(src, 1, len, f);
01363 
01364       if (ferror(f) && errno != EINTR && errno != EAGAIN) {
01365          /* fatal error from fwrite() */
01366          if (!feof(f)) {
01367             /* Don't spam the logs if it was just that the connection is closed. */
01368             ast_log(LOG_ERROR, "fwrite() returned error: %s\n", strerror(errno));
01369          }
01370          n = -1;
01371          break;
01372       }
01373 
01374       /* Update for data already written to the socket */
01375       len -= n;
01376       src += n;
01377 
01378       elapsed = ast_tvdiff_ms(ast_tvnow(), start);
01379       if (elapsed >= timeoutms) {
01380          /* We've taken too long to write
01381           * This is only an error condition if we haven't finished writing. */
01382          n = len ? -1 : 0;
01383          break;
01384       }
01385    }
01386 
01387    while (fflush(f)) {
01388       if (errno == EAGAIN || errno == EINTR) {
01389          continue;
01390       }
01391       if (!feof(f)) {
01392          /* Don't spam the logs if it was just that the connection is closed. */
01393          ast_log(LOG_ERROR, "fflush() returned error: %s\n", strerror(errno));
01394       }
01395       n = -1;
01396       break;
01397    }
01398 
01399    return n < 0 ? -1 : 0;
01400 }
01401 
01402 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
01403 {
01404    char *e;
01405    char *q;
01406 
01407    s = ast_strip(s);
01408    if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
01409       e = s + strlen(s) - 1;
01410       if (*e == *(end_quotes + (q - beg_quotes))) {
01411          s++;
01412          *e = '\0';
01413       }
01414    }
01415 
01416    return s;
01417 }
01418 
01419 char *ast_unescape_semicolon(char *s)
01420 {
01421    char *e;
01422    char *work = s;
01423 
01424    while ((e = strchr(work, ';'))) {
01425       if ((e > work) && (*(e-1) == '\\')) {
01426          memmove(e - 1, e, strlen(e) + 1);
01427          work = e;
01428       } else {
01429          work = e + 1;
01430       }
01431    }
01432 
01433    return s;
01434 }
01435 
01436 /* !\brief unescape some C sequences in place, return pointer to the original string.
01437  */
01438 char *ast_unescape_c(char *src)
01439 {
01440    char c, *ret, *dst;
01441 
01442    if (src == NULL)
01443       return NULL;
01444    for (ret = dst = src; (c = *src++); *dst++ = c ) {
01445       if (c != '\\')
01446          continue;   /* copy char at the end of the loop */
01447       switch ((c = *src++)) {
01448       case '\0':  /* special, trailing '\' */
01449          c = '\\';
01450          break;
01451       case 'b':   /* backspace */
01452          c = '\b';
01453          break;
01454       case 'f':   /* form feed */
01455          c = '\f';
01456          break;
01457       case 'n':
01458          c = '\n';
01459          break;
01460       case 'r':
01461          c = '\r';
01462          break;
01463       case 't':
01464          c = '\t';
01465          break;
01466       }
01467       /* default, use the char literally */
01468    }
01469    *dst = '\0';
01470    return ret;
01471 }
01472 
01473 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
01474 {
01475    int result;
01476 
01477    if (!buffer || !*buffer || !space || !*space)
01478       return -1;
01479 
01480    result = vsnprintf(*buffer, *space, fmt, ap);
01481 
01482    if (result < 0)
01483       return -1;
01484    else if (result > *space)
01485       result = *space;
01486 
01487    *buffer += result;
01488    *space -= result;
01489    return 0;
01490 }
01491 
01492 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
01493 {
01494    va_list ap;
01495    int result;
01496 
01497    va_start(ap, fmt);
01498    result = ast_build_string_va(buffer, space, fmt, ap);
01499    va_end(ap);
01500 
01501    return result;
01502 }
01503 
01504 int ast_regex_string_to_regex_pattern(const char *regex_string, struct ast_str **regex_pattern)
01505 {
01506    int regex_len = strlen(regex_string);
01507    int ret = 3;
01508 
01509    /* Chop off the leading / if there is one */
01510    if ((regex_len >= 1) && (regex_string[0] == '/')) {
01511       ast_str_set(regex_pattern, 0, "%s", regex_string + 1);
01512       ret -= 2;
01513    }
01514 
01515    /* Chop off the ending / if there is one */
01516    if ((regex_len > 1) && (regex_string[regex_len - 1] == '/')) {
01517       ast_str_truncate(*regex_pattern, -1);
01518       ret -= 1;
01519    }
01520 
01521    return ret;
01522 }
01523 
01524 int ast_true(const char *s)
01525 {
01526    if (ast_strlen_zero(s))
01527       return 0;
01528 
01529    /* Determine if this is a true value */
01530    if (!strcasecmp(s, "yes") ||
01531        !strcasecmp(s, "true") ||
01532        !strcasecmp(s, "y") ||
01533        !strcasecmp(s, "t") ||
01534        !strcasecmp(s, "1") ||
01535        !strcasecmp(s, "on"))
01536       return -1;
01537 
01538    return 0;
01539 }
01540 
01541 int ast_false(const char *s)
01542 {
01543    if (ast_strlen_zero(s))
01544       return 0;
01545 
01546    /* Determine if this is a false value */
01547    if (!strcasecmp(s, "no") ||
01548        !strcasecmp(s, "false") ||
01549        !strcasecmp(s, "n") ||
01550        !strcasecmp(s, "f") ||
01551        !strcasecmp(s, "0") ||
01552        !strcasecmp(s, "off"))
01553       return -1;
01554 
01555    return 0;
01556 }
01557 
01558 #define ONE_MILLION  1000000
01559 /*
01560  * put timeval in a valid range. usec is 0..999999
01561  * negative values are not allowed and truncated.
01562  */
01563 static struct timeval tvfix(struct timeval a)
01564 {
01565    if (a.tv_usec >= ONE_MILLION) {
01566       ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
01567          (long)a.tv_sec, (long int) a.tv_usec);
01568       a.tv_sec += a.tv_usec / ONE_MILLION;
01569       a.tv_usec %= ONE_MILLION;
01570    } else if (a.tv_usec < 0) {
01571       ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
01572          (long)a.tv_sec, (long int) a.tv_usec);
01573       a.tv_usec = 0;
01574    }
01575    return a;
01576 }
01577 
01578 struct timeval ast_tvadd(struct timeval a, struct timeval b)
01579 {
01580    /* consistency checks to guarantee usec in 0..999999 */
01581    a = tvfix(a);
01582    b = tvfix(b);
01583    a.tv_sec += b.tv_sec;
01584    a.tv_usec += b.tv_usec;
01585    if (a.tv_usec >= ONE_MILLION) {
01586       a.tv_sec++;
01587       a.tv_usec -= ONE_MILLION;
01588    }
01589    return a;
01590 }
01591 
01592 struct timeval ast_tvsub(struct timeval a, struct timeval b)
01593 {
01594    /* consistency checks to guarantee usec in 0..999999 */
01595    a = tvfix(a);
01596    b = tvfix(b);
01597    a.tv_sec -= b.tv_sec;
01598    a.tv_usec -= b.tv_usec;
01599    if (a.tv_usec < 0) {
01600       a.tv_sec-- ;
01601       a.tv_usec += ONE_MILLION;
01602    }
01603    return a;
01604 }
01605 
01606 int ast_remaining_ms(struct timeval start, int max_ms)
01607 {
01608    int ms;
01609 
01610    if (max_ms < 0) {
01611       ms = max_ms;
01612    } else {
01613       ms = max_ms - ast_tvdiff_ms(ast_tvnow(), start);
01614       if (ms < 0) {
01615          ms = 0;
01616       }
01617    }
01618 
01619    return ms;
01620 }
01621 
01622 #undef ONE_MILLION
01623 
01624 /*! \brief glibc puts a lock inside random(3), so that the results are thread-safe.
01625  * BSD libc (and others) do not. */
01626 
01627 #ifndef linux
01628 AST_MUTEX_DEFINE_STATIC(randomlock);
01629 #endif
01630 
01631 long int ast_random(void)
01632 {
01633    long int res;
01634 #ifdef HAVE_DEV_URANDOM
01635    if (dev_urandom_fd >= 0) {
01636       int read_res = read(dev_urandom_fd, &res, sizeof(res));
01637       if (read_res > 0) {
01638          long int rm = RAND_MAX;
01639          res = res < 0 ? ~res : res;
01640          rm++;
01641          return res % rm;
01642       }
01643    }
01644 #endif
01645 #ifdef linux
01646    res = random();
01647 #else
01648    ast_mutex_lock(&randomlock);
01649    res = random();
01650    ast_mutex_unlock(&randomlock);
01651 #endif
01652    return res;
01653 }
01654 
01655 void ast_replace_subargument_delimiter(char *s)
01656 {
01657    for (; *s; s++) {
01658       if (*s == '^') {
01659          *s = ',';
01660       }
01661    }
01662 }
01663 
01664 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
01665 {
01666    char *dataPut = start;
01667    int inEscape = 0;
01668    int inQuotes = 0;
01669 
01670    for (; *start; start++) {
01671       if (inEscape) {
01672          *dataPut++ = *start;       /* Always goes verbatim */
01673          inEscape = 0;
01674       } else {
01675          if (*start == '\\') {
01676             inEscape = 1;      /* Do not copy \ into the data */
01677          } else if (*start == '\'') {
01678             inQuotes = 1 - inQuotes;   /* Do not copy ' into the data */
01679          } else {
01680             /* Replace , with |, unless in quotes */
01681             *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
01682          }
01683       }
01684    }
01685    if (start != dataPut)
01686       *dataPut = 0;
01687    return dataPut;
01688 }
01689 
01690 void ast_join(char *s, size_t len, const char * const w[])
01691 {
01692    int x, ofs = 0;
01693    const char *src;
01694 
01695    /* Join words into a string */
01696    if (!s)
01697       return;
01698    for (x = 0; ofs < len && w[x]; x++) {
01699       if (x > 0)
01700          s[ofs++] = ' ';
01701       for (src = w[x]; *src && ofs < len; src++)
01702          s[ofs++] = *src;
01703    }
01704    if (ofs == len)
01705       ofs--;
01706    s[ofs] = '\0';
01707 }
01708 
01709 /*
01710  * stringfields support routines.
01711  */
01712 
01713 /* this is a little complex... string fields are stored with their
01714    allocated size in the bytes preceding the string; even the
01715    constant 'empty' string has to be this way, so the code that
01716    checks to see if there is enough room for a new string doesn't
01717    have to have any special case checks
01718 */
01719 
01720 static const struct {
01721    ast_string_field_allocation allocation;
01722    char string[1];
01723 } __ast_string_field_empty_buffer;
01724 
01725 ast_string_field __ast_string_field_empty = __ast_string_field_empty_buffer.string;
01726 
01727 #define ALLOCATOR_OVERHEAD 48
01728 
01729 static size_t optimal_alloc_size(size_t size)
01730 {
01731    unsigned int count;
01732 
01733    size += ALLOCATOR_OVERHEAD;
01734 
01735    for (count = 1; size; size >>= 1, count++);
01736 
01737    return (1 << count) - ALLOCATOR_OVERHEAD;
01738 }
01739 
01740 /*! \brief add a new block to the pool.
01741  * We can only allocate from the topmost pool, so the
01742  * fields in *mgr reflect the size of that only.
01743  */
01744 static int add_string_pool(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
01745             size_t size, const char *file, int lineno, const char *func)
01746 {
01747    struct ast_string_field_pool *pool;
01748    size_t alloc_size = optimal_alloc_size(sizeof(*pool) + size);
01749 
01750 #if defined(__AST_DEBUG_MALLOC)
01751    if (!(pool = __ast_calloc(1, alloc_size, file, lineno, func))) {
01752       return -1;
01753    }
01754 #else
01755    if (!(pool = ast_calloc(1, alloc_size))) {
01756       return -1;
01757    }
01758 #endif
01759 
01760    pool->prev = *pool_head;
01761    pool->size = alloc_size - sizeof(*pool);
01762    *pool_head = pool;
01763    mgr->last_alloc = NULL;
01764 
01765    return 0;
01766 }
01767 
01768 /*
01769  * This is an internal API, code should not use it directly.
01770  * It initializes all fields as empty, then uses 'size' for 3 functions:
01771  * size > 0 means initialize the pool list with a pool of given size.
01772  * This must be called right after allocating the object.
01773  * size = 0 means release all pools except the most recent one.
01774  *      If the first pool was allocated via embedding in another
01775  *      object, that pool will be preserved instead.
01776  * This is useful to e.g. reset an object to the initial value.
01777  * size < 0 means release all pools.
01778  * This must be done before destroying the object.
01779  */
01780 int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
01781              int needed, const char *file, int lineno, const char *func)
01782 {
01783    const char **p = (const char **) pool_head + 1;
01784    struct ast_string_field_pool *cur = NULL;
01785    struct ast_string_field_pool *preserve = NULL;
01786 
01787    /* clear fields - this is always necessary */
01788    while ((struct ast_string_field_mgr *) p != mgr) {
01789       *p++ = __ast_string_field_empty;
01790    }
01791 
01792    mgr->last_alloc = NULL;
01793 #if defined(__AST_DEBUG_MALLOC)
01794    mgr->owner_file = file;
01795    mgr->owner_func = func;
01796    mgr->owner_line = lineno;
01797 #endif
01798    if (needed > 0) {    /* allocate the initial pool */
01799       *pool_head = NULL;
01800       mgr->embedded_pool = NULL;
01801       return add_string_pool(mgr, pool_head, needed, file, lineno, func);
01802    }
01803 
01804    /* if there is an embedded pool, we can't actually release *all*
01805     * pools, we must keep the embedded one. if the caller is about
01806     * to free the structure that contains the stringfield manager
01807     * and embedded pool anyway, it will be freed as part of that
01808     * operation.
01809     */
01810    if ((needed < 0) && mgr->embedded_pool) {
01811       needed = 0;
01812    }
01813 
01814    if (needed < 0) {    /* reset all pools */
01815       cur = *pool_head;
01816    } else if (mgr->embedded_pool) { /* preserve the embedded pool */
01817       preserve = mgr->embedded_pool;
01818       cur = *pool_head;
01819    } else {       /* preserve the last pool */
01820       if (*pool_head == NULL) {
01821          ast_log(LOG_WARNING, "trying to reset empty pool\n");
01822          return -1;
01823       }
01824       preserve = *pool_head;
01825       cur = preserve->prev;
01826    }
01827 
01828    if (preserve) {
01829       preserve->prev = NULL;
01830       preserve->used = preserve->active = 0;
01831    }
01832 
01833    while (cur) {
01834       struct ast_string_field_pool *prev = cur->prev;
01835 
01836       if (cur != preserve) {
01837          ast_free(cur);
01838       }
01839       cur = prev;
01840    }
01841 
01842    *pool_head = preserve;
01843 
01844    return 0;
01845 }
01846 
01847 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr,
01848                   struct ast_string_field_pool **pool_head, size_t needed)
01849 {
01850    char *result = NULL;
01851    size_t space = (*pool_head)->size - (*pool_head)->used;
01852    size_t to_alloc;
01853 
01854    /* Make room for ast_string_field_allocation and make it a multiple of that. */
01855    to_alloc = ast_make_room_for(needed, ast_string_field_allocation);
01856    ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0);
01857 
01858    if (__builtin_expect(to_alloc > space, 0)) {
01859       size_t new_size = (*pool_head)->size;
01860 
01861       while (new_size < to_alloc) {
01862          new_size *= 2;
01863       }
01864 
01865 #if defined(__AST_DEBUG_MALLOC)
01866       if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
01867          return NULL;
01868 #else
01869       if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
01870          return NULL;
01871 #endif
01872    }
01873 
01874    /* pool->base is always aligned (gcc aligned attribute). We ensure that
01875     * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation)
01876     * causing result to always be aligned as well; which in turn fixes that
01877     * AST_STRING_FIELD_ALLOCATION(result) is aligned. */
01878    result = (*pool_head)->base + (*pool_head)->used;
01879    (*pool_head)->used += to_alloc;
01880    (*pool_head)->active += needed;
01881    result += ast_alignof(ast_string_field_allocation);
01882    AST_STRING_FIELD_ALLOCATION(result) = needed;
01883    mgr->last_alloc = result;
01884 
01885    return result;
01886 }
01887 
01888 int __ast_string_field_ptr_grow(struct ast_string_field_mgr *mgr,
01889             struct ast_string_field_pool **pool_head, size_t needed,
01890             const ast_string_field *ptr)
01891 {
01892    ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr);
01893    size_t space = (*pool_head)->size - (*pool_head)->used;
01894 
01895    if (*ptr != mgr->last_alloc) {
01896       return 1;
01897    }
01898 
01899    if (space < grow) {
01900       return 1;
01901    }
01902 
01903    (*pool_head)->used += grow;
01904    (*pool_head)->active += grow;
01905    AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
01906 
01907    return 0;
01908 }
01909 
01910 void __ast_string_field_release_active(struct ast_string_field_pool *pool_head,
01911                    const ast_string_field ptr)
01912 {
01913    struct ast_string_field_pool *pool, *prev;
01914 
01915    if (ptr == __ast_string_field_empty) {
01916       return;
01917    }
01918 
01919    for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) {
01920       if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) {
01921          pool->active -= AST_STRING_FIELD_ALLOCATION(ptr);
01922          if ((pool->active == 0) && prev) {
01923             prev->prev = pool->prev;
01924             ast_free(pool);
01925          }
01926          break;
01927       }
01928    }
01929 }
01930 
01931 void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
01932                  struct ast_string_field_pool **pool_head,
01933                  ast_string_field *ptr, const char *format, va_list ap)
01934 {
01935    size_t needed;
01936    size_t available;
01937    size_t space = (*pool_head)->size - (*pool_head)->used;
01938    ssize_t grow;
01939    char *target;
01940    va_list ap2;
01941 
01942    /* if the field already has space allocated, try to reuse it;
01943       otherwise, try to use the empty space at the end of the current
01944       pool
01945    */
01946    if (*ptr != __ast_string_field_empty) {
01947       target = (char *) *ptr;
01948       available = AST_STRING_FIELD_ALLOCATION(*ptr);
01949       if (*ptr == mgr->last_alloc) {
01950          available += space;
01951       }
01952    } else {
01953       /* pool->used is always a multiple of ast_alignof(ast_string_field_allocation)
01954        * so we don't need to re-align anything here.
01955        */
01956       target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation);
01957       available = space - ast_alignof(ast_string_field_allocation);
01958    }
01959 
01960    va_copy(ap2, ap);
01961    needed = vsnprintf(target, available, format, ap2) + 1;
01962    va_end(ap2);
01963 
01964    if (needed > available) {
01965       /* the allocation could not be satisfied using the field's current allocation
01966          (if it has one), or the space available in the pool (if it does not). allocate
01967          space for it, adding a new string pool if necessary.
01968       */
01969       if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) {
01970          return;
01971       }
01972       vsprintf(target, format, ap);
01973       va_end(ap); /* XXX va_end without va_start? */
01974       __ast_string_field_release_active(*pool_head, *ptr);
01975       *ptr = target;
01976    } else if (*ptr != target) {
01977       /* the allocation was satisfied using available space in the pool, but not
01978          using the space already allocated to the field
01979       */
01980       __ast_string_field_release_active(*pool_head, *ptr);
01981       mgr->last_alloc = *ptr = target;
01982       AST_STRING_FIELD_ALLOCATION(target) = needed;
01983       (*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation);
01984       (*pool_head)->active += needed;
01985    } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) {
01986       /* the allocation was satisfied by using available space in the pool *and*
01987          the field was the last allocated field from the pool, so it grew
01988       */
01989       AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
01990       (*pool_head)->used += ast_align_for(grow, ast_string_field_allocation);
01991       (*pool_head)->active += grow;
01992    }
01993 }
01994 
01995 void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
01996               struct ast_string_field_pool **pool_head,
01997               ast_string_field *ptr, const char *format, ...)
01998 {
01999    va_list ap;
02000 
02001    va_start(ap, format);
02002    __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap);
02003    va_end(ap);
02004 }
02005 
02006 void *__ast_calloc_with_stringfields(unsigned int num_structs, size_t struct_size, size_t field_mgr_offset,
02007                  size_t field_mgr_pool_offset, size_t pool_size, const char *file,
02008                  int lineno, const char *func)
02009 {
02010    struct ast_string_field_mgr *mgr;
02011    struct ast_string_field_pool *pool;
02012    struct ast_string_field_pool **pool_head;
02013    size_t pool_size_needed = sizeof(*pool) + pool_size;
02014    size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed);
02015    void *allocation;
02016    unsigned int x;
02017 
02018 #if defined(__AST_DEBUG_MALLOC)
02019    if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
02020       return NULL;
02021    }
02022 #else
02023    if (!(allocation = ast_calloc(num_structs, size_to_alloc))) {
02024       return NULL;
02025    }
02026 #endif
02027 
02028    for (x = 0; x < num_structs; x++) {
02029       void *base = allocation + (size_to_alloc * x);
02030       const char **p;
02031 
02032       mgr = base + field_mgr_offset;
02033       pool_head = base + field_mgr_pool_offset;
02034       pool = base + struct_size;
02035 
02036       p = (const char **) pool_head + 1;
02037       while ((struct ast_string_field_mgr *) p != mgr) {
02038          *p++ = __ast_string_field_empty;
02039       }
02040 
02041       mgr->embedded_pool = pool;
02042       *pool_head = pool;
02043       pool->size = size_to_alloc - struct_size - sizeof(*pool);
02044 #if defined(__AST_DEBUG_MALLOC)
02045       mgr->owner_file = file;
02046       mgr->owner_func = func;
02047       mgr->owner_line = lineno;
02048 #endif
02049    }
02050 
02051    return allocation;
02052 }
02053 
02054 /* end of stringfields support */
02055 
02056 AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
02057 
02058 int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
02059 {
02060    int ret;
02061    ast_mutex_lock(&fetchadd_m);
02062    ret = *p;
02063    *p += v;
02064    ast_mutex_unlock(&fetchadd_m);
02065    return ret;
02066 }
02067 
02068 /*! \brief
02069  * get values from config variables.
02070  */
02071 int ast_get_timeval(const char *src, struct timeval *dst, struct timeval _default, int *consumed)
02072 {
02073    long double dtv = 0.0;
02074    int scanned;
02075 
02076    if (dst == NULL)
02077       return -1;
02078 
02079    *dst = _default;
02080 
02081    if (ast_strlen_zero(src))
02082       return -1;
02083 
02084    /* only integer at the moment, but one day we could accept more formats */
02085    if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) {
02086       dst->tv_sec = dtv;
02087       dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
02088       if (consumed)
02089          *consumed = scanned;
02090       return 0;
02091    } else
02092       return -1;
02093 }
02094 
02095 /*! \brief
02096  * get values from config variables.
02097  */
02098 int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
02099 {
02100    long t;
02101    int scanned;
02102 
02103    if (dst == NULL)
02104       return -1;
02105 
02106    *dst = _default;
02107 
02108    if (ast_strlen_zero(src))
02109       return -1;
02110 
02111    /* only integer at the moment, but one day we could accept more formats */
02112    if (sscanf(src, "%30ld%n", &t, &scanned) == 1) {
02113       *dst = t;
02114       if (consumed)
02115          *consumed = scanned;
02116       return 0;
02117    } else
02118       return -1;
02119 }
02120 
02121 void ast_enable_packet_fragmentation(int sock)
02122 {
02123 #if defined(HAVE_IP_MTU_DISCOVER)
02124    int val = IP_PMTUDISC_DONT;
02125 
02126    if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
02127       ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
02128 #endif /* HAVE_IP_MTU_DISCOVER */
02129 }
02130 
02131 int ast_mkdir(const char *path, int mode)
02132 {
02133    char *ptr;
02134    int len = strlen(path), count = 0, x, piececount = 0;
02135    char *tmp = ast_strdupa(path);
02136    char **pieces;
02137    char *fullpath = ast_alloca(len + 1);
02138    int res = 0;
02139 
02140    for (ptr = tmp; *ptr; ptr++) {
02141       if (*ptr == '/')
02142          count++;
02143    }
02144 
02145    /* Count the components to the directory path */
02146    pieces = ast_alloca(count * sizeof(*pieces));
02147    for (ptr = tmp; *ptr; ptr++) {
02148       if (*ptr == '/') {
02149          *ptr = '\0';
02150          pieces[piececount++] = ptr + 1;
02151       }
02152    }
02153 
02154    *fullpath = '\0';
02155    for (x = 0; x < piececount; x++) {
02156       /* This looks funky, but the buffer is always ideally-sized, so it's fine. */
02157       strcat(fullpath, "/");
02158       strcat(fullpath, pieces[x]);
02159       res = mkdir(fullpath, mode);
02160       if (res && errno != EEXIST)
02161          return errno;
02162    }
02163    return 0;
02164 }
02165 
02166 static void utils_shutdown(void)
02167 {
02168 #ifdef HAVE_DEV_URANDOM
02169    close(dev_urandom_fd);
02170    dev_urandom_fd = -1;
02171 #endif
02172 #if defined(DEBUG_THREADS) && !defined(LOW_MEMORY)
02173    ast_cli_unregister_multiple(utils_cli, ARRAY_LEN(utils_cli));
02174 #endif
02175 }
02176 
02177 int ast_utils_init(void)
02178 {
02179 #ifdef HAVE_DEV_URANDOM
02180    dev_urandom_fd = open("/dev/urandom", O_RDONLY);
02181 #endif
02182    base64_init();
02183 #ifdef DEBUG_THREADS
02184 #if !defined(LOW_MEMORY)
02185    ast_cli_register_multiple(utils_cli, ARRAY_LEN(utils_cli));
02186 #endif
02187 #endif
02188    ast_register_atexit(utils_shutdown);
02189    return 0;
02190 }
02191 
02192 
02193 /*!
02194  *\brief Parse digest authorization header.
02195  *\return Returns -1 if we have no auth or something wrong with digest.
02196  *\note  This function may be used for Digest request and responce header.
02197  * request arg is set to nonzero, if we parse Digest Request.
02198  * pedantic arg can be set to nonzero if we need to do addition Digest check.
02199  */
02200 int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic) {
02201    char *c;
02202    struct ast_str *str = ast_str_create(16);
02203 
02204    /* table of recognised keywords, and places where they should be copied */
02205    const struct x {
02206       const char *key;
02207       const ast_string_field *field;
02208    } *i, keys[] = {
02209       { "username=", &d->username },
02210       { "realm=", &d->realm },
02211       { "nonce=", &d->nonce },
02212       { "uri=", &d->uri },
02213       { "domain=", &d->domain },
02214       { "response=", &d->response },
02215       { "cnonce=", &d->cnonce },
02216       { "opaque=", &d->opaque },
02217       /* Special cases that cannot be directly copied */
02218       { "algorithm=", NULL },
02219       { "qop=", NULL },
02220       { "nc=", NULL },
02221       { NULL, 0 },
02222    };
02223 
02224    if (ast_strlen_zero(digest) || !d || !str) {
02225       ast_free(str);
02226       return -1;
02227    }
02228 
02229    ast_str_set(&str, 0, "%s", digest);
02230 
02231    c = ast_skip_blanks(ast_str_buffer(str));
02232 
02233    if (strncasecmp(c, "Digest ", strlen("Digest "))) {
02234       ast_log(LOG_WARNING, "Missing Digest.\n");
02235       ast_free(str);
02236       return -1;
02237    }
02238    c += strlen("Digest ");
02239 
02240    /* lookup for keys/value pair */
02241    while (c && *c && *(c = ast_skip_blanks(c))) {
02242       /* find key */
02243       for (i = keys; i->key != NULL; i++) {
02244          char *src, *separator;
02245          int unescape = 0;
02246          if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
02247             continue;
02248          }
02249 
02250          /* Found. Skip keyword, take text in quotes or up to the separator. */
02251          c += strlen(i->key);
02252          if (*c == '"') {
02253             src = ++c;
02254             separator = "\"";
02255             unescape = 1;
02256          } else {
02257             src = c;
02258             separator = ",";
02259          }
02260          strsep(&c, separator); /* clear separator and move ptr */
02261          if (unescape) {
02262             ast_unescape_c(src);
02263          }
02264          if (i->field) {
02265             ast_string_field_ptr_set(d, i->field, src);
02266          } else {
02267             /* Special cases that require additional procesing */
02268             if (!strcasecmp(i->key, "algorithm=")) {
02269                if (strcasecmp(src, "MD5")) {
02270                   ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", src);
02271                   ast_free(str);
02272                   return -1;
02273                }
02274             } else if (!strcasecmp(i->key, "qop=") && !strcasecmp(src, "auth")) {
02275                d->qop = 1;
02276             } else if (!strcasecmp(i->key, "nc=")) {
02277                unsigned long u;
02278                if (sscanf(src, "%30lx", &u) != 1) {
02279                   ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", src);
02280                   ast_free(str);
02281                   return -1;
02282                }
02283                ast_string_field_set(d, nc, src);
02284             }
02285          }
02286          break;
02287       }
02288       if (i->key == NULL) { /* not found, try ',' */
02289          strsep(&c, ",");
02290       }
02291    }
02292    ast_free(str);
02293 
02294    /* Digest checkout */
02295    if (ast_strlen_zero(d->realm) || ast_strlen_zero(d->nonce)) {
02296       /* "realm" and "nonce" MUST be always exist */
02297       return -1;
02298    }
02299 
02300    if (!request) {
02301       /* Additional check for Digest response */
02302       if (ast_strlen_zero(d->username) || ast_strlen_zero(d->uri) || ast_strlen_zero(d->response)) {
02303          return -1;
02304       }
02305 
02306       if (pedantic && d->qop && (ast_strlen_zero(d->cnonce) || ast_strlen_zero(d->nc))) {
02307          return -1;
02308       }
02309    }
02310 
02311    return 0;
02312 }
02313 
02314 #ifndef __AST_DEBUG_MALLOC
02315 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...)
02316 {
02317    int res;
02318    va_list ap;
02319 
02320    va_start(ap, fmt);
02321    if ((res = vasprintf(ret, fmt, ap)) == -1) {
02322       MALLOC_FAILURE_MSG;
02323    }
02324    va_end(ap);
02325 
02326    return res;
02327 }
02328 #endif
02329 
02330 int ast_get_tid(void)
02331 {
02332    int ret = -1;
02333 #if defined (__linux) && defined(SYS_gettid)
02334    ret = syscall(SYS_gettid); /* available since Linux 1.4.11 */
02335 #elif defined(__sun)
02336    ret = pthread_self();
02337 #elif defined(__APPLE__)
02338    ret = mach_thread_self();
02339    mach_port_deallocate(mach_task_self(), ret);
02340 #elif defined(__FreeBSD__) && defined(HAVE_SYS_THR_H)
02341    long lwpid;
02342    thr_self(&lwpid); /* available since sys/thr.h creation 2003 */
02343    ret = lwpid;
02344 #endif
02345    return ret;
02346 }
02347 
02348 char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size)
02349 {
02350    const char *envPATH = getenv("PATH");
02351    char *tpath, *path;
02352    struct stat unused;
02353    if (!envPATH) {
02354       return NULL;
02355    }
02356    tpath = ast_strdupa(envPATH);
02357    while ((path = strsep(&tpath, ":"))) {
02358       snprintf(fullpath, fullpath_size, "%s/%s", path, binary);
02359       if (!stat(fullpath, &unused)) {
02360          return fullpath;
02361       }
02362    }
02363    return NULL;
02364 }
02365 
02366 void ast_do_crash(void)
02367 {
02368 #if defined(DO_CRASH)
02369    abort();
02370    /*
02371     * Just in case abort() doesn't work or something else super
02372     * silly, and for Qwell's amusement.
02373     */
02374    *((int *) 0) = 0;
02375 #endif   /* defined(DO_CRASH) */
02376 }
02377 
02378 #if defined(AST_DEVMODE)
02379 void __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function)
02380 {
02381    /*
02382     * Attempt to put it into the logger, but hope that at least
02383     * someone saw the message on stderr ...
02384     */
02385    ast_log(__LOG_ERROR, file, line, function, "FRACK!, Failed assertion %s (%d)\n",
02386       condition_str, condition);
02387    fprintf(stderr, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
02388       condition_str, condition, line, function, file);
02389    /*
02390     * Give the logger a chance to get the message out, just in case
02391     * we abort(), or Asterisk crashes due to whatever problem just
02392     * happened after we exit ast_assert().
02393     */
02394    usleep(1);
02395    ast_do_crash();
02396 }
02397 #endif   /* defined(AST_DEVMODE) */