Wed Nov 28 2012 04:18:17

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: 371690 $")
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 /*! \brief  ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
00471 const char *ast_inet_ntoa(struct in_addr ia)
00472 {
00473    char *buf;
00474 
00475    if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
00476       return "";
00477 
00478    return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
00479 }
00480 
00481 #ifdef HAVE_DEV_URANDOM
00482 static int dev_urandom_fd;
00483 #endif
00484 
00485 #ifndef __linux__
00486 #undef pthread_create /* For ast_pthread_create function only */
00487 #endif /* !__linux__ */
00488 
00489 #if !defined(LOW_MEMORY)
00490 
00491 #ifdef DEBUG_THREADS
00492 
00493 /*! \brief A reasonable maximum number of locks a thread would be holding ... */
00494 #define AST_MAX_LOCKS 64
00495 
00496 /* Allow direct use of pthread_mutex_t and friends */
00497 #undef pthread_mutex_t
00498 #undef pthread_mutex_lock
00499 #undef pthread_mutex_unlock
00500 #undef pthread_mutex_init
00501 #undef pthread_mutex_destroy
00502 
00503 /*! 
00504  * \brief Keep track of which locks a thread holds 
00505  *
00506  * There is an instance of this struct for every active thread
00507  */
00508 struct thr_lock_info {
00509    /*! The thread's ID */
00510    pthread_t thread_id;
00511    /*! The thread name which includes where the thread was started */
00512    const char *thread_name;
00513    /*! This is the actual container of info for what locks this thread holds */
00514    struct {
00515       const char *file;
00516       int line_num;
00517       const char *func;
00518       const char *lock_name;
00519       void *lock_addr;
00520       int times_locked;
00521       enum ast_lock_type type;
00522       /*! This thread is waiting on this lock */
00523       int pending:2;
00524 #ifdef HAVE_BKTR
00525       struct ast_bt *backtrace;
00526 #endif
00527    } locks[AST_MAX_LOCKS];
00528    /*! This is the number of locks currently held by this thread.
00529     *  The index (num_locks - 1) has the info on the last one in the
00530     *  locks member */
00531    unsigned int num_locks;
00532    /*! Protects the contents of the locks member 
00533     * Intentionally not ast_mutex_t */
00534    pthread_mutex_t lock;
00535    AST_LIST_ENTRY(thr_lock_info) entry;
00536 };
00537 
00538 /*! 
00539  * \brief Locked when accessing the lock_infos list 
00540  */
00541 AST_MUTEX_DEFINE_STATIC(lock_infos_lock);
00542 /*!
00543  * \brief A list of each thread's lock info 
00544  */
00545 static AST_LIST_HEAD_NOLOCK_STATIC(lock_infos, thr_lock_info);
00546 
00547 /*!
00548  * \brief Destroy a thread's lock info
00549  *
00550  * This gets called automatically when the thread stops
00551  */
00552 static void lock_info_destroy(void *data)
00553 {
00554    struct thr_lock_info *lock_info = data;
00555    int i;
00556 
00557    pthread_mutex_lock(&lock_infos_lock.mutex);
00558    AST_LIST_REMOVE(&lock_infos, lock_info, entry);
00559    pthread_mutex_unlock(&lock_infos_lock.mutex);
00560 
00561 
00562    for (i = 0; i < lock_info->num_locks; i++) {
00563       if (lock_info->locks[i].pending == -1) {
00564          /* This just means that the last lock this thread went for was by
00565           * using trylock, and it failed.  This is fine. */
00566          break;
00567       }
00568 
00569       ast_log(LOG_ERROR, 
00570          "Thread '%s' still has a lock! - '%s' (%p) from '%s' in %s:%d!\n", 
00571          lock_info->thread_name,
00572          lock_info->locks[i].lock_name,
00573          lock_info->locks[i].lock_addr,
00574          lock_info->locks[i].func,
00575          lock_info->locks[i].file,
00576          lock_info->locks[i].line_num
00577       );
00578    }
00579 
00580    pthread_mutex_destroy(&lock_info->lock);
00581    if (lock_info->thread_name)
00582       free((void *) lock_info->thread_name);
00583    free(lock_info);
00584 }
00585 
00586 /*!
00587  * \brief The thread storage key for per-thread lock info
00588  */
00589 AST_THREADSTORAGE_CUSTOM(thread_lock_info, NULL, lock_info_destroy);
00590 #ifdef HAVE_BKTR
00591 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
00592    int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
00593 #else
00594 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
00595    int line_num, const char *func, const char *lock_name, void *lock_addr)
00596 #endif
00597 {
00598    struct thr_lock_info *lock_info;
00599    int i;
00600 
00601    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00602       return;
00603 
00604    pthread_mutex_lock(&lock_info->lock);
00605 
00606    for (i = 0; i < lock_info->num_locks; i++) {
00607       if (lock_info->locks[i].lock_addr == lock_addr) {
00608          lock_info->locks[i].times_locked++;
00609 #ifdef HAVE_BKTR
00610          lock_info->locks[i].backtrace = bt;
00611 #endif
00612          pthread_mutex_unlock(&lock_info->lock);
00613          return;
00614       }
00615    }
00616 
00617    if (lock_info->num_locks == AST_MAX_LOCKS) {
00618       /* Can't use ast_log here, because it will cause infinite recursion */
00619       fprintf(stderr, "XXX ERROR XXX A thread holds more locks than '%d'."
00620          "  Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
00621       pthread_mutex_unlock(&lock_info->lock);
00622       return;
00623    }
00624 
00625    if (i && lock_info->locks[i - 1].pending == -1) {
00626       /* The last lock on the list was one that this thread tried to lock but
00627        * failed at doing so.  It has now moved on to something else, so remove
00628        * the old lock from the list. */
00629       i--;
00630       lock_info->num_locks--;
00631       memset(&lock_info->locks[i], 0, sizeof(lock_info->locks[0]));
00632    }
00633 
00634    lock_info->locks[i].file = filename;
00635    lock_info->locks[i].line_num = line_num;
00636    lock_info->locks[i].func = func;
00637    lock_info->locks[i].lock_name = lock_name;
00638    lock_info->locks[i].lock_addr = lock_addr;
00639    lock_info->locks[i].times_locked = 1;
00640    lock_info->locks[i].type = type;
00641    lock_info->locks[i].pending = 1;
00642 #ifdef HAVE_BKTR
00643    lock_info->locks[i].backtrace = bt;
00644 #endif
00645    lock_info->num_locks++;
00646 
00647    pthread_mutex_unlock(&lock_info->lock);
00648 }
00649 
00650 void ast_mark_lock_acquired(void *lock_addr)
00651 {
00652    struct thr_lock_info *lock_info;
00653 
00654    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00655       return;
00656 
00657    pthread_mutex_lock(&lock_info->lock);
00658    if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
00659       lock_info->locks[lock_info->num_locks - 1].pending = 0;
00660    }
00661    pthread_mutex_unlock(&lock_info->lock);
00662 }
00663 
00664 void ast_mark_lock_failed(void *lock_addr)
00665 {
00666    struct thr_lock_info *lock_info;
00667 
00668    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00669       return;
00670 
00671    pthread_mutex_lock(&lock_info->lock);
00672    if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
00673       lock_info->locks[lock_info->num_locks - 1].pending = -1;
00674       lock_info->locks[lock_info->num_locks - 1].times_locked--;
00675    }
00676    pthread_mutex_unlock(&lock_info->lock);
00677 }
00678 
00679 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)
00680 {
00681    struct thr_lock_info *lock_info;
00682    int i = 0;
00683 
00684    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00685       return -1;
00686 
00687    pthread_mutex_lock(&lock_info->lock);
00688 
00689    for (i = lock_info->num_locks - 1; i >= 0; i--) {
00690       if (lock_info->locks[i].lock_addr == lock_addr)
00691          break;
00692    }
00693 
00694    if (i == -1) {
00695       /* Lock not found :( */
00696       pthread_mutex_unlock(&lock_info->lock);
00697       return -1;
00698    }
00699 
00700    ast_copy_string(filename, lock_info->locks[i].file, filename_size);
00701    *lineno = lock_info->locks[i].line_num;
00702    ast_copy_string(func, lock_info->locks[i].func, func_size);
00703    ast_copy_string(mutex_name, lock_info->locks[i].lock_name, mutex_name_size);
00704 
00705    pthread_mutex_unlock(&lock_info->lock);
00706 
00707    return 0;
00708 }
00709 
00710 #ifdef HAVE_BKTR
00711 void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt)
00712 #else
00713 void ast_remove_lock_info(void *lock_addr)
00714 #endif
00715 {
00716    struct thr_lock_info *lock_info;
00717    int i = 0;
00718 
00719    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00720       return;
00721 
00722    pthread_mutex_lock(&lock_info->lock);
00723 
00724    for (i = lock_info->num_locks - 1; i >= 0; i--) {
00725       if (lock_info->locks[i].lock_addr == lock_addr)
00726          break;
00727    }
00728 
00729    if (i == -1) {
00730       /* Lock not found :( */
00731       pthread_mutex_unlock(&lock_info->lock);
00732       return;
00733    }
00734 
00735    if (lock_info->locks[i].times_locked > 1) {
00736       lock_info->locks[i].times_locked--;
00737 #ifdef HAVE_BKTR
00738       lock_info->locks[i].backtrace = bt;
00739 #endif
00740       pthread_mutex_unlock(&lock_info->lock);
00741       return;
00742    }
00743 
00744    if (i < lock_info->num_locks - 1) {
00745       /* Not the last one ... *should* be rare! */
00746       memmove(&lock_info->locks[i], &lock_info->locks[i + 1], 
00747          (lock_info->num_locks - (i + 1)) * sizeof(lock_info->locks[0]));
00748    }
00749 
00750    lock_info->num_locks--;
00751 
00752    pthread_mutex_unlock(&lock_info->lock);
00753 }
00754 
00755 static const char *locktype2str(enum ast_lock_type type)
00756 {
00757    switch (type) {
00758    case AST_MUTEX:
00759       return "MUTEX";
00760    case AST_RDLOCK:
00761       return "RDLOCK";
00762    case AST_WRLOCK:
00763       return "WRLOCK";
00764    }
00765 
00766    return "UNKNOWN";
00767 }
00768 
00769 #ifdef HAVE_BKTR
00770 static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt)
00771 {
00772    char **symbols;
00773    int num_frames;
00774 
00775    if (!bt) {
00776       ast_str_append(str, 0, "\tNo backtrace to print\n");
00777       return;
00778    }
00779 
00780    /* store frame count locally to avoid the memory corruption that
00781     * sometimes happens on virtualized CentOS 6.x systems */
00782    num_frames = bt->num_frames;
00783    if ((symbols = ast_bt_get_symbols(bt->addresses, num_frames))) {
00784       int frame_iterator;
00785       
00786       for (frame_iterator = 0; frame_iterator < num_frames; ++frame_iterator) {
00787          ast_str_append(str, 0, "\t%s\n", symbols[frame_iterator]);
00788       }
00789 
00790       free(symbols);
00791    } else {
00792       ast_str_append(str, 0, "\tCouldn't retrieve backtrace symbols\n");
00793    }
00794 }
00795 #endif
00796 
00797 static void append_lock_information(struct ast_str **str, struct thr_lock_info *lock_info, int i)
00798 {
00799    int j;
00800    ast_mutex_t *lock;
00801    struct ast_lock_track *lt;
00802    
00803    ast_str_append(str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d)\n", 
00804                lock_info->locks[i].pending > 0 ? "Waiting for " : 
00805                lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
00806                lock_info->locks[i].file, 
00807                locktype2str(lock_info->locks[i].type),
00808                lock_info->locks[i].line_num,
00809                lock_info->locks[i].func, lock_info->locks[i].lock_name,
00810                lock_info->locks[i].lock_addr, 
00811                lock_info->locks[i].times_locked);
00812 #ifdef HAVE_BKTR
00813    append_backtrace_information(str, lock_info->locks[i].backtrace);
00814 #endif
00815    
00816    if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
00817       return;
00818    
00819    /* We only have further details for mutexes right now */
00820    if (lock_info->locks[i].type != AST_MUTEX)
00821       return;
00822    
00823    lock = lock_info->locks[i].lock_addr;
00824    lt = lock->track;
00825    ast_reentrancy_lock(lt);
00826    for (j = 0; *str && j < lt->reentrancy; j++) {
00827       ast_str_append(str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n",
00828                   lt->file[j], lt->lineno[j], lt->func[j]);
00829    }
00830    ast_reentrancy_unlock(lt); 
00831 }
00832 
00833 
00834 /*! This function can help you find highly temporal locks; locks that happen for a 
00835     short time, but at unexpected times, usually at times that create a deadlock,
00836    Why is this thing locked right then? Who is locking it? Who am I fighting
00837     with for this lock? 
00838 
00839    To answer such questions, just call this routine before you would normally try
00840    to aquire a lock. It doesn't do anything if the lock is not acquired. If the
00841    lock is taken, it will publish a line or two to the console via ast_log().
00842 
00843    Sometimes, the lock message is pretty uninformative. For instance, you might
00844    find that the lock is being aquired deep within the astobj2 code; this tells
00845    you little about higher level routines that call the astobj2 routines.
00846    But, using gdb, you can set a break at the ast_log below, and for that
00847    breakpoint, you can set the commands:
00848      where
00849      cont
00850    which will give a stack trace and continue. -- that aught to do the job!
00851 
00852 */
00853 void log_show_lock(void *this_lock_addr)
00854 {
00855    struct thr_lock_info *lock_info;
00856    struct ast_str *str;
00857 
00858    if (!(str = ast_str_create(4096))) {
00859       ast_log(LOG_NOTICE,"Could not create str\n");
00860       return;
00861    }
00862    
00863 
00864    pthread_mutex_lock(&lock_infos_lock.mutex);
00865    AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
00866       int i;
00867       pthread_mutex_lock(&lock_info->lock);
00868       for (i = 0; str && i < lock_info->num_locks; i++) {
00869          /* ONLY show info about this particular lock, if
00870             it's acquired... */
00871          if (lock_info->locks[i].lock_addr == this_lock_addr) {
00872             append_lock_information(&str, lock_info, i);
00873             ast_log(LOG_NOTICE, "%s", ast_str_buffer(str));
00874             break;
00875          }
00876       }
00877       pthread_mutex_unlock(&lock_info->lock);
00878    }
00879    pthread_mutex_unlock(&lock_infos_lock.mutex);
00880    ast_free(str);
00881 }
00882 
00883 
00884 static char *handle_show_locks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
00885 {
00886    struct thr_lock_info *lock_info;
00887    struct ast_str *str;
00888 
00889    if (!(str = ast_str_create(4096)))
00890       return CLI_FAILURE;
00891 
00892    switch (cmd) {
00893    case CLI_INIT:
00894       e->command = "core show locks";
00895       e->usage =
00896          "Usage: core show locks\n"
00897          "       This command is for lock debugging.  It prints out which locks\n"
00898          "are owned by each active thread.\n";
00899       return NULL;
00900 
00901    case CLI_GENERATE:
00902       return NULL;
00903    }
00904 
00905    ast_str_append(&str, 0, "\n" 
00906                   "=======================================================================\n"
00907                   "=== Currently Held Locks ==============================================\n"
00908                   "=======================================================================\n"
00909                   "===\n"
00910                   "=== <pending> <lock#> (<file>): <lock type> <line num> <function> <lock name> <lock addr> (times locked)\n"
00911                   "===\n");
00912 
00913    if (!str)
00914       return CLI_FAILURE;
00915 
00916    pthread_mutex_lock(&lock_infos_lock.mutex);
00917    AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
00918       int i;
00919       if (lock_info->num_locks) {
00920          ast_str_append(&str, 0, "=== Thread ID: 0x%lx (%s)\n", (long) lock_info->thread_id,
00921             lock_info->thread_name);
00922          pthread_mutex_lock(&lock_info->lock);
00923          for (i = 0; str && i < lock_info->num_locks; i++) {
00924             append_lock_information(&str, lock_info, i);
00925          }
00926          pthread_mutex_unlock(&lock_info->lock);
00927          if (!str)
00928             break;
00929          ast_str_append(&str, 0, "=== -------------------------------------------------------------------\n"
00930                         "===\n");
00931          if (!str)
00932             break;
00933       }
00934    }
00935    pthread_mutex_unlock(&lock_infos_lock.mutex);
00936 
00937    if (!str)
00938       return CLI_FAILURE;
00939 
00940    ast_str_append(&str, 0, "=======================================================================\n"
00941                   "\n");
00942 
00943    if (!str)
00944       return CLI_FAILURE;
00945 
00946    ast_cli(a->fd, "%s", ast_str_buffer(str));
00947 
00948    ast_free(str);
00949 
00950    return CLI_SUCCESS;
00951 }
00952 
00953 static struct ast_cli_entry utils_cli[] = {
00954    AST_CLI_DEFINE(handle_show_locks, "Show which locks are held by which thread"),
00955 };
00956 
00957 #endif /* DEBUG_THREADS */
00958 
00959 /*
00960  * support for 'show threads'. The start routine is wrapped by
00961  * dummy_start(), so that ast_register_thread() and
00962  * ast_unregister_thread() know the thread identifier.
00963  */
00964 struct thr_arg {
00965    void *(*start_routine)(void *);
00966    void *data;
00967    char *name;
00968 };
00969 
00970 /*
00971  * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
00972  * are odd macros which start and end a block, so they _must_ be
00973  * used in pairs (the latter with a '1' argument to call the
00974  * handler on exit.
00975  * On BSD we don't need this, but we keep it for compatibility.
00976  */
00977 static void *dummy_start(void *data)
00978 {
00979    void *ret;
00980    struct thr_arg a = *((struct thr_arg *) data);  /* make a local copy */
00981 #ifdef DEBUG_THREADS
00982    struct thr_lock_info *lock_info;
00983    pthread_mutexattr_t mutex_attr;
00984 #endif
00985 
00986    /* note that even though data->name is a pointer to allocated memory,
00987       we are not freeing it here because ast_register_thread is going to
00988       keep a copy of the pointer and then ast_unregister_thread will
00989       free the memory
00990    */
00991    ast_free(data);
00992    ast_register_thread(a.name);
00993    pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());
00994 
00995 #ifdef DEBUG_THREADS
00996    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00997       return NULL;
00998 
00999    lock_info->thread_id = pthread_self();
01000    lock_info->thread_name = strdup(a.name);
01001 
01002    pthread_mutexattr_init(&mutex_attr);
01003    pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND);
01004    pthread_mutex_init(&lock_info->lock, &mutex_attr);
01005    pthread_mutexattr_destroy(&mutex_attr);
01006 
01007    pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
01008    AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry);
01009    pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
01010 #endif /* DEBUG_THREADS */
01011 
01012    ret = a.start_routine(a.data);
01013 
01014    pthread_cleanup_pop(1);
01015 
01016    return ret;
01017 }
01018 
01019 #endif /* !LOW_MEMORY */
01020 
01021 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
01022               void *data, size_t stacksize, const char *file, const char *caller,
01023               int line, const char *start_fn)
01024 {
01025 #if !defined(LOW_MEMORY)
01026    struct thr_arg *a;
01027 #endif
01028 
01029    if (!attr) {
01030       attr = ast_alloca(sizeof(*attr));
01031       pthread_attr_init(attr);
01032    }
01033 
01034 #ifdef __linux__
01035    /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
01036       which is kind of useless. Change this here to
01037       PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
01038       priority will propagate down to new threads by default.
01039       This does mean that callers cannot set a different priority using
01040       PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
01041       the priority afterwards with pthread_setschedparam(). */
01042    if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
01043       ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
01044 #endif
01045 
01046    if (!stacksize)
01047       stacksize = AST_STACKSIZE;
01048 
01049    if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
01050       ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));
01051 
01052 #if !defined(LOW_MEMORY)
01053    if ((a = ast_malloc(sizeof(*a)))) {
01054       a->start_routine = start_routine;
01055       a->data = data;
01056       start_routine = dummy_start;
01057       if (ast_asprintf(&a->name, "%-20s started at [%5d] %s %s()",
01058               start_fn, line, file, caller) < 0) {
01059          a->name = NULL;
01060       }
01061       data = a;
01062    }
01063 #endif /* !LOW_MEMORY */
01064 
01065    return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
01066 }
01067 
01068 
01069 int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
01070               void *data, size_t stacksize, const char *file, const char *caller,
01071               int line, const char *start_fn)
01072 {
01073    unsigned char attr_destroy = 0;
01074    int res;
01075 
01076    if (!attr) {
01077       attr = ast_alloca(sizeof(*attr));
01078       pthread_attr_init(attr);
01079       attr_destroy = 1;
01080    }
01081 
01082    if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
01083       ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno));
01084 
01085    res = ast_pthread_create_stack(thread, attr, start_routine, data, 
01086                                   stacksize, file, caller, line, start_fn);
01087 
01088    if (attr_destroy)
01089       pthread_attr_destroy(attr);
01090 
01091    return res;
01092 }
01093 
01094 int ast_wait_for_input(int fd, int ms)
01095 {
01096    struct pollfd pfd[1];
01097    memset(pfd, 0, sizeof(pfd));
01098    pfd[0].fd = fd;
01099    pfd[0].events = POLLIN|POLLPRI;
01100    return ast_poll(pfd, 1, ms);
01101 }
01102 
01103 static int ast_wait_for_output(int fd, int timeoutms)
01104 {
01105    struct pollfd pfd = {
01106       .fd = fd,
01107       .events = POLLOUT,
01108    };
01109    int res;
01110    struct timeval start = ast_tvnow();
01111    int elapsed = 0;
01112 
01113    /* poll() until the fd is writable without blocking */
01114    while ((res = ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
01115       if (res == 0) {
01116          /* timed out. */
01117 #ifndef STANDALONE
01118          ast_debug(1, "Timed out trying to write\n");
01119 #endif
01120          return -1;
01121       } else if (res == -1) {
01122          /* poll() returned an error, check to see if it was fatal */
01123 
01124          if (errno == EINTR || errno == EAGAIN) {
01125             elapsed = ast_tvdiff_ms(ast_tvnow(), start);
01126             if (elapsed >= timeoutms) {
01127                return -1;
01128             }
01129             /* This was an acceptable error, go back into poll() */
01130             continue;
01131          }
01132 
01133          /* Fatal error, bail. */
01134          ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno));
01135 
01136          return -1;
01137       }
01138       elapsed = ast_tvdiff_ms(ast_tvnow(), start);
01139       if (elapsed >= timeoutms) {
01140          return -1;
01141       }
01142    }
01143 
01144    return 0;
01145 }
01146 
01147 /*!
01148  * Try to write string, but wait no more than ms milliseconds before timing out.
01149  *
01150  * \note The code assumes that the file descriptor has NONBLOCK set,
01151  * so there is only one system call made to do a write, unless we actually
01152  * have a need to wait.  This way, we get better performance.
01153  * If the descriptor is blocking, all assumptions on the guaranteed
01154  * detail do not apply anymore.
01155  */
01156 int ast_carefulwrite(int fd, char *s, int len, int timeoutms) 
01157 {
01158    struct timeval start = ast_tvnow();
01159    int res = 0;
01160    int elapsed = 0;
01161 
01162    while (len) {
01163       if (ast_wait_for_output(fd, timeoutms - elapsed)) {
01164          return -1;
01165       }
01166 
01167       res = write(fd, s, len);
01168 
01169       if (res < 0 && errno != EAGAIN && errno != EINTR) {
01170          /* fatal error from write() */
01171          ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
01172          return -1;
01173       }
01174 
01175       if (res < 0) {
01176          /* It was an acceptable error */
01177          res = 0;
01178       }
01179 
01180       /* Update how much data we have left to write */
01181       len -= res;
01182       s += res;
01183       res = 0;
01184 
01185       elapsed = ast_tvdiff_ms(ast_tvnow(), start);
01186       if (elapsed >= timeoutms) {
01187          /* We've taken too long to write 
01188           * This is only an error condition if we haven't finished writing. */
01189          res = len ? -1 : 0;
01190          break;
01191       }
01192    }
01193 
01194    return res;
01195 }
01196 
01197 int ast_careful_fwrite(FILE *f, int fd, const char *src, size_t len, int timeoutms)
01198 {
01199    struct timeval start = ast_tvnow();
01200    int n = 0;
01201    int elapsed = 0;
01202 
01203    while (len) {
01204       if (ast_wait_for_output(fd, timeoutms - elapsed)) {
01205          /* poll returned a fatal error, so bail out immediately. */
01206          return -1;
01207       }
01208 
01209       /* Clear any errors from a previous write */
01210       clearerr(f);
01211 
01212       n = fwrite(src, 1, len, f);
01213 
01214       if (ferror(f) && errno != EINTR && errno != EAGAIN) {
01215          /* fatal error from fwrite() */
01216          if (!feof(f)) {
01217             /* Don't spam the logs if it was just that the connection is closed. */
01218             ast_log(LOG_ERROR, "fwrite() returned error: %s\n", strerror(errno));
01219          }
01220          n = -1;
01221          break;
01222       }
01223 
01224       /* Update for data already written to the socket */
01225       len -= n;
01226       src += n;
01227 
01228       elapsed = ast_tvdiff_ms(ast_tvnow(), start);
01229       if (elapsed >= timeoutms) {
01230          /* We've taken too long to write 
01231           * This is only an error condition if we haven't finished writing. */
01232          n = len ? -1 : 0;
01233          break;
01234       }
01235    }
01236 
01237    while (fflush(f)) {
01238       if (errno == EAGAIN || errno == EINTR) {
01239          continue;
01240       }
01241       if (!feof(f)) {
01242          /* Don't spam the logs if it was just that the connection is closed. */
01243          ast_log(LOG_ERROR, "fflush() returned error: %s\n", strerror(errno));
01244       }
01245       n = -1;
01246       break;
01247    }
01248 
01249    return n < 0 ? -1 : 0;
01250 }
01251 
01252 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
01253 {
01254    char *e;
01255    char *q;
01256 
01257    s = ast_strip(s);
01258    if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
01259       e = s + strlen(s) - 1;
01260       if (*e == *(end_quotes + (q - beg_quotes))) {
01261          s++;
01262          *e = '\0';
01263       }
01264    }
01265 
01266    return s;
01267 }
01268 
01269 char *ast_unescape_semicolon(char *s)
01270 {
01271    char *e;
01272    char *work = s;
01273 
01274    while ((e = strchr(work, ';'))) {
01275       if ((e > work) && (*(e-1) == '\\')) {
01276          memmove(e - 1, e, strlen(e) + 1);
01277          work = e;
01278       } else {
01279          work = e + 1;
01280       }
01281    }
01282 
01283    return s;
01284 }
01285 
01286 /* !\brief unescape some C sequences in place, return pointer to the original string.
01287  */
01288 char *ast_unescape_c(char *src)
01289 {
01290    char c, *ret, *dst;
01291 
01292    if (src == NULL)
01293       return NULL;
01294    for (ret = dst = src; (c = *src++); *dst++ = c ) {
01295       if (c != '\\')
01296          continue;   /* copy char at the end of the loop */
01297       switch ((c = *src++)) {
01298       case '\0':  /* special, trailing '\' */
01299          c = '\\';
01300          break;
01301       case 'b':   /* backspace */
01302          c = '\b';
01303          break;
01304       case 'f':   /* form feed */
01305          c = '\f';
01306          break;
01307       case 'n':
01308          c = '\n';
01309          break;
01310       case 'r':
01311          c = '\r';
01312          break;
01313       case 't':
01314          c = '\t';
01315          break;
01316       }
01317       /* default, use the char literally */
01318    }
01319    *dst = '\0';
01320    return ret;
01321 }
01322 
01323 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
01324 {
01325    int result;
01326 
01327    if (!buffer || !*buffer || !space || !*space)
01328       return -1;
01329 
01330    result = vsnprintf(*buffer, *space, fmt, ap);
01331 
01332    if (result < 0)
01333       return -1;
01334    else if (result > *space)
01335       result = *space;
01336 
01337    *buffer += result;
01338    *space -= result;
01339    return 0;
01340 }
01341 
01342 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
01343 {
01344    va_list ap;
01345    int result;
01346 
01347    va_start(ap, fmt);
01348    result = ast_build_string_va(buffer, space, fmt, ap);
01349    va_end(ap);
01350 
01351    return result;
01352 }
01353 
01354 int ast_true(const char *s)
01355 {
01356    if (ast_strlen_zero(s))
01357       return 0;
01358 
01359    /* Determine if this is a true value */
01360    if (!strcasecmp(s, "yes") ||
01361        !strcasecmp(s, "true") ||
01362        !strcasecmp(s, "y") ||
01363        !strcasecmp(s, "t") ||
01364        !strcasecmp(s, "1") ||
01365        !strcasecmp(s, "on"))
01366       return -1;
01367 
01368    return 0;
01369 }
01370 
01371 int ast_false(const char *s)
01372 {
01373    if (ast_strlen_zero(s))
01374       return 0;
01375 
01376    /* Determine if this is a false value */
01377    if (!strcasecmp(s, "no") ||
01378        !strcasecmp(s, "false") ||
01379        !strcasecmp(s, "n") ||
01380        !strcasecmp(s, "f") ||
01381        !strcasecmp(s, "0") ||
01382        !strcasecmp(s, "off"))
01383       return -1;
01384 
01385    return 0;
01386 }
01387 
01388 #define ONE_MILLION  1000000
01389 /*
01390  * put timeval in a valid range. usec is 0..999999
01391  * negative values are not allowed and truncated.
01392  */
01393 static struct timeval tvfix(struct timeval a)
01394 {
01395    if (a.tv_usec >= ONE_MILLION) {
01396       ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
01397          (long)a.tv_sec, (long int) a.tv_usec);
01398       a.tv_sec += a.tv_usec / ONE_MILLION;
01399       a.tv_usec %= ONE_MILLION;
01400    } else if (a.tv_usec < 0) {
01401       ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
01402          (long)a.tv_sec, (long int) a.tv_usec);
01403       a.tv_usec = 0;
01404    }
01405    return a;
01406 }
01407 
01408 struct timeval ast_tvadd(struct timeval a, struct timeval b)
01409 {
01410    /* consistency checks to guarantee usec in 0..999999 */
01411    a = tvfix(a);
01412    b = tvfix(b);
01413    a.tv_sec += b.tv_sec;
01414    a.tv_usec += b.tv_usec;
01415    if (a.tv_usec >= ONE_MILLION) {
01416       a.tv_sec++;
01417       a.tv_usec -= ONE_MILLION;
01418    }
01419    return a;
01420 }
01421 
01422 struct timeval ast_tvsub(struct timeval a, struct timeval b)
01423 {
01424    /* consistency checks to guarantee usec in 0..999999 */
01425    a = tvfix(a);
01426    b = tvfix(b);
01427    a.tv_sec -= b.tv_sec;
01428    a.tv_usec -= b.tv_usec;
01429    if (a.tv_usec < 0) {
01430       a.tv_sec-- ;
01431       a.tv_usec += ONE_MILLION;
01432    }
01433    return a;
01434 }
01435 #undef ONE_MILLION
01436 
01437 /*! \brief glibc puts a lock inside random(3), so that the results are thread-safe.
01438  * BSD libc (and others) do not. */
01439 
01440 #ifndef linux
01441 AST_MUTEX_DEFINE_STATIC(randomlock);
01442 #endif
01443 
01444 long int ast_random(void)
01445 {
01446    long int res;
01447 #ifdef HAVE_DEV_URANDOM
01448    if (dev_urandom_fd >= 0) {
01449       int read_res = read(dev_urandom_fd, &res, sizeof(res));
01450       if (read_res > 0) {
01451          long int rm = RAND_MAX;
01452          res = res < 0 ? ~res : res;
01453          rm++;
01454          return res % rm;
01455       }
01456    }
01457 #endif
01458 #ifdef linux
01459    res = random();
01460 #else
01461    ast_mutex_lock(&randomlock);
01462    res = random();
01463    ast_mutex_unlock(&randomlock);
01464 #endif
01465    return res;
01466 }
01467 
01468 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
01469 {
01470    char *dataPut = start;
01471    int inEscape = 0;
01472    int inQuotes = 0;
01473 
01474    for (; *start; start++) {
01475       if (inEscape) {
01476          *dataPut++ = *start;       /* Always goes verbatim */
01477          inEscape = 0;
01478       } else {
01479          if (*start == '\\') {
01480             inEscape = 1;      /* Do not copy \ into the data */
01481          } else if (*start == '\'') {
01482             inQuotes = 1 - inQuotes;   /* Do not copy ' into the data */
01483          } else {
01484             /* Replace , with |, unless in quotes */
01485             *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
01486          }
01487       }
01488    }
01489    if (start != dataPut)
01490       *dataPut = 0;
01491    return dataPut;
01492 }
01493 
01494 void ast_join(char *s, size_t len, const char * const w[])
01495 {
01496    int x, ofs = 0;
01497    const char *src;
01498 
01499    /* Join words into a string */
01500    if (!s)
01501       return;
01502    for (x = 0; ofs < len && w[x]; x++) {
01503       if (x > 0)
01504          s[ofs++] = ' ';
01505       for (src = w[x]; *src && ofs < len; src++)
01506          s[ofs++] = *src;
01507    }
01508    if (ofs == len)
01509       ofs--;
01510    s[ofs] = '\0';
01511 }
01512 
01513 /*
01514  * stringfields support routines.
01515  */
01516 
01517 /* this is a little complex... string fields are stored with their
01518    allocated size in the bytes preceding the string; even the
01519    constant 'empty' string has to be this way, so the code that
01520    checks to see if there is enough room for a new string doesn't
01521    have to have any special case checks
01522 */
01523 
01524 static const struct {
01525    ast_string_field_allocation allocation;
01526    char string[1];
01527 } __ast_string_field_empty_buffer;
01528 
01529 ast_string_field __ast_string_field_empty = __ast_string_field_empty_buffer.string;
01530 
01531 #define ALLOCATOR_OVERHEAD 48
01532 
01533 static size_t optimal_alloc_size(size_t size)
01534 {
01535    unsigned int count;
01536 
01537    size += ALLOCATOR_OVERHEAD;
01538 
01539    for (count = 1; size; size >>= 1, count++);
01540 
01541    return (1 << count) - ALLOCATOR_OVERHEAD;
01542 }
01543 
01544 /*! \brief add a new block to the pool.
01545  * We can only allocate from the topmost pool, so the
01546  * fields in *mgr reflect the size of that only.
01547  */
01548 static int add_string_pool(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
01549             size_t size, const char *file, int lineno, const char *func)
01550 {
01551    struct ast_string_field_pool *pool;
01552    size_t alloc_size = optimal_alloc_size(sizeof(*pool) + size);
01553 
01554 #if defined(__AST_DEBUG_MALLOC)
01555    if (!(pool = __ast_calloc(1, alloc_size, file, lineno, func))) {
01556       return -1;
01557    }
01558 #else
01559    if (!(pool = ast_calloc(1, alloc_size))) {
01560       return -1;
01561    }
01562 #endif
01563 
01564    pool->prev = *pool_head;
01565    pool->size = alloc_size - sizeof(*pool);
01566    *pool_head = pool;
01567    mgr->last_alloc = NULL;
01568 
01569    return 0;
01570 }
01571 
01572 /*
01573  * This is an internal API, code should not use it directly.
01574  * It initializes all fields as empty, then uses 'size' for 3 functions:
01575  * size > 0 means initialize the pool list with a pool of given size.
01576  * This must be called right after allocating the object.
01577  * size = 0 means release all pools except the most recent one.
01578  *      If the first pool was allocated via embedding in another
01579  *      object, that pool will be preserved instead.
01580  * This is useful to e.g. reset an object to the initial value.
01581  * size < 0 means release all pools.
01582  * This must be done before destroying the object.
01583  */
01584 int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
01585              int needed, const char *file, int lineno, const char *func)
01586 {
01587    const char **p = (const char **) pool_head + 1;
01588    struct ast_string_field_pool *cur = NULL;
01589    struct ast_string_field_pool *preserve = NULL;
01590 
01591    /* clear fields - this is always necessary */
01592    while ((struct ast_string_field_mgr *) p != mgr) {
01593       *p++ = __ast_string_field_empty;
01594    }
01595 
01596    mgr->last_alloc = NULL;
01597 #if defined(__AST_DEBUG_MALLOC)
01598    mgr->owner_file = file;
01599    mgr->owner_func = func;
01600    mgr->owner_line = lineno;
01601 #endif
01602    if (needed > 0) {    /* allocate the initial pool */
01603       *pool_head = NULL;
01604       mgr->embedded_pool = NULL;
01605       return add_string_pool(mgr, pool_head, needed, file, lineno, func);
01606    }
01607 
01608    /* if there is an embedded pool, we can't actually release *all*
01609     * pools, we must keep the embedded one. if the caller is about
01610     * to free the structure that contains the stringfield manager
01611     * and embedded pool anyway, it will be freed as part of that
01612     * operation.
01613     */
01614    if ((needed < 0) && mgr->embedded_pool) {
01615       needed = 0;
01616    }
01617 
01618    if (needed < 0) {    /* reset all pools */
01619       cur = *pool_head;
01620    } else if (mgr->embedded_pool) { /* preserve the embedded pool */
01621       preserve = mgr->embedded_pool;
01622       cur = *pool_head;
01623    } else {       /* preserve the last pool */
01624       if (*pool_head == NULL) {
01625          ast_log(LOG_WARNING, "trying to reset empty pool\n");
01626          return -1;
01627       }
01628       preserve = *pool_head;
01629       cur = preserve->prev;
01630    }
01631 
01632    if (preserve) {
01633       preserve->prev = NULL;
01634       preserve->used = preserve->active = 0;
01635    }
01636 
01637    while (cur) {
01638       struct ast_string_field_pool *prev = cur->prev;
01639 
01640       if (cur != preserve) {
01641          ast_free(cur);
01642       }
01643       cur = prev;
01644    }
01645 
01646    *pool_head = preserve;
01647 
01648    return 0;
01649 }
01650 
01651 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr,
01652                   struct ast_string_field_pool **pool_head, size_t needed)
01653 {
01654    char *result = NULL;
01655    size_t space = (*pool_head)->size - (*pool_head)->used;
01656    size_t to_alloc;
01657 
01658    /* Make room for ast_string_field_allocation and make it a multiple of that. */
01659    to_alloc = ast_make_room_for(needed, ast_string_field_allocation);
01660    ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0);
01661 
01662    if (__builtin_expect(to_alloc > space, 0)) {
01663       size_t new_size = (*pool_head)->size;
01664 
01665       while (new_size < to_alloc) {
01666          new_size *= 2;
01667       }
01668 
01669 #if defined(__AST_DEBUG_MALLOC)
01670       if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
01671          return NULL;
01672 #else
01673       if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
01674          return NULL;
01675 #endif
01676    }
01677 
01678    /* pool->base is always aligned (gcc aligned attribute). We ensure that
01679     * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation)
01680     * causing result to always be aligned as well; which in turn fixes that
01681     * AST_STRING_FIELD_ALLOCATION(result) is aligned. */
01682    result = (*pool_head)->base + (*pool_head)->used;
01683    (*pool_head)->used += to_alloc;
01684    (*pool_head)->active += needed;
01685    result += ast_alignof(ast_string_field_allocation);
01686    AST_STRING_FIELD_ALLOCATION(result) = needed;
01687    mgr->last_alloc = result;
01688 
01689    return result;
01690 }
01691 
01692 int __ast_string_field_ptr_grow(struct ast_string_field_mgr *mgr,
01693             struct ast_string_field_pool **pool_head, size_t needed,
01694             const ast_string_field *ptr)
01695 {
01696    ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr);
01697    size_t space = (*pool_head)->size - (*pool_head)->used;
01698 
01699    if (*ptr != mgr->last_alloc) {
01700       return 1;
01701    }
01702 
01703    if (space < grow) {
01704       return 1;
01705    }
01706 
01707    (*pool_head)->used += grow;
01708    (*pool_head)->active += grow;
01709    AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
01710 
01711    return 0;
01712 }
01713 
01714 void __ast_string_field_release_active(struct ast_string_field_pool *pool_head,
01715                    const ast_string_field ptr)
01716 {
01717    struct ast_string_field_pool *pool, *prev;
01718 
01719    if (ptr == __ast_string_field_empty) {
01720       return;
01721    }
01722 
01723    for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) {
01724       if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) {
01725          pool->active -= AST_STRING_FIELD_ALLOCATION(ptr);
01726          if ((pool->active == 0) && prev) {
01727             prev->prev = pool->prev;
01728             ast_free(pool);
01729          }
01730          break;
01731       }
01732    }
01733 }
01734 
01735 void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
01736                  struct ast_string_field_pool **pool_head,
01737                  ast_string_field *ptr, const char *format, va_list ap1, va_list ap2)
01738 {
01739    size_t needed;
01740    size_t available;
01741    size_t space = (*pool_head)->size - (*pool_head)->used;
01742    ssize_t grow;
01743    char *target;
01744 
01745    /* if the field already has space allocated, try to reuse it;
01746       otherwise, try to use the empty space at the end of the current
01747       pool
01748    */
01749    if (*ptr != __ast_string_field_empty) {
01750       target = (char *) *ptr;
01751       available = AST_STRING_FIELD_ALLOCATION(*ptr);
01752       if (*ptr == mgr->last_alloc) {
01753          available += space;
01754       }
01755    } else {
01756       /* pool->used is always a multiple of ast_alignof(ast_string_field_allocation)
01757        * so we don't need to re-align anything here.
01758        */
01759       target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation);
01760       available = space - ast_alignof(ast_string_field_allocation);
01761    }
01762 
01763    needed = vsnprintf(target, available, format, ap1) + 1;
01764 
01765    if (needed > available) {
01766       /* the allocation could not be satisfied using the field's current allocation
01767          (if it has one), or the space available in the pool (if it does not). allocate
01768          space for it, adding a new string pool if necessary.
01769       */
01770       if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) {
01771          return;
01772       }
01773       vsprintf(target, format, ap2);
01774       __ast_string_field_release_active(*pool_head, *ptr);
01775       *ptr = target;
01776    } else if (*ptr != target) {
01777       /* the allocation was satisfied using available space in the pool, but not
01778          using the space already allocated to the field
01779       */
01780       __ast_string_field_release_active(*pool_head, *ptr);
01781       mgr->last_alloc = *ptr = target;
01782       AST_STRING_FIELD_ALLOCATION(target) = needed;
01783       (*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation);
01784       (*pool_head)->active += needed;
01785    } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) {
01786       /* the allocation was satisfied by using available space in the pool *and*
01787          the field was the last allocated field from the pool, so it grew
01788       */
01789       AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
01790       (*pool_head)->used += ast_align_for(grow, ast_string_field_allocation);
01791       (*pool_head)->active += grow;
01792    }
01793 }
01794 
01795 void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
01796               struct ast_string_field_pool **pool_head,
01797               ast_string_field *ptr, const char *format, ...)
01798 {
01799    va_list ap1, ap2;
01800 
01801    va_start(ap1, format);
01802    va_start(ap2, format);     /* va_copy does not exist on FreeBSD */
01803 
01804    __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2);
01805 
01806    va_end(ap1);
01807    va_end(ap2);
01808 }
01809 
01810 void *__ast_calloc_with_stringfields(unsigned int num_structs, size_t struct_size, size_t field_mgr_offset,
01811                  size_t field_mgr_pool_offset, size_t pool_size, const char *file,
01812                  int lineno, const char *func)
01813 {
01814    struct ast_string_field_mgr *mgr;
01815    struct ast_string_field_pool *pool;
01816    struct ast_string_field_pool **pool_head;
01817    size_t pool_size_needed = sizeof(*pool) + pool_size;
01818    size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed);
01819    void *allocation;
01820    unsigned int x;
01821 
01822 #if defined(__AST_DEBUG_MALLOC)  
01823    if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
01824       return NULL;
01825    }
01826 #else
01827    if (!(allocation = ast_calloc(num_structs, size_to_alloc))) {
01828       return NULL;
01829    }
01830 #endif
01831 
01832    for (x = 0; x < num_structs; x++) {
01833       void *base = allocation + (size_to_alloc * x);
01834       const char **p;
01835 
01836       mgr = base + field_mgr_offset;
01837       pool_head = base + field_mgr_pool_offset;
01838       pool = base + struct_size;
01839 
01840       p = (const char **) pool_head + 1;
01841       while ((struct ast_string_field_mgr *) p != mgr) {
01842          *p++ = __ast_string_field_empty;
01843       }
01844 
01845       mgr->embedded_pool = pool;
01846       *pool_head = pool;
01847       pool->size = size_to_alloc - struct_size - sizeof(*pool);
01848 #if defined(__AST_DEBUG_MALLOC)
01849       mgr->owner_file = file;
01850       mgr->owner_func = func;
01851       mgr->owner_line = lineno;
01852 #endif
01853    }
01854 
01855    return allocation;
01856 }
01857 
01858 /* end of stringfields support */
01859 
01860 AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
01861 
01862 int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
01863 {
01864    int ret;
01865    ast_mutex_lock(&fetchadd_m);
01866    ret = *p;
01867    *p += v;
01868    ast_mutex_unlock(&fetchadd_m);
01869    return ret;
01870 }
01871 
01872 /*! \brief
01873  * get values from config variables.
01874  */
01875 int ast_get_timeval(const char *src, struct timeval *dst, struct timeval _default, int *consumed)
01876 {
01877    long double dtv = 0.0;
01878    int scanned;
01879 
01880    if (dst == NULL)
01881       return -1;
01882 
01883    *dst = _default;
01884 
01885    if (ast_strlen_zero(src))
01886       return -1;
01887 
01888    /* only integer at the moment, but one day we could accept more formats */
01889    if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) {
01890       dst->tv_sec = dtv;
01891       dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
01892       if (consumed)
01893          *consumed = scanned;
01894       return 0;
01895    } else
01896       return -1;
01897 }
01898 
01899 /*! \brief
01900  * get values from config variables.
01901  */
01902 int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
01903 {
01904    long t;
01905    int scanned;
01906 
01907    if (dst == NULL)
01908       return -1;
01909 
01910    *dst = _default;
01911 
01912    if (ast_strlen_zero(src))
01913       return -1;
01914 
01915    /* only integer at the moment, but one day we could accept more formats */
01916    if (sscanf(src, "%30ld%n", &t, &scanned) == 1) {
01917       *dst = t;
01918       if (consumed)
01919          *consumed = scanned;
01920       return 0;
01921    } else
01922       return -1;
01923 }
01924 
01925 void ast_enable_packet_fragmentation(int sock)
01926 {
01927 #if defined(HAVE_IP_MTU_DISCOVER)
01928    int val = IP_PMTUDISC_DONT;
01929    
01930    if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
01931       ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
01932 #endif /* HAVE_IP_MTU_DISCOVER */
01933 }
01934 
01935 int ast_mkdir(const char *path, int mode)
01936 {
01937    char *ptr;
01938    int len = strlen(path), count = 0, x, piececount = 0;
01939    char *tmp = ast_strdupa(path);
01940    char **pieces;
01941    char *fullpath = ast_alloca(len + 1);
01942    int res = 0;
01943 
01944    for (ptr = tmp; *ptr; ptr++) {
01945       if (*ptr == '/')
01946          count++;
01947    }
01948 
01949    /* Count the components to the directory path */
01950    pieces = ast_alloca(count * sizeof(*pieces));
01951    for (ptr = tmp; *ptr; ptr++) {
01952       if (*ptr == '/') {
01953          *ptr = '\0';
01954          pieces[piececount++] = ptr + 1;
01955       }
01956    }
01957 
01958    *fullpath = '\0';
01959    for (x = 0; x < piececount; x++) {
01960       /* This looks funky, but the buffer is always ideally-sized, so it's fine. */
01961       strcat(fullpath, "/");
01962       strcat(fullpath, pieces[x]);
01963       res = mkdir(fullpath, mode);
01964       if (res && errno != EEXIST)
01965          return errno;
01966    }
01967    return 0;
01968 }
01969 
01970 int ast_utils_init(void)
01971 {
01972 #ifdef HAVE_DEV_URANDOM
01973    dev_urandom_fd = open("/dev/urandom", O_RDONLY);
01974 #endif
01975    base64_init();
01976 #ifdef DEBUG_THREADS
01977 #if !defined(LOW_MEMORY)
01978    ast_cli_register_multiple(utils_cli, ARRAY_LEN(utils_cli));
01979 #endif
01980 #endif
01981    return 0;
01982 }
01983 
01984 
01985 /*!
01986  *\brief Parse digest authorization header.
01987  *\return Returns -1 if we have no auth or something wrong with digest.
01988  *\note  This function may be used for Digest request and responce header.
01989  * request arg is set to nonzero, if we parse Digest Request.
01990  * pedantic arg can be set to nonzero if we need to do addition Digest check.
01991  */
01992 int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic) {
01993    char *c;
01994    struct ast_str *str = ast_str_create(16);
01995 
01996    /* table of recognised keywords, and places where they should be copied */
01997    const struct x {
01998       const char *key;
01999       const ast_string_field *field;
02000    } *i, keys[] = {
02001       { "username=", &d->username },
02002       { "realm=", &d->realm },
02003       { "nonce=", &d->nonce },
02004       { "uri=", &d->uri },
02005       { "domain=", &d->domain },
02006       { "response=", &d->response },
02007       { "cnonce=", &d->cnonce },
02008       { "opaque=", &d->opaque },
02009       /* Special cases that cannot be directly copied */
02010       { "algorithm=", NULL },
02011       { "qop=", NULL },
02012       { "nc=", NULL },
02013       { NULL, 0 },
02014    };
02015 
02016    if (ast_strlen_zero(digest) || !d || !str) {
02017       ast_free(str);
02018       return -1;
02019    }
02020 
02021    ast_str_set(&str, 0, "%s", digest);
02022 
02023    c = ast_skip_blanks(ast_str_buffer(str));
02024 
02025    if (strncasecmp(c, "Digest ", strlen("Digest "))) {
02026       ast_log(LOG_WARNING, "Missing Digest.\n");
02027       ast_free(str);
02028       return -1;
02029    }
02030    c += strlen("Digest ");
02031 
02032    /* lookup for keys/value pair */
02033    while (c && *c && *(c = ast_skip_blanks(c))) {
02034       /* find key */
02035       for (i = keys; i->key != NULL; i++) {
02036          char *src, *separator;
02037          int unescape = 0;
02038          if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
02039             continue;
02040          }
02041 
02042          /* Found. Skip keyword, take text in quotes or up to the separator. */
02043          c += strlen(i->key);
02044          if (*c == '"') {
02045             src = ++c;
02046             separator = "\"";
02047             unescape = 1;
02048          } else {
02049             src = c;
02050             separator = ",";
02051          }
02052          strsep(&c, separator); /* clear separator and move ptr */
02053          if (unescape) {
02054             ast_unescape_c(src);
02055          }
02056          if (i->field) {
02057             ast_string_field_ptr_set(d, i->field, src);
02058          } else {
02059             /* Special cases that require additional procesing */
02060             if (!strcasecmp(i->key, "algorithm=")) {
02061                if (strcasecmp(src, "MD5")) {
02062                   ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", src);
02063                   ast_free(str);
02064                   return -1;
02065                }
02066             } else if (!strcasecmp(i->key, "qop=") && !strcasecmp(src, "auth")) {
02067                d->qop = 1;
02068             } else if (!strcasecmp(i->key, "nc=")) {
02069                unsigned long u;
02070                if (sscanf(src, "%30lx", &u) != 1) {
02071                   ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", src);
02072                   ast_free(str);
02073                   return -1;
02074                }
02075                ast_string_field_set(d, nc, src);
02076             }
02077          }
02078          break;
02079       }
02080       if (i->key == NULL) { /* not found, try ',' */
02081          strsep(&c, ",");
02082       }
02083    }
02084    ast_free(str);
02085 
02086    /* Digest checkout */
02087    if (ast_strlen_zero(d->realm) || ast_strlen_zero(d->nonce)) {
02088       /* "realm" and "nonce" MUST be always exist */
02089       return -1;
02090    }
02091 
02092    if (!request) {
02093       /* Additional check for Digest response */
02094       if (ast_strlen_zero(d->username) || ast_strlen_zero(d->uri) || ast_strlen_zero(d->response)) {
02095          return -1;
02096       }
02097 
02098       if (pedantic && d->qop && (ast_strlen_zero(d->cnonce) || ast_strlen_zero(d->nc))) {
02099          return -1;
02100       }
02101    }
02102 
02103    return 0;
02104 }
02105 
02106 #ifndef __AST_DEBUG_MALLOC
02107 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...)
02108 {
02109    int res;
02110    va_list ap;
02111 
02112    va_start(ap, fmt);
02113    if ((res = vasprintf(ret, fmt, ap)) == -1) {
02114       MALLOC_FAILURE_MSG;
02115    }
02116    va_end(ap);
02117 
02118    return res;
02119 }
02120 #endif
02121 
02122 char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size)
02123 {
02124    const char *envPATH = getenv("PATH");
02125    char *tpath, *path;
02126    struct stat unused;
02127    if (!envPATH) {
02128       return NULL;
02129    }
02130    tpath = ast_strdupa(envPATH);
02131    while ((path = strsep(&tpath, ":"))) {
02132       snprintf(fullpath, fullpath_size, "%s/%s", path, binary);
02133       if (!stat(fullpath, &unused)) {
02134          return fullpath;
02135       }
02136    }
02137    return NULL;
02138 }
02139