Sat Mar 10 01:54:28 2012

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: 344843 $")
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;
01650 
01651    /* Make room for ast_string_field_allocation and make it a multiple of that. */
01652    to_alloc = ast_make_room_for(needed, ast_string_field_allocation);
01653    ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0);
01654 
01655    if (__builtin_expect(to_alloc > space, 0)) {
01656       size_t new_size = (*pool_head)->size;
01657 
01658       while (new_size < to_alloc) {
01659          new_size *= 2;
01660       }
01661 
01662 #if defined(__AST_DEBUG_MALLOC)
01663       if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
01664          return NULL;
01665 #else
01666       if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
01667          return NULL;
01668 #endif
01669    }
01670 
01671    /* pool->base is always aligned (gcc aligned attribute). We ensure that
01672     * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation)
01673     * causing result to always be aligned as well; which in turn fixes that
01674     * AST_STRING_FIELD_ALLOCATION(result) is aligned. */
01675    result = (*pool_head)->base + (*pool_head)->used;
01676    (*pool_head)->used += to_alloc;
01677    (*pool_head)->active += needed;
01678    result += ast_alignof(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       /* pool->used is always a multiple of ast_alignof(ast_string_field_allocation)
01750        * so we don't need to re-align anything here.
01751        */
01752       target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation);
01753       available = space - ast_alignof(ast_string_field_allocation);
01754    }
01755 
01756    needed = vsnprintf(target, available, format, ap1) + 1;
01757 
01758    va_end(ap1);
01759 
01760    if (needed > available) {
01761       /* the allocation could not be satisfied using the field's current allocation
01762          (if it has one), or the space available in the pool (if it does not). allocate
01763          space for it, adding a new string pool if necessary.
01764       */
01765       if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) {
01766          return;
01767       }
01768       vsprintf(target, format, ap2);
01769       __ast_string_field_release_active(*pool_head, *ptr);
01770       *ptr = target;
01771    } else if (*ptr != target) {
01772       /* the allocation was satisfied using available space in the pool, but not
01773          using the space already allocated to the field
01774       */
01775       __ast_string_field_release_active(*pool_head, *ptr);
01776       mgr->last_alloc = *ptr = target;
01777       AST_STRING_FIELD_ALLOCATION(target) = needed;
01778       (*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation);
01779       (*pool_head)->active += needed;
01780    } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) {
01781       /* the allocation was satisfied by using available space in the pool *and*
01782          the field was the last allocated field from the pool, so it grew
01783       */
01784       AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
01785       (*pool_head)->used += ast_align_for(grow, ast_string_field_allocation);
01786       (*pool_head)->active += grow;
01787    }
01788 }
01789 
01790 void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
01791               struct ast_string_field_pool **pool_head,
01792               ast_string_field *ptr, const char *format, ...)
01793 {
01794    va_list ap1, ap2;
01795 
01796    va_start(ap1, format);
01797    va_start(ap2, format);     /* va_copy does not exist on FreeBSD */
01798 
01799    __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2);
01800 
01801    va_end(ap1);
01802    va_end(ap2);
01803 }
01804 
01805 void *__ast_calloc_with_stringfields(unsigned int num_structs, size_t struct_size, size_t field_mgr_offset,
01806                  size_t field_mgr_pool_offset, size_t pool_size, const char *file,
01807                  int lineno, const char *func)
01808 {
01809    struct ast_string_field_mgr *mgr;
01810    struct ast_string_field_pool *pool;
01811    struct ast_string_field_pool **pool_head;
01812    size_t pool_size_needed = sizeof(*pool) + pool_size;
01813    size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed);
01814    void *allocation;
01815    unsigned int x;
01816 
01817 #if defined(__AST_DEBUG_MALLOC)  
01818    if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
01819       return NULL;
01820    }
01821 #else
01822    if (!(allocation = ast_calloc(num_structs, size_to_alloc))) {
01823       return NULL;
01824    }
01825 #endif
01826 
01827    for (x = 0; x < num_structs; x++) {
01828       void *base = allocation + (size_to_alloc * x);
01829       const char **p;
01830 
01831       mgr = base + field_mgr_offset;
01832       pool_head = base + field_mgr_pool_offset;
01833       pool = base + struct_size;
01834 
01835       p = (const char **) pool_head + 1;
01836       while ((struct ast_string_field_mgr *) p != mgr) {
01837          *p++ = __ast_string_field_empty;
01838       }
01839 
01840       mgr->embedded_pool = pool;
01841       *pool_head = pool;
01842       pool->size = size_to_alloc - struct_size - sizeof(*pool);
01843 #if defined(__AST_DEBUG_MALLOC)
01844       mgr->owner_file = file;
01845       mgr->owner_func = func;
01846       mgr->owner_line = lineno;
01847 #endif
01848    }
01849 
01850    return allocation;
01851 }
01852 
01853 /* end of stringfields support */
01854 
01855 AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
01856 
01857 int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
01858 {
01859    int ret;
01860    ast_mutex_lock(&fetchadd_m);
01861    ret = *p;
01862    *p += v;
01863    ast_mutex_unlock(&fetchadd_m);
01864    return ret;
01865 }
01866 
01867 /*! \brief
01868  * get values from config variables.
01869  */
01870 int ast_get_timeval(const char *src, struct timeval *dst, struct timeval _default, int *consumed)
01871 {
01872    long double dtv = 0.0;
01873    int scanned;
01874 
01875    if (dst == NULL)
01876       return -1;
01877 
01878    *dst = _default;
01879 
01880    if (ast_strlen_zero(src))
01881       return -1;
01882 
01883    /* only integer at the moment, but one day we could accept more formats */
01884    if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) {
01885       dst->tv_sec = dtv;
01886       dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
01887       if (consumed)
01888          *consumed = scanned;
01889       return 0;
01890    } else
01891       return -1;
01892 }
01893 
01894 /*! \brief
01895  * get values from config variables.
01896  */
01897 int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
01898 {
01899    long t;
01900    int scanned;
01901 
01902    if (dst == NULL)
01903       return -1;
01904 
01905    *dst = _default;
01906 
01907    if (ast_strlen_zero(src))
01908       return -1;
01909 
01910    /* only integer at the moment, but one day we could accept more formats */
01911    if (sscanf(src, "%30ld%n", &t, &scanned) == 1) {
01912       *dst = t;
01913       if (consumed)
01914          *consumed = scanned;
01915       return 0;
01916    } else
01917       return -1;
01918 }
01919 
01920 void ast_enable_packet_fragmentation(int sock)
01921 {
01922 #if defined(HAVE_IP_MTU_DISCOVER)
01923    int val = IP_PMTUDISC_DONT;
01924    
01925    if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
01926       ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
01927 #endif /* HAVE_IP_MTU_DISCOVER */
01928 }
01929 
01930 int ast_mkdir(const char *path, int mode)
01931 {
01932    char *ptr;
01933    int len = strlen(path), count = 0, x, piececount = 0;
01934    char *tmp = ast_strdupa(path);
01935    char **pieces;
01936    char *fullpath = alloca(len + 1);
01937    int res = 0;
01938 
01939    for (ptr = tmp; *ptr; ptr++) {
01940       if (*ptr == '/')
01941          count++;
01942    }
01943 
01944    /* Count the components to the directory path */
01945    pieces = alloca(count * sizeof(*pieces));
01946    for (ptr = tmp; *ptr; ptr++) {
01947       if (*ptr == '/') {
01948          *ptr = '\0';
01949          pieces[piececount++] = ptr + 1;
01950       }
01951    }
01952 
01953    *fullpath = '\0';
01954    for (x = 0; x < piececount; x++) {
01955       /* This looks funky, but the buffer is always ideally-sized, so it's fine. */
01956       strcat(fullpath, "/");
01957       strcat(fullpath, pieces[x]);
01958       res = mkdir(fullpath, mode);
01959       if (res && errno != EEXIST)
01960          return errno;
01961    }
01962    return 0;
01963 }
01964 
01965 int ast_utils_init(void)
01966 {
01967 #ifdef HAVE_DEV_URANDOM
01968    dev_urandom_fd = open("/dev/urandom", O_RDONLY);
01969 #endif
01970    base64_init();
01971 #ifdef DEBUG_THREADS
01972 #if !defined(LOW_MEMORY)
01973    ast_cli_register_multiple(utils_cli, ARRAY_LEN(utils_cli));
01974 #endif
01975 #endif
01976    return 0;
01977 }
01978 
01979 
01980 /*!
01981  *\brief Parse digest authorization header.
01982  *\return Returns -1 if we have no auth or something wrong with digest.
01983  *\note  This function may be used for Digest request and responce header.
01984  * request arg is set to nonzero, if we parse Digest Request.
01985  * pedantic arg can be set to nonzero if we need to do addition Digest check.
01986  */
01987 int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic) {
01988    int i;
01989    char *c, key[512], val[512];
01990    struct ast_str *str = ast_str_create(16);
01991 
01992    if (ast_strlen_zero(digest) || !d || !str) {
01993       ast_free(str);
01994       return -1;
01995    }
01996 
01997    ast_str_set(&str, 0, "%s", digest);
01998 
01999    c = ast_skip_blanks(ast_str_buffer(str));
02000 
02001    if (strncasecmp(c, "Digest ", strlen("Digest "))) {
02002       ast_log(LOG_WARNING, "Missing Digest.\n");
02003       ast_free(str);
02004       return -1;
02005    }
02006    c += strlen("Digest ");
02007 
02008    /* lookup for keys/value pair */
02009    while (*c && *(c = ast_skip_blanks(c))) {
02010       /* find key */
02011       i = 0;
02012       while (*c && *c != '=' && *c != ',' && !isspace(*c)) {
02013          key[i++] = *c++;
02014       }
02015       key[i] = '\0';
02016       c = ast_skip_blanks(c);
02017       if (*c == '=') {
02018          c = ast_skip_blanks(++c);
02019          i = 0;
02020          if (*c == '\"') {
02021             /* in quotes. Skip first and look for last */
02022             c++;
02023             while (*c && *c != '\"') {
02024                if (*c == '\\' && c[1] != '\0') { /* unescape chars */
02025                   c++;
02026                }
02027                val[i++] = *c++;
02028             }
02029          } else {
02030             /* token */
02031             while (*c && *c != ',' && !isspace(*c)) {
02032                val[i++] = *c++;
02033             }
02034          }
02035          val[i] = '\0';
02036       }
02037 
02038       while (*c && *c != ',') {
02039          c++;
02040       }
02041       if (*c) {
02042          c++;
02043       }
02044 
02045       if (!strcasecmp(key, "username")) {
02046          ast_string_field_set(d, username, val);
02047       } else if (!strcasecmp(key, "realm")) {
02048          ast_string_field_set(d, realm, val);
02049       } else if (!strcasecmp(key, "nonce")) {
02050          ast_string_field_set(d, nonce, val);
02051       } else if (!strcasecmp(key, "uri")) {
02052          ast_string_field_set(d, uri, val);
02053       } else if (!strcasecmp(key, "domain")) {
02054          ast_string_field_set(d, domain, val);
02055       } else if (!strcasecmp(key, "response")) {
02056          ast_string_field_set(d, response, val);
02057       } else if (!strcasecmp(key, "algorithm")) {
02058          if (strcasecmp(val, "MD5")) {
02059             ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", val);
02060             return -1;
02061          }
02062       } else if (!strcasecmp(key, "cnonce")) {
02063          ast_string_field_set(d, cnonce, val);
02064       } else if (!strcasecmp(key, "opaque")) {
02065          ast_string_field_set(d, opaque, val);
02066       } else if (!strcasecmp(key, "qop") && !strcasecmp(val, "auth")) {
02067          d->qop = 1;
02068       } else if (!strcasecmp(key, "nc")) {
02069          unsigned long u;
02070          if (sscanf(val, "%30lx", &u) != 1) {
02071             ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", val);
02072             return -1;
02073          }
02074          ast_string_field_set(d, nc, val);
02075       }
02076    }
02077    ast_free(str);
02078 
02079    /* Digest checkout */
02080    if (ast_strlen_zero(d->realm) || ast_strlen_zero(d->nonce)) {
02081       /* "realm" and "nonce" MUST be always exist */
02082       return -1;
02083    }
02084 
02085    if (!request) {
02086       /* Additional check for Digest response */
02087       if (ast_strlen_zero(d->username) || ast_strlen_zero(d->uri) || ast_strlen_zero(d->response)) {
02088          return -1;
02089       }
02090 
02091       if (pedantic && d->qop && (ast_strlen_zero(d->cnonce) || ast_strlen_zero(d->nc))) {
02092          return -1;
02093       }
02094    }
02095 
02096    return 0;
02097 }
02098 
02099 #ifndef __AST_DEBUG_MALLOC
02100 int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...)
02101 {
02102    int res;
02103    va_list ap;
02104 
02105    va_start(ap, fmt);
02106    if ((res = vasprintf(ret, fmt, ap)) == -1) {
02107       MALLOC_FAILURE_MSG;
02108    }
02109    va_end(ap);
02110 
02111    return res;
02112 }
02113 #endif
02114 
02115 char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size)
02116 {
02117    const char *envPATH = getenv("PATH");
02118    char *tpath, *path;
02119    struct stat unused;
02120    if (!envPATH) {
02121       return NULL;
02122    }
02123    tpath = ast_strdupa(envPATH);
02124    while ((path = strsep(&tpath, ":"))) {
02125       snprintf(fullpath, fullpath_size, "%s/%s", path, binary);
02126       if (!stat(fullpath, &unused)) {
02127          return fullpath;
02128       }
02129    }
02130    return NULL;
02131 }
02132 

Generated on Sat Mar 10 01:54:28 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7