Sat Jul 12 2014 17:18:38

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