Tue Aug 20 16:34:39 2013

Asterisk developer's documentation


utils.c

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

Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1