Wed Apr 6 11:29:48 2011

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

Generated on Wed Apr 6 11:29:48 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7