Sun Oct 16 2011 08:41:48

Asterisk developer's documentation


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