Wed Apr 6 11:30:11 2011

Asterisk developer's documentation


utils.c File Reference

Utility functions. More...

#include "asterisk.h"
#include <ctype.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "asterisk/network.h"
#include "asterisk/lock.h"
#include "asterisk/io.h"
#include "asterisk/md5.h"
#include "asterisk/sha1.h"
#include "asterisk/cli.h"
#include "asterisk/linkedlists.h"
#include "asterisk/strings.h"
#include "asterisk/time.h"
#include "asterisk/stringfields.h"
#include "asterisk/utils.h"
#include "asterisk/threadstorage.h"
#include "asterisk/config.h"

Go to the source code of this file.

Data Structures

struct  thr_arg

Defines

#define ALLOCATOR_OVERHEAD   48
#define AST_API_MODULE
#define AST_API_MODULE
#define AST_API_MODULE
#define AST_API_MODULE
#define AST_API_MODULE
#define AST_API_MODULE
#define AST_API_MODULE
#define ONE_MILLION   1000000

Functions

void * __ast_calloc_with_stringfields (unsigned int num_structs, size_t struct_size, size_t field_mgr_offset, size_t field_mgr_pool_offset, size_t pool_size, const char *file, int lineno, const char *func)
ast_string_field __ast_string_field_alloc_space (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, size_t needed)
int __ast_string_field_init (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, int needed, const char *file, int lineno, const char *func)
void __ast_string_field_ptr_build (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, ast_string_field *ptr, const char *format,...)
void __ast_string_field_ptr_build_va (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, ast_string_field *ptr, const char *format, va_list ap1, va_list ap2)
int __ast_string_field_ptr_grow (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, size_t needed, const ast_string_field *ptr)
void __ast_string_field_release_active (struct ast_string_field_pool *pool_head, const ast_string_field ptr)
static void __init_inet_ntoa_buf (void)
int _ast_asprintf (char **ret, const char *file, int lineno, const char *func, const char *fmt,...)
static int add_string_pool (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, size_t size, const char *file, int lineno, const char *func)
 add a new block to the pool. We can only allocate from the topmost pool, so the fields in *mgr reflect the size of that only.
int ast_atomic_fetchadd_int_slow (volatile int *p, int v)
int ast_base64decode (unsigned char *dst, const char *src, int max)
 Decode data from base64.
int ast_base64encode (char *dst, const unsigned char *src, int srclen, int max)
 Encode data in base64.
int ast_base64encode_full (char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
 encode text to BASE64 coding
int ast_build_string (char **buffer, size_t *space, const char *fmt,...)
 Build a string in a buffer, designed to be called repeatedly.
int ast_build_string_va (char **buffer, size_t *space, const char *fmt, va_list ap)
 Build a string in a buffer, designed to be called repeatedly.
int ast_careful_fwrite (FILE *f, int fd, const char *src, size_t len, int timeoutms)
 Write data to a file stream with a timeout.
int ast_carefulwrite (int fd, char *s, int len, int timeoutms)
 Try to write string, but wait no more than ms milliseconds before timing out.
void ast_enable_packet_fragmentation (int sock)
 Disable PMTU discovery on a socket.
int ast_false (const char *s)
 Make sure something is false. Determine if a string containing a boolean value is "false". This function checks to see whether a string passed to it is an indication of an "false" value. It checks to see if the string is "no", "false", "n", "f", "off" or "0".
int ast_get_time_t (const char *src, time_t *dst, time_t _default, int *consumed)
 get values from config variables.
int ast_get_timeval (const char *src, struct timeval *dst, struct timeval _default, int *consumed)
 get values from config variables.
hostent * ast_gethostbyname (const char *host, struct ast_hostent *hp)
 Thread-safe gethostbyname function to use in Asterisk.
const char * ast_inet_ntoa (struct in_addr ia)
 thread-safe replacement for inet_ntoa().
void ast_join (char *s, size_t len, const char *const w[])
void ast_md5_hash (char *output, const char *input)
 Produces MD5 hash based on input string.
int ast_mkdir (const char *path, int mode)
 Recursively create directory path.
int ast_parse_digest (const char *digest, struct ast_http_digest *d, int request, int pedantic)
 Parse digest authorization header.
char * ast_process_quotes_and_slashes (char *start, char find, char replace_with)
 Process a string to find and replace characters.
int ast_pthread_create_detached_stack (pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize, const char *file, const char *caller, int line, const char *start_fn)
int ast_pthread_create_stack (pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize, const char *file, const char *caller, int line, const char *start_fn)
long int ast_random (void)
void ast_sha1_hash (char *output, const char *input)
 Produces SHA1 hash based on input string.
char * ast_strip_quoted (char *s, const char *beg_quotes, const char *end_quotes)
 Strip leading/trailing whitespace and quotes from a string.
int ast_true (const char *s)
 Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
timeval ast_tvadd (struct timeval a, struct timeval b)
 Returns the sum of two timevals a + b.
timeval ast_tvsub (struct timeval a, struct timeval b)
 Returns the difference of two timevals a - b.
char * ast_unescape_c (char *src)
 Convert some C escape sequences.
char * ast_unescape_semicolon (char *s)
 Strip backslash for "escaped" semicolons, the string to be stripped (will be modified).
void ast_uri_decode (char *s)
 Decode URI, URN, URL (overwrite string).
char * ast_uri_encode (const char *string, char *outbuf, int buflen, int do_special_char)
 Turn text string to URI-encoded XX version.
int ast_utils_init (void)
char * ast_utils_which (const char *binary, char *fullpath, size_t fullpath_size)
 Resolve a binary to a full pathname.
int ast_wait_for_input (int fd, int ms)
static int ast_wait_for_output (int fd, int timeoutms)
static void base64_init (void)
static void * dummy_start (void *data)
static size_t optimal_alloc_size (size_t size)
static struct timeval tvfix (struct timeval a)

Variables

ast_string_field __ast_string_field_empty = __ast_string_field_empty_buffer.string
struct {
   ast_string_field_allocation   allocation
   char   string [1]
__ast_string_field_empty_buffer
static char b2a [256]
static char base64 [64]
static int dev_urandom_fd
static ast_mutex_t fetchadd_m = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP }
static struct ast_threadstorage inet_ntoa_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_inet_ntoa_buf , .custom_init = NULL , }
static ast_mutex_t randomlock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP }
 glibc puts a lock inside random(3), so that the results are thread-safe. BSD libc (and others) do not.


Detailed Description

Utility functions.

Note:
These are important for portability and security, so please use them in favour of other routines. Please consult the CODING GUIDELINES for more information.

Definition in file utils.c.


Define Documentation

#define ALLOCATOR_OVERHEAD   48

Definition at line 1491 of file utils.c.

Referenced by optimal_alloc_size().

#define AST_API_MODULE

Definition at line 63 of file utils.c.

#define AST_API_MODULE

Definition at line 63 of file utils.c.

#define AST_API_MODULE

Definition at line 63 of file utils.c.

#define AST_API_MODULE

Definition at line 63 of file utils.c.

#define AST_API_MODULE

Definition at line 63 of file utils.c.

#define AST_API_MODULE

Definition at line 63 of file utils.c.

#define AST_API_MODULE

Definition at line 63 of file utils.c.

#define ONE_MILLION   1000000

Definition at line 1348 of file utils.c.

Referenced by ast_tvadd(), ast_tvsub(), and tvfix().


Function Documentation

void* __ast_calloc_with_stringfields ( unsigned int  num_structs,
size_t  struct_size,
size_t  field_mgr_offset,
size_t  field_mgr_pool_offset,
size_t  pool_size,
const char *  file,
int  lineno,
const char *  func 
)

Definition at line 1775 of file utils.c.

References __ast_calloc(), __ast_string_field_empty, allocation, ast_calloc, ast_string_field_pool::base, ast_string_field_mgr::embedded_pool, optimal_alloc_size(), and ast_string_field_pool::size.

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 }

ast_string_field __ast_string_field_alloc_space ( struct ast_string_field_mgr mgr,
struct ast_string_field_pool **  pool_head,
size_t  needed 
)

Definition at line 1611 of file utils.c.

References add_string_pool(), AST_STRING_FIELD_ALLOCATION, and ast_string_field_mgr::last_alloc.

Referenced by __ast_string_field_ptr_build_va().

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 }

int __ast_string_field_init ( struct ast_string_field_mgr mgr,
struct ast_string_field_pool **  pool_head,
int  needed,
const char *  file,
int  lineno,
const char *  func 
)

Definition at line 1544 of file utils.c.

References ast_string_field_pool::active, add_string_pool(), ast_free, ast_log(), ast_string_field_mgr::embedded_pool, ast_string_field_mgr::last_alloc, LOG_WARNING, ast_string_field_pool::prev, and ast_string_field_pool::used.

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 }

void __ast_string_field_ptr_build ( struct ast_string_field_mgr mgr,
struct ast_string_field_pool **  pool_head,
ast_string_field ptr,
const char *  format,
  ... 
)

Definition at line 1760 of file utils.c.

References __ast_string_field_ptr_build_va().

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 }

void __ast_string_field_ptr_build_va ( struct ast_string_field_mgr mgr,
struct ast_string_field_pool **  pool_head,
ast_string_field ptr,
const char *  format,
va_list  ap1,
va_list  ap2 
)

Definition at line 1695 of file utils.c.

References __ast_string_field_alloc_space(), __ast_string_field_empty, __ast_string_field_release_active(), AST_STRING_FIELD_ALLOCATION, available(), and ast_string_field_mgr::last_alloc.

Referenced by __ast_string_field_ptr_build().

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 }

int __ast_string_field_ptr_grow ( struct ast_string_field_mgr mgr,
struct ast_string_field_pool **  pool_head,
size_t  needed,
const ast_string_field ptr 
)

Definition at line 1652 of file utils.c.

References AST_STRING_FIELD_ALLOCATION, and ast_string_field_mgr::last_alloc.

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 }

void __ast_string_field_release_active ( struct ast_string_field_pool pool_head,
const ast_string_field  ptr 
)

Definition at line 1674 of file utils.c.

References ast_string_field_pool::active, ast_free, AST_STRING_FIELD_ALLOCATION, and ast_string_field_pool::prev.

Referenced by __ast_string_field_ptr_build_va().

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 }

static void __init_inet_ntoa_buf ( void   )  [static]

Definition at line 69 of file utils.c.

00086 {

int _ast_asprintf ( char **  ret,
const char *  file,
int  lineno,
const char *  func,
const char *  fmt,
  ... 
)

Definition at line 2070 of file utils.c.

References MALLOC_FAILURE_MSG, and vasprintf.

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 }

static int add_string_pool ( struct ast_string_field_mgr mgr,
struct ast_string_field_pool **  pool_head,
size_t  size,
const char *  file,
int  lineno,
const char *  func 
) [static]

add a new block to the pool. We can only allocate from the topmost pool, so the fields in *mgr reflect the size of that only.

Definition at line 1508 of file utils.c.

References __ast_calloc(), ast_calloc, ast_string_field_mgr::last_alloc, optimal_alloc_size(), and ast_string_field_pool::size.

Referenced by __ast_string_field_alloc_space(), and __ast_string_field_init().

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 }

int ast_atomic_fetchadd_int_slow ( volatile int *  p,
int  v 
)

Definition at line 1827 of file utils.c.

References ast_mutex_lock, ast_mutex_unlock, and fetchadd_m.

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 }

int ast_base64decode ( unsigned char *  dst,
const char *  src,
int  max 
)

Decode data from base64.

Parameters:
dst the destination buffer
src the source buffer
max The maximum number of bytes to write into the destination buffer. Note that this function will not ensure that the destination buffer is NULL terminated. So, in general, this parameter should be sizeof(dst) - 1.

Definition at line 265 of file utils.c.

Referenced by aes_helper(), ast_check_signature(), base64_helper(), and osp_validate_token().

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 }

int ast_base64encode ( char *  dst,
const unsigned char *  src,
int  srclen,
int  max 
)

Encode data in base64.

Parameters:
dst the destination buffer
src the source data to be encoded
srclen the number of bytes present in the source buffer
max the maximum number of bytes to write into the destination buffer, *including* the terminating NULL character.

Definition at line 343 of file utils.c.

References ast_base64encode_full().

Referenced by aes_helper(), aji_start_sasl(), ast_sign(), base64_helper(), build_secret(), and osp_check_destination().

00344 {
00345    return ast_base64encode_full(dst, src, srclen, max, 0);
00346 }

int ast_base64encode_full ( char *  dst,
const unsigned char *  src,
int  srclen,
int  max,
int  linebreaks 
)

encode text to BASE64 coding

Definition at line 292 of file utils.c.

Referenced by ast_base64encode().

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 }

int ast_build_string ( char **  buffer,
size_t *  space,
const char *  fmt,
  ... 
)

Build a string in a buffer, designed to be called repeatedly.

Note:
This method is not recommended. New code should use ast_str_*() instead.
This is a wrapper for snprintf, that properly handles the buffer pointer and buffer space available.

Parameters:
buffer current position in buffer to place string into (will be updated on return)
space remaining space in buffer (will be updated on return)
fmt printf-style format string
Return values:
0 on success
non-zero on failure.

Definition at line 1302 of file utils.c.

References ast_build_string_va().

Referenced by ast_fax_caps_to_str(), config_odbc(), generate_filenames_string(), handle_speechrecognize(), lua_func_read(), lua_pbx_exec(), pp_each_extension_helper(), and pp_each_user_helper().

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 }

int ast_build_string_va ( char **  buffer,
size_t *  space,
const char *  fmt,
va_list  ap 
)

Build a string in a buffer, designed to be called repeatedly.

This is a wrapper for snprintf, that properly handles the buffer pointer and buffer space available.

Returns:
0 on success, non-zero on failure.
Parameters:
buffer current position in buffer to place string into (will be updated on return)
space remaining space in buffer (will be updated on return)
fmt printf-style format string
ap varargs list of arguments for format

Definition at line 1283 of file utils.c.

Referenced by ast_build_string().

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 }

int ast_careful_fwrite ( FILE *  f,
int  fd,
const char *  s,
size_t  len,
int  timeoutms 
)

Write data to a file stream with a timeout.

Parameters:
f the file stream to write to
fd the file description to poll on to know when the file stream can be written to without blocking.
s the buffer to write from
len the number of bytes to write
timeoutms The maximum amount of time to block in this function trying to write, specified in milliseconds.
Note:
This function assumes that the associated file stream has been set up as non-blocking.
Return values:
0 success
-1 error

Definition at line 1157 of file utils.c.

References ast_log(), ast_tvdiff_ms(), ast_tvnow(), ast_wait_for_output(), errno, fwrite, and LOG_ERROR.

Referenced by send_string().

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 }

int ast_carefulwrite ( int  fd,
char *  s,
int  len,
int  timeoutms 
)

Try to write string, but wait no more than ms milliseconds before timing out.

Try to write string, but wait no more than ms milliseconds before timing out.

Note:
The code assumes that the file descriptor has NONBLOCK set, so there is only one system call made to do a write, unless we actually have a need to wait. This way, we get better performance. If the descriptor is blocking, all assumptions on the guaranteed detail do not apply anymore.

Definition at line 1116 of file utils.c.

References ast_log(), ast_tvdiff_ms(), ast_tvnow(), ast_wait_for_output(), errno, and LOG_ERROR.

Referenced by ast_agi_send(), and ast_cli().

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 }

void ast_enable_packet_fragmentation ( int  sock  ) 

Disable PMTU discovery on a socket.

Parameters:
sock The socket to manipulate
Returns:
Nothing
On Linux, UDP sockets default to sending packets with the Dont Fragment (DF) bit set. This is supposedly done to allow the application to do PMTU discovery, but Asterisk does not do this.

Because of this, UDP packets sent by Asterisk that are larger than the MTU of any hop in the path will be lost. This function can be called on a socket to ensure that the DF bit will not be set.

Definition at line 1890 of file utils.c.

References ast_log(), and LOG_WARNING.

Referenced by ast_netsock_bindaddr().

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 }

int ast_false ( const char *  val  ) 

Make sure something is false. Determine if a string containing a boolean value is "false". This function checks to see whether a string passed to it is an indication of an "false" value. It checks to see if the string is "no", "false", "n", "f", "off" or "0".

Return values:
0 if val is a NULL pointer.
-1 if "true".
0 otherwise.

Definition at line 1331 of file utils.c.

References ast_strlen_zero().

Referenced by __ast_udptl_reload(), acf_faxopt_write(), acf_transaction_write(), aji_create_client(), aji_load_config(), aoc_cli_debug_enable(), build_peer(), build_user(), dahdi_set_dnd(), find_realtime(), func_channel_write_real(), handle_common_options(), init_acf_query(), load_config(), load_odbc_config(), manager_mute_mixmonitor(), parse_empty_options(), rtp_reload(), run_agi(), set_config(), set_insecure_flags(), and strings_to_mask().

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 }

int ast_get_time_t ( const char *  src,
time_t *  dst,
time_t  _default,
int *  consumed 
)

get values from config variables.

Definition at line 1867 of file utils.c.

References ast_strlen_zero().

Referenced by build_peer(), cache_lookup_internal(), handle_saydatetime(), load_password(), play_message_datetime(), process_clearcache(), and sayunixtime_exec().

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 }

int ast_get_timeval ( const char *  src,
struct timeval *  dst,
struct timeval  _default,
int *  consumed 
)

get values from config variables.

Definition at line 1840 of file utils.c.

References ast_strlen_zero().

Referenced by acf_strftime().

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 }

struct hostent* ast_gethostbyname ( const char *  host,
struct ast_hostent hp 
)

Thread-safe gethostbyname function to use in Asterisk.

Definition at line 183 of file utils.c.

References hp.

Referenced by ast_parse_arg(), config_load(), config_parse_variables(), create_addr(), festival_exec(), gtalk_update_stun(), iax_template_parse(), jingle_load_config(), jingle_update_stun(), launch_netscript(), process_sdp(), realtime_peer(), realtime_user(), reload_config(), rpt_exec(), and set_config().

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 }

const char* ast_inet_ntoa ( struct in_addr  ia  ) 

thread-safe replacement for inet_ntoa().

Note:
It is very important to note that even though this is a thread-safe replacement for inet_ntoa(), it is *not* reentrant. In a single thread, the result from a previous call to this function is no longer valid once it is called again. If the result from multiple calls to this function need to be kept or used at once, then the result must be copied to a local buffer before calling this function again.

Definition at line 434 of file utils.c.

References ast_threadstorage_get(), and inet_ntoa_buf.

Referenced by __attempt_transmit(), __find_callno(), __iax2_show_peers(), _skinny_show_device(), _skinny_show_devices(), acf_channel_read(), action_login(), add_ipv4_ie(), add_sdp(), ast_apply_ha(), ast_netsock_bindaddr(), ast_parse_arg(), authenticate(), calltoken_required(), check_access(), config_load(), create_client(), data_get_xml_add_child(), data_result_manager_output(), data_result_print_cli_node(), dump_addr(), dump_ipaddr(), dundi_rexmit(), dundi_show_peer(), dundi_show_peers(), dundi_show_trans(), dundi_showframe(), dundi_xmit(), external_rtp_create(), find_command(), find_peer(), find_subchannel_and_lock(), find_tpeer(), function_iaxpeer(), gtalk_update_externip(), gtalk_update_stun(), handle_call_token(), handle_cli_iax2_set_debug(), handle_cli_iax2_show_callno_limits(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_peer(), handle_cli_iax2_show_registry(), handle_command_response(), handle_error(), handle_mgcp_show_endpoints(), handle_open_receive_channel_ack_message(), handle_request(), handle_show_http(), handle_showmanconn(), handle_skinny_show_settings(), iax2_ack_registry(), iax2_prov_app(), iax2_trunk_queue(), iax_server(), iax_showframe(), jingle_create_candidates(), load_module(), manager_iax2_show_peer_list(), manager_iax2_show_registry(), mgcpsock_read(), oh323_addrcmp_str(), oh323_call(), oh323_set_rtp_peer(), parsing(), peercnt_add(), peercnt_modify(), peercnt_remove(), peers_data_provider_get(), phoneprov_callback(), process_request(), process_sdp(), purge_sessions(), raw_hangup(), realtime_peer(), realtime_user(), register_verify(), registry_rerequest(), resend_response(), rpt_exec(), sched_delay_remove(), score_address(), send_packet(), send_raw_client(), send_request(), send_response(), send_trunk(), set_config(), set_peercnt_limit(), setup_incoming_call(), show_main_page(), skinny_session(), skinny_set_rtp_peer(), socket_process(), socket_process_meta(), start_rtp(), stun_monitor_request(), timing_read(), unistim_info(), unistimsock_read(), and update_registry().

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 }

void ast_join ( char *  s,
size_t  len,
const char *const   w[] 
)

Definition at line 1454 of file utils.c.

Referenced by __ast_cli_generator(), ast_agi_register(), ast_agi_unregister(), ast_cli_command_full(), cli_console_sendtext(), console_sendtext(), find_best(), handle_cli_agi_show(), handle_cli_check_permissions(), handle_help(), help1(), help_workhorse(), set_full_cmd(), and write_htmldump().

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 }

void ast_md5_hash ( char *  output,
const char *  input 
)

Produces MD5 hash based on input string.

Definition at line 231 of file utils.c.

References md5(), MD5Final(), MD5Init(), and MD5Update().

Referenced by build_reply_digest(), and md5().

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 }

int ast_mkdir ( const char *  path,
int  mode 
)

Recursively create directory path.

Parameters:
path The directory path to create
mode The permissions with which to try to create the directory
Returns:
0 on success or an error code otherwise
Creates a directory path, creating parent directories as needed.

Definition at line 1900 of file utils.c.

References ast_strdupa, errno, and len().

Referenced by ast_monitor_change_fname(), ast_monitor_start(), conf_run(), create_dirpath(), dictate_exec(), init_logger(), load_module(), mixmonitor_exec(), reload_logger(), remove_from_queue(), setup_privacy_args(), sms_nextoutgoing(), sms_writefile(), testclient_exec(), testserver_exec(), and write_history().

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 }

int ast_parse_digest ( const char *  digest,
struct ast_http_digest d,
int  request,
int  pedantic 
)

Parse digest authorization header.

Returns:
Returns -1 if we have no auth or something wrong with digest.
Note:
This function may be used for Digest request and responce header. request arg is set to nonzero, if we parse Digest Request. pedantic arg can be set to nonzero if we need to do addition Digest check.

Definition at line 1957 of file utils.c.

References ast_free, ast_log(), ast_skip_blanks(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_string_field_set, ast_strlen_zero(), ast_http_digest::cnonce, LOG_WARNING, ast_http_digest::nc, ast_http_digest::nonce, ast_http_digest::qop, ast_http_digest::realm, ast_http_digest::response, str, ast_http_digest::uri, and ast_http_digest::username.

01957                                                                                                {
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 }

char* ast_process_quotes_and_slashes ( char *  start,
char  find,
char  replace_with 
)

Process a string to find and replace characters.

Parameters:
start The string to analyze
find The character to find
replace_with The character that will replace the one we are looking for

Definition at line 1428 of file utils.c.

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 }

int ast_pthread_create_detached_stack ( pthread_t *  thread,
pthread_attr_t *  attr,
void *(*)(void *)  start_routine,
void *  data,
size_t  stacksize,
const char *  file,
const char *  caller,
int  line,
const char *  start_fn 
)

Definition at line 1029 of file utils.c.

References ast_log(), ast_pthread_create_stack(), errno, and LOG_WARNING.

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 }

int ast_pthread_create_stack ( pthread_t *  thread,
pthread_attr_t *  attr,
void *(*)(void *)  start_routine,
void *  data,
size_t  stacksize,
const char *  file,
const char *  caller,
int  line,
const char *  start_fn 
)

Definition at line 980 of file utils.c.

References asprintf, ast_log(), ast_malloc, AST_STACKSIZE, dummy_start(), errno, LOG_WARNING, and pthread_create.

Referenced by ast_pthread_create_detached_stack().

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 }

long int ast_random ( void   ) 

Definition at line 1404 of file utils.c.

References ast_mutex_lock, ast_mutex_unlock, and randomlock.

Referenced by acf_rand_exec(), action_challenge(), add_sdp(), agent_new(), agi_handle_command(), ast_lock_path_lockfile(), ast_moh_files_next(), ast_rtp_change_source(), ast_rtp_new(), ast_udptl_new_with_bindaddr(), authenticate_request(), build_iv(), build_rand_pad(), build_reply_digest(), calc_metric(), calc_rxstamp(), caldav_write_event(), callno_hash(), create_channel_name(), generate_exchange_uuid(), generate_random_string(), get_trans_id(), gtalk_alloc(), gtalk_create_candidates(), gtalk_new(), handle_incoming(), handle_response_invite(), iax2_key_rotate(), iax2_start_transfer(), jingle_alloc(), jingle_create_candidates(), jingle_new(), load_module(), local_new(), make_email_file(), make_our_tag(), moh_files_alloc(), multicast_rtp_new(), ogg_vorbis_rewrite(), osp_create_uuid(), page_exec(), park_space_reserve(), process_weights(), reg_source_db(), registry_authrequest(), reqprep(), say_periodic_announcement(), sendmail(), set_nonce_randdata(), sip_alloc(), socket_read(), start_rtp(), stun_req_id(), transmit_invite(), transmit_register(), transmit_response_using_temp(), and try_firmware().

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 }

void ast_sha1_hash ( char *  output,
const char *  input 
)

Produces SHA1 hash based on input string.

Definition at line 247 of file utils.c.

References SHA1Input(), SHA1Reset(), and SHA1Result().

Referenced by aji_act_hook(), handle_call_token(), jabber_make_auth(), and sha1().

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 }

char* ast_strip_quoted ( char *  s,
const char *  beg_quotes,
const char *  end_quotes 
)

Strip leading/trailing whitespace and quotes from a string.

Parameters:
s The string to be stripped (will be modified).
beg_quotes The list of possible beginning quote characters.
end_quotes The list of matching ending quote characters.
Returns:
The stripped string.
This functions strips all leading and trailing whitespace characters from the input string, and returns a pointer to the resulting string. The string is modified in place.

It can also remove beginning and ending quote (or quote-like) characters, in matching pairs. If the first character of the string matches any character in beg_quotes, and the last character of the string is the matching character in end_quotes, then they are removed from the string.

Examples:

  ast_strip_quoted(buf, "\"", "\"");
  ast_strip_quoted(buf, "'", "'");
  ast_strip_quoted(buf, "[{(", "]})");

Definition at line 1212 of file utils.c.

References ast_strip().

Referenced by ast_register_file_version(), get_rdnis(), iftime(), load_values_config(), parse_allowed_methods(), parse_cookies(), and parse_dial_string().

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 }

int ast_true ( const char *  val  ) 

Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".

Return values:
0 if val is a NULL pointer.
-1 if "true".
0 otherwise.

Definition at line 1314 of file utils.c.

References ast_strlen_zero().

Referenced by __ast_http_load(), __ast_udptl_reload(), __init_manager(), _parse(), acf_curlopt_write(), acf_faxopt_write(), acf_transaction_write(), action_agent_logoff(), action_bridge(), action_originate(), action_updateconfig(), aji_create_client(), aji_load_config(), aoc_cli_debug_enable(), apply_general_options(), apply_option(), apply_outgoing(), ast_bridge_timelimit(), ast_jb_read_conf(), ast_plc_reload(), ast_tls_read_conf(), autopause2int(), build_device(), build_peer(), build_user(), config_parse_variables(), connect_link(), dahdi_r2_answer(), dahdi_set_dnd(), data_search_cmp_bool(), do_reload(), festival_exec(), func_channel_write_real(), func_inheritance_write(), func_mute_write(), get_encrypt_methods(), gtalk_load_config(), handle_common_options(), handle_logger_set_level(), handle_t38_options(), init_logger_chain(), jingle_load_config(), load_config(), load_config_meetme(), load_module(), load_moh_classes(), load_odbc_config(), load_rpt_vars(), local_ast_moh_start(), login_exec(), manager_add_queue_member(), manager_mutestream(), manager_pause_queue_member(), message_template_build(), misdn_answer(), odbc_load_module(), osp_load(), osplookup_exec(), parse_config(), parse_empty_options(), pbx_load_config(), pbx_load_users(), process_echocancel(), queue_set_global_params(), queue_set_param(), read_agent_config(), realtime_directory(), reload_config(), rtp_reload(), run_startup_commands(), search_directory(), search_directory_sub(), set_active(), set_config(), sla_load_config(), speex_write(), start_monitor_action(), strings_to_mask(), tds_load_module(), update_common_options(), xmldoc_get_syntax_cmd(), xmldoc_get_syntax_fun(), and xmldoc_get_syntax_manager().

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 }

struct timeval ast_tvadd ( struct timeval  a,
struct timeval  b 
)

Returns the sum of two timevals a + b.

Definition at line 1368 of file utils.c.

References ONE_MILLION, and tvfix().

Referenced by __get_from_jb(), acf_jabberreceive_read(), agent_hangup(), ast_audiohook_trigger_wait(), ast_channel_bridge(), ast_channel_cmpwhentohangup_tv(), ast_channel_setwhentohangup_tv(), ast_generic_bridge(), ast_poll2(), ast_rtp_dtmf_begin(), ast_rtp_dtmf_end_with_duration(), ast_sched_runq(), ast_smoother_read(), ast_translate(), calc_rxstamp(), calc_timestamp(), cli_tps_ping(), conf_run(), dial_exec_full(), do_cdr(), do_timing(), iax2_process_thread(), jb_get_and_deliver(), mb_poll_thread(), monmp3thread(), mp3_exec(), mwi_monitor_handler(), NBScat_exec(), sched_run(), sched_settime(), schedule_delivery(), sla_process_timers(), smdi_message_wait(), and timeout_write().

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 }

struct timeval ast_tvsub ( struct timeval  a,
struct timeval  b 
)

Returns the difference of two timevals a - b.

Definition at line 1382 of file utils.c.

References ONE_MILLION, and tvfix().

Referenced by __ast_rwlock_timedrdlock(), __ast_rwlock_timedwrlock(), ast_channel_bridge(), ast_poll2(), ast_sched_dump(), ast_translate(), ast_waitfor_nandfds(), calc_rxstamp(), calc_timestamp(), cli_tps_ping(), conf_run(), debug_check_frame_for_silence(), handle_showcalls(), handle_showuptime(), and pri_dchannel().

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 }

char* ast_unescape_c ( char *  s  ) 

Convert some C escape sequences.

(\b\f\n\r\t) 
into the equivalent characters. The string to be converted (will be modified).
Returns:
The converted string.

Definition at line 1248 of file utils.c.

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 }

char* ast_unescape_semicolon ( char *  s  ) 

Strip backslash for "escaped" semicolons, the string to be stripped (will be modified).

Returns:
The stripped string.

Definition at line 1229 of file utils.c.

Referenced by sip_cli_notify().

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 }

void ast_uri_decode ( char *  s  ) 

Decode URI, URN, URL (overwrite string).

Parameters:
s String to be decoded

Definition at line 417 of file utils.c.

Referenced by acf_curl_helper(), config_curl(), get_destination(), get_refer_info(), handle_request_invite(), http_decode(), parse_moved_contact(), realtime_curl(), realtime_multi_curl(), sip_new(), and uridecode().

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 }

char* ast_uri_encode ( const char *  string,
char *  outbuf,
int  buflen,
int  do_special_char 
)

Turn text string to URI-encoded XX version.

Note:
At this point, this function is encoding agnostic; it does not check whether it is fed legal UTF-8. We escape control characters (-), '', and all characters above 0x7F. If do_special_char == 1 we will convert all characters except alnum and mark. Outbuf needs to have more memory allocated than the instring to have room for the expansion. Every char that is converted is replaced by three ASCII characters.

Definition at line 384 of file utils.c.

Referenced by add_rpid(), config_curl(), destroy_curl(), initreqprep(), launch_asyncagi(), realtime_curl(), realtime_multi_curl(), require_curl(), store_curl(), update2_curl(), update_curl(), and uriencode().

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 }

int ast_utils_init ( void   ) 

Definition at line 1935 of file utils.c.

References ARRAY_LEN, ast_cli_register_multiple(), and base64_init().

Referenced by main().

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 }

char* ast_utils_which ( const char *  binary,
char *  fullpath,
size_t  fullpath_size 
)

Resolve a binary to a full pathname.

Parameters:
binary Name of the executable to resolve
fullpath Buffer to hold the complete pathname
fullpath_size Size of fullpath
Return values:
NULL binary was not found or the environment variable PATH is not set
Returns:
fullpath

Definition at line 2085 of file utils.c.

References ast_strdupa, and strsep().

Referenced by ast_bt_get_symbols().

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 }

int ast_wait_for_input ( int  fd,
int  ms 
)

Definition at line 1054 of file utils.c.

References ast_poll.

Referenced by ast_tcptls_server_root(), dahdi_test_timer(), and moh_class_destructor().

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 }

static int ast_wait_for_output ( int  fd,
int  timeoutms 
) [static]

Definition at line 1063 of file utils.c.

References ast_debug, ast_log(), ast_poll, ast_tvdiff_ms(), ast_tvnow(), errno, and LOG_ERROR.

Referenced by ast_careful_fwrite(), and ast_carefulwrite().

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 }

static void base64_init ( void   )  [static]

Definition at line 348 of file utils.c.

Referenced by ast_utils_init().

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 }

static void* dummy_start ( void *  data  )  [static]

Definition at line 936 of file utils.c.

References ast_free, AST_LIST_INSERT_TAIL, AST_MUTEX_KIND, ast_register_thread(), ast_threadstorage_get(), ast_unregister_thread(), thr_arg::data, lock_info, thr_arg::name, pthread_mutex_init, pthread_mutex_lock, pthread_mutex_unlock, thr_arg::start_routine, and strdup.

Referenced by ast_pthread_create_stack().

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 }

static size_t optimal_alloc_size ( size_t  size  )  [static]

Definition at line 1493 of file utils.c.

References ALLOCATOR_OVERHEAD.

Referenced by __ast_calloc_with_stringfields(), and add_string_pool().

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 }

static struct timeval tvfix ( struct timeval  a  )  [static]

Definition at line 1353 of file utils.c.

References ast_log(), LOG_WARNING, and ONE_MILLION.

Referenced by ast_tvadd(), and ast_tvsub().

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 }


Variable Documentation

ast_string_field __ast_string_field_empty = __ast_string_field_empty_buffer.string

Definition at line 1489 of file utils.c.

Referenced by __ast_calloc_with_stringfields(), and __ast_string_field_ptr_build_va().

struct { ... } __ast_string_field_empty_buffer [static]

ast_string_field_allocation allocation

Definition at line 1485 of file utils.c.

Referenced by __ast_calloc_with_stringfields().

char b2a[256] [static]

Definition at line 67 of file utils.c.

char base64[64] [static]

Definition at line 66 of file utils.c.

Referenced by aji_start_sasl().

int dev_urandom_fd [static]

Definition at line 445 of file utils.c.

ast_mutex_t fetchadd_m = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } [static]

Definition at line 1825 of file utils.c.

Referenced by ast_atomic_fetchadd_int_slow().

struct ast_threadstorage inet_ntoa_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_inet_ntoa_buf , .custom_init = NULL , } [static]

Definition at line 69 of file utils.c.

Referenced by ast_inet_ntoa().

ast_mutex_t randomlock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } [static]

glibc puts a lock inside random(3), so that the results are thread-safe. BSD libc (and others) do not.

Definition at line 1401 of file utils.c.

Referenced by ast_random().

char string[1]

Definition at line 1486 of file utils.c.

Referenced by channel_steer(), filter(), function_cop(), pp_each_user_helper(), and private_enum_init().


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