Mon Mar 12 2012 21:46:47

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"
Include dependency graph for utils.c:

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 BASE64 encoded text
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.
char * ast_escape_quoted (const char *string, char *outbuf, int buflen)
 escapes characters specified for quoted portions of sip messages
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.
struct hostent * ast_gethostbyname (const char *host, struct ast_hostent *hp)
 Re-entrant (thread safe) version of gethostbyname that replaces the standard gethostbyname (which is not thread safe)
const char * ast_inet_ntoa (struct in_addr ia)
 ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa
void ast_join (char *s, size_t len, const char *const w[])
void ast_md5_hash (char *output, const char *input)
 Produce 32 char MD5 hash of value.
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)
 Produce 40 char SHA1 hash of value.
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".
struct timeval ast_tvadd (struct timeval a, struct timeval b)
 Returns the sum of two timevals a + b.
struct 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)
 ast_uri_decode: Decode SIP URI, URN, URL (overwrite the 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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 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 1524 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 1381 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 1805 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.

{
   struct ast_string_field_mgr *mgr;
   struct ast_string_field_pool *pool;
   struct ast_string_field_pool **pool_head;
   size_t pool_size_needed = sizeof(*pool) + pool_size;
   size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed);
   void *allocation;
   unsigned int x;

#if defined(__AST_DEBUG_MALLOC)  
   if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
      return NULL;
   }
#else
   if (!(allocation = ast_calloc(num_structs, size_to_alloc))) {
      return NULL;
   }
#endif

   for (x = 0; x < num_structs; x++) {
      void *base = allocation + (size_to_alloc * x);
      const char **p;

      mgr = base + field_mgr_offset;
      pool_head = base + field_mgr_pool_offset;
      pool = base + struct_size;

      p = (const char **) pool_head + 1;
      while ((struct ast_string_field_mgr *) p != mgr) {
         *p++ = __ast_string_field_empty;
      }

      mgr->embedded_pool = pool;
      *pool_head = pool;
      pool->size = size_to_alloc - struct_size - sizeof(*pool);
#if defined(__AST_DEBUG_MALLOC)
      mgr->owner_file = file;
      mgr->owner_func = func;
      mgr->owner_line = lineno;
#endif
   }

   return allocation;
}
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 1644 of file utils.c.

References add_string_pool(), ast_alignof, ast_assert, ast_make_room_for, AST_STRING_FIELD_ALLOCATION, and ast_string_field_mgr::last_alloc.

Referenced by __ast_string_field_ptr_build_va().

{
   char *result = NULL;
   size_t space = (*pool_head)->size - (*pool_head)->used;
   size_t to_alloc;

   /* Make room for ast_string_field_allocation and make it a multiple of that. */
   to_alloc = ast_make_room_for(needed, ast_string_field_allocation);
   ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0);

   if (__builtin_expect(to_alloc > space, 0)) {
      size_t new_size = (*pool_head)->size;

      while (new_size < to_alloc) {
         new_size *= 2;
      }

#if defined(__AST_DEBUG_MALLOC)
      if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
         return NULL;
#else
      if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
         return NULL;
#endif
   }

   /* pool->base is always aligned (gcc aligned attribute). We ensure that
    * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation)
    * causing result to always be aligned as well; which in turn fixes that
    * AST_STRING_FIELD_ALLOCATION(result) is aligned. */
   result = (*pool_head)->base + (*pool_head)->used;
   (*pool_head)->used += to_alloc;
   (*pool_head)->active += needed;
   result += ast_alignof(ast_string_field_allocation);
   AST_STRING_FIELD_ALLOCATION(result) = needed;
   mgr->last_alloc = result;

   return result;
}
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 1577 of file utils.c.

References __ast_string_field_empty, 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.

{
   const char **p = (const char **) pool_head + 1;
   struct ast_string_field_pool *cur = NULL;
   struct ast_string_field_pool *preserve = NULL;

   /* clear fields - this is always necessary */
   while ((struct ast_string_field_mgr *) p != mgr) {
      *p++ = __ast_string_field_empty;
   }

   mgr->last_alloc = NULL;
#if defined(__AST_DEBUG_MALLOC)
   mgr->owner_file = file;
   mgr->owner_func = func;
   mgr->owner_line = lineno;
#endif
   if (needed > 0) {    /* allocate the initial pool */
      *pool_head = NULL;
      mgr->embedded_pool = NULL;
      return add_string_pool(mgr, pool_head, needed, file, lineno, func);
   }

   /* if there is an embedded pool, we can't actually release *all*
    * pools, we must keep the embedded one. if the caller is about
    * to free the structure that contains the stringfield manager
    * and embedded pool anyway, it will be freed as part of that
    * operation.
    */
   if ((needed < 0) && mgr->embedded_pool) {
      needed = 0;
   }

   if (needed < 0) {    /* reset all pools */
      cur = *pool_head;
   } else if (mgr->embedded_pool) { /* preserve the embedded pool */
      preserve = mgr->embedded_pool;
      cur = *pool_head;
   } else {       /* preserve the last pool */
      if (*pool_head == NULL) {
         ast_log(LOG_WARNING, "trying to reset empty pool\n");
         return -1;
      }
      preserve = *pool_head;
      cur = preserve->prev;
   }

   if (preserve) {
      preserve->prev = NULL;
      preserve->used = preserve->active = 0;
   }

   while (cur) {
      struct ast_string_field_pool *prev = cur->prev;

      if (cur != preserve) {
         ast_free(cur);
      }
      cur = prev;
   }

   *pool_head = preserve;

   return 0;
}
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 1790 of file utils.c.

References __ast_string_field_ptr_build_va().

{
   va_list ap1, ap2;

   va_start(ap1, format);
   va_start(ap2, format);     /* va_copy does not exist on FreeBSD */

   __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2);

   va_end(ap1);
   va_end(ap2);
}
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 1728 of file utils.c.

References __ast_string_field_alloc_space(), __ast_string_field_release_active(), ast_align_for, ast_alignof, ast_make_room_for, AST_STRING_FIELD_ALLOCATION, available(), and ast_string_field_mgr::last_alloc.

Referenced by __ast_string_field_ptr_build().

{
   size_t needed;
   size_t available;
   size_t space = (*pool_head)->size - (*pool_head)->used;
   ssize_t grow;
   char *target;

   /* if the field already has space allocated, try to reuse it;
      otherwise, try to use the empty space at the end of the current
      pool
   */
   if (*ptr != __ast_string_field_empty) {
      target = (char *) *ptr;
      available = AST_STRING_FIELD_ALLOCATION(*ptr);
      if (*ptr == mgr->last_alloc) {
         available += space;
      }
   } else {
      /* pool->used is always a multiple of ast_alignof(ast_string_field_allocation)
       * so we don't need to re-align anything here.
       */
      target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation);
      available = space - ast_alignof(ast_string_field_allocation);
   }

   needed = vsnprintf(target, available, format, ap1) + 1;

   va_end(ap1);

   if (needed > available) {
      /* the allocation could not be satisfied using the field's current allocation
         (if it has one), or the space available in the pool (if it does not). allocate
         space for it, adding a new string pool if necessary.
      */
      if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) {
         return;
      }
      vsprintf(target, format, ap2);
      __ast_string_field_release_active(*pool_head, *ptr);
      *ptr = target;
   } else if (*ptr != target) {
      /* the allocation was satisfied using available space in the pool, but not
         using the space already allocated to the field
      */
      __ast_string_field_release_active(*pool_head, *ptr);
      mgr->last_alloc = *ptr = target;
      AST_STRING_FIELD_ALLOCATION(target) = needed;
      (*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation);
      (*pool_head)->active += needed;
   } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) {
      /* the allocation was satisfied by using available space in the pool *and*
         the field was the last allocated field from the pool, so it grew
      */
      AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
      (*pool_head)->used += ast_align_for(grow, ast_string_field_allocation);
      (*pool_head)->active += grow;
   }
}
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 1685 of file utils.c.

References AST_STRING_FIELD_ALLOCATION, and ast_string_field_mgr::last_alloc.

{
   ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr);
   size_t space = (*pool_head)->size - (*pool_head)->used;

   if (*ptr != mgr->last_alloc) {
      return 1;
   }

   if (space < grow) {
      return 1;
   }

   (*pool_head)->used += grow;
   (*pool_head)->active += grow;
   AST_STRING_FIELD_ALLOCATION(*ptr) += grow;

   return 0;
}
void __ast_string_field_release_active ( struct ast_string_field_pool pool_head,
const ast_string_field  ptr 
)

Definition at line 1707 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().

{
   struct ast_string_field_pool *pool, *prev;

   if (ptr == __ast_string_field_empty) {
      return;
   }

   for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) {
      if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) {
         pool->active -= AST_STRING_FIELD_ALLOCATION(ptr);
         if ((pool->active == 0) && prev) {
            prev->prev = pool->prev;
            ast_free(pool);
         }
         break;
      }
   }
}
static void __init_inet_ntoa_buf ( void  ) [static]

Definition at line 69 of file utils.c.

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

Definition at line 2100 of file utils.c.

References MALLOC_FAILURE_MSG, and vasprintf().

{
   int res;
   va_list ap;

   va_start(ap, fmt);
   if ((res = vasprintf(ret, fmt, ap)) == -1) {
      MALLOC_FAILURE_MSG;
   }
   va_end(ap);

   return res;
}
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 1541 of file utils.c.

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

Referenced by __ast_string_field_alloc_space(), and __ast_string_field_init().

{
   struct ast_string_field_pool *pool;
   size_t alloc_size = optimal_alloc_size(sizeof(*pool) + size);

#if defined(__AST_DEBUG_MALLOC)
   if (!(pool = __ast_calloc(1, alloc_size, file, lineno, func))) {
      return -1;
   }
#else
   if (!(pool = ast_calloc(1, alloc_size))) {
      return -1;
   }
#endif

   pool->prev = *pool_head;
   pool->size = alloc_size - sizeof(*pool);
   *pool_head = pool;
   mgr->last_alloc = NULL;

   return 0;
}
int ast_atomic_fetchadd_int_slow ( volatile int *  p,
int  v 
)

Definition at line 1857 of file utils.c.

References ast_mutex_lock, ast_mutex_unlock, and fetchadd_m.

{
   int ret;
   ast_mutex_lock(&fetchadd_m);
   ret = *p;
   *p += v;
   ast_mutex_unlock(&fetchadd_m);
   return ret;
}
int ast_base64decode ( unsigned char *  dst,
const char *  src,
int  max 
)

decode BASE64 encoded text

Decode data from base64.

Definition at line 267 of file utils.c.

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

{
   int cnt = 0;
   unsigned int byte = 0;
   unsigned int bits = 0;
   int incnt = 0;
   while(*src && *src != '=' && (cnt < max)) {
      /* Shift in 6 bits of input */
      byte <<= 6;
      byte |= (b2a[(int)(*src)]) & 0x3f;
      bits += 6;
      src++;
      incnt++;
      /* If we have at least 8 bits left over, take that character 
         off the top */
      if (bits >= 8)  {
         bits -= 8;
         *dst = (byte >> bits) & 0xff;
         dst++;
         cnt++;
      }
   }
   /* Don't worry about left over bits, they're extra anyway */
   return cnt;
}
int ast_base64encode ( char *  dst,
const unsigned char *  src,
int  srclen,
int  max 
)

Encode data in base64.

Parameters:
dstthe destination buffer
srcthe source data to be encoded
srclenthe number of bytes present in the source buffer
maxthe maximum number of bytes to write into the destination buffer, *including* the terminating NULL character.

Definition at line 345 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().

{
   return ast_base64encode_full(dst, src, srclen, max, 0);
}
int ast_base64encode_full ( char *  dst,
const unsigned char *  src,
int  srclen,
int  max,
int  linebreaks 
)

encode text to BASE64 coding

Definition at line 294 of file utils.c.

Referenced by ast_base64encode().

{
   int cnt = 0;
   int col = 0;
   unsigned int byte = 0;
   int bits = 0;
   int cntin = 0;
   /* Reserve space for null byte at end of string */
   max--;
   while ((cntin < srclen) && (cnt < max)) {
      byte <<= 8;
      byte |= *(src++);
      bits += 8;
      cntin++;
      if ((bits == 24) && (cnt + 4 <= max)) {
         *dst++ = base64[(byte >> 18) & 0x3f];
         *dst++ = base64[(byte >> 12) & 0x3f];
         *dst++ = base64[(byte >> 6) & 0x3f];
         *dst++ = base64[byte & 0x3f];
         cnt += 4;
         col += 4;
         bits = 0;
         byte = 0;
      }
      if (linebreaks && (cnt < max) && (col == 64)) {
         *dst++ = '\n';
         cnt++;
         col = 0;
      }
   }
   if (bits && (cnt + 4 <= max)) {
      /* Add one last character for the remaining bits, 
         padding the rest with 0 */
      byte <<= 24 - bits;
      *dst++ = base64[(byte >> 18) & 0x3f];
      *dst++ = base64[(byte >> 12) & 0x3f];
      if (bits == 16)
         *dst++ = base64[(byte >> 6) & 0x3f];
      else
         *dst++ = '=';
      *dst++ = '=';
      cnt += 4;
   }
   if (linebreaks && (cnt < max)) {
      *dst++ = '\n';
      cnt++;
   }
   *dst = '\0';
   return cnt;
}
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:
buffercurrent position in buffer to place string into (will be updated on return)
spaceremaining space in buffer (will be updated on return)
fmtprintf-style format string
Return values:
0on success
non-zeroon failure.

Definition at line 1335 of file utils.c.

References ast_build_string_va().

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

{
   va_list ap;
   int result;

   va_start(ap, fmt);
   result = ast_build_string_va(buffer, space, fmt, ap);
   va_end(ap);

   return result;
}
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:
buffercurrent position in buffer to place string into (will be updated on return)
spaceremaining space in buffer (will be updated on return)
fmtprintf-style format string
apvarargs list of arguments for format

Definition at line 1316 of file utils.c.

Referenced by ast_build_string().

{
   int result;

   if (!buffer || !*buffer || !space || !*space)
      return -1;

   result = vsnprintf(*buffer, *space, fmt, ap);

   if (result < 0)
      return -1;
   else if (result > *space)
      result = *space;

   *buffer += result;
   *space -= result;
   return 0;
}
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:
fthe file stream to write to
fdthe file description to poll on to know when the file stream can be written to without blocking.
sthe buffer to write from
lenthe number of bytes to write
timeoutmsThe 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:
0success
-1error

Definition at line 1190 of file utils.c.

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

Referenced by send_string().

{
   struct timeval start = ast_tvnow();
   int n = 0;
   int elapsed = 0;

   while (len) {
      if (ast_wait_for_output(fd, timeoutms - elapsed)) {
         /* poll returned a fatal error, so bail out immediately. */
         return -1;
      }

      /* Clear any errors from a previous write */
      clearerr(f);

      n = fwrite(src, 1, len, f);

      if (ferror(f) && errno != EINTR && errno != EAGAIN) {
         /* fatal error from fwrite() */
         if (!feof(f)) {
            /* Don't spam the logs if it was just that the connection is closed. */
            ast_log(LOG_ERROR, "fwrite() returned error: %s\n", strerror(errno));
         }
         n = -1;
         break;
      }

      /* Update for data already written to the socket */
      len -= n;
      src += n;

      elapsed = ast_tvdiff_ms(ast_tvnow(), start);
      if (elapsed >= timeoutms) {
         /* We've taken too long to write 
          * This is only an error condition if we haven't finished writing. */
         n = len ? -1 : 0;
         break;
      }
   }

   while (fflush(f)) {
      if (errno == EAGAIN || errno == EINTR) {
         continue;
      }
      if (!feof(f)) {
         /* Don't spam the logs if it was just that the connection is closed. */
         ast_log(LOG_ERROR, "fflush() returned error: %s\n", strerror(errno));
      }
      n = -1;
      break;
   }

   return n < 0 ? -1 : 0;
}
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 1149 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().

{
   struct timeval start = ast_tvnow();
   int res = 0;
   int elapsed = 0;

   while (len) {
      if (ast_wait_for_output(fd, timeoutms - elapsed)) {
         return -1;
      }

      res = write(fd, s, len);

      if (res < 0 && errno != EAGAIN && errno != EINTR) {
         /* fatal error from write() */
         ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
         return -1;
      }

      if (res < 0) {
         /* It was an acceptable error */
         res = 0;
      }

      /* Update how much data we have left to write */
      len -= res;
      s += res;
      res = 0;

      elapsed = ast_tvdiff_ms(ast_tvnow(), start);
      if (elapsed >= timeoutms) {
         /* We've taken too long to write 
          * This is only an error condition if we haven't finished writing. */
         res = len ? -1 : 0;
         break;
      }
   }

   return res;
}
void ast_enable_packet_fragmentation ( int  sock)

Disable PMTU discovery on a socket.

Parameters:
sockThe 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 1920 of file utils.c.

References ast_log(), and LOG_WARNING.

Referenced by ast_netsock_bindaddr(), and reload_config().

{
#if defined(HAVE_IP_MTU_DISCOVER)
   int val = IP_PMTUDISC_DONT;
   
   if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
      ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
#endif /* HAVE_IP_MTU_DISCOVER */
}
char* ast_escape_quoted ( const char *  string,
char *  outbuf,
int  buflen 
)

escapes characters specified for quoted portions of sip messages

Escape characters found in a quoted string.

Definition at line 419 of file utils.c.

References string.

Referenced by initreqprep().

{
   const char *ptr  = string;
   char *out = outbuf;
   char *allow = "\t\v !"; /* allow LWS (minus \r and \n) and "!" */

   while (*ptr && out - outbuf < buflen - 1) {
      if (!(strchr(allow, *ptr))
         && !(*ptr >= '#' && *ptr <= '[') /* %x23 - %x5b */
         && !(*ptr >= ']' && *ptr <= '~') /* %x5d - %x7e */
         && !((unsigned char) *ptr > 0x7f)) {             /* UTF8-nonascii */

         if (out - outbuf >= buflen - 2) {
            break;
         }
         out += sprintf(out, "\\%c", (unsigned char) *ptr);
      } else {
         *out = *ptr;
         out++;
      }
      ptr++;
   }

   if (buflen) {
      *out = '\0';
   }

   return outbuf;
}
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:
0if val is a NULL pointer.
-1if "true".
0otherwise.

Definition at line 1364 of file utils.c.

References ast_strlen_zero().

Referenced by __ast_udptl_reload(), acf_faxopt_write(), acf_transaction_write(), actual_load_config(), 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(), reload_config(), rtp_reload(), run_agi(), set_config(), set_insecure_flags(), sla_build_trunk(), and strings_to_mask().

{
   if (ast_strlen_zero(s))
      return 0;

   /* Determine if this is a false value */
   if (!strcasecmp(s, "no") ||
       !strcasecmp(s, "false") ||
       !strcasecmp(s, "n") ||
       !strcasecmp(s, "f") ||
       !strcasecmp(s, "0") ||
       !strcasecmp(s, "off"))
      return -1;

   return 0;
}
int ast_get_time_t ( const char *  src,
time_t *  dst,
time_t  _default,
int *  consumed 
)

get values from config variables.

Definition at line 1897 of file utils.c.

References ast_strlen_zero().

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

{
   long t;
   int scanned;

   if (dst == NULL)
      return -1;

   *dst = _default;

   if (ast_strlen_zero(src))
      return -1;

   /* only integer at the moment, but one day we could accept more formats */
   if (sscanf(src, "%30ld%n", &t, &scanned) == 1) {
      *dst = t;
      if (consumed)
         *consumed = scanned;
      return 0;
   } else
      return -1;
}
int ast_get_timeval ( const char *  src,
struct timeval *  dst,
struct timeval  _default,
int *  consumed 
)

get values from config variables.

Definition at line 1870 of file utils.c.

References ast_strlen_zero().

Referenced by acf_strftime().

{
   long double dtv = 0.0;
   int scanned;

   if (dst == NULL)
      return -1;

   *dst = _default;

   if (ast_strlen_zero(src))
      return -1;

   /* only integer at the moment, but one day we could accept more formats */
   if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) {
      dst->tv_sec = dtv;
      dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
      if (consumed)
         *consumed = scanned;
      return 0;
   } else
      return -1;
}
struct hostent* ast_gethostbyname ( const char *  host,
struct ast_hostent hp 
) [read]

Re-entrant (thread safe) version of gethostbyname that replaces the standard gethostbyname (which is not thread safe)

Thread-safe gethostbyname function to use in Asterisk.

Definition at line 183 of file utils.c.

References ast_hostent::buf, and ast_hostent::hp.

Referenced by __ast_http_load(), app_exec(), ast_parse_arg(), build_peer(), config_load(), config_parse_variables(), create_addr(), festival_exec(), gtalk_load_config(), 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().

{
   int res;
   int herrno;
   int dots = 0;
   const char *s;
   struct hostent *result = NULL;
   /* Although it is perfectly legitimate to lookup a pure integer, for
      the sake of the sanity of people who like to name their peers as
      integers, we break with tradition and refuse to look up a
      pure integer */
   s = host;
   res = 0;
   while (s && *s) {
      if (*s == '.')
         dots++;
      else if (!isdigit(*s))
         break;
      s++;
   }
   if (!s || !*s) {
      /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
      if (dots != 3)
         return NULL;
      memset(hp, 0, sizeof(struct ast_hostent));
      hp->hp.h_addrtype = AF_INET;
      hp->hp.h_addr_list = (void *) hp->buf;
      hp->hp.h_addr = hp->buf + sizeof(void *);
      /* For AF_INET, this will always be 4 */
      hp->hp.h_length = 4;
      if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
         return &hp->hp;
      return NULL;
      
   }
#ifdef HAVE_GETHOSTBYNAME_R_5
   result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);

   if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
      return NULL;
#else
   res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);

   if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
      return NULL;
#endif
   return &hp->hp;
}
const char* ast_inet_ntoa ( struct in_addr  ia)

ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa

thread-safe replacement for inet_ntoa().

Definition at line 467 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(), auth_http_callback(), authenticate(), calltoken_required(), check_access(), config_load(), create_client(), data_get_xml_add_child(), data_result_manager_output(), data_result_print_cli_node(), do_message(), 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(), generic_http_callback(), get_input(), 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(), reload_config(), resend_response(), rpt_exec(), sched_delay_remove(), score_address(), send_packet(), send_raw_client(), send_request(), send_response(), send_trunk(), session_do(), 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().

{
   char *buf;

   if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
      return "";

   return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
}
void ast_join ( char *  s,
size_t  len,
const char *const  w[] 
)

Definition at line 1487 of file utils.c.

References len().

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().

{
   int x, ofs = 0;
   const char *src;

   /* Join words into a string */
   if (!s)
      return;
   for (x = 0; ofs < len && w[x]; x++) {
      if (x > 0)
         s[ofs++] = ' ';
      for (src = w[x]; *src && ofs < len; src++)
         s[ofs++] = *src;
   }
   if (ofs == len)
      ofs--;
   s[ofs] = '\0';
}
void ast_md5_hash ( char *  output,
const char *  input 
)

Produce 32 char MD5 hash of value.

Produces MD5 hash based on input string.

Definition at line 233 of file utils.c.

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

Referenced by __init_manager(), auth_exec(), auth_http_callback(), build_reply_digest(), check_auth(), and md5().

{
   struct MD5Context md5;
   unsigned char digest[16];
   char *ptr;
   int x;

   MD5Init(&md5);
   MD5Update(&md5, (const unsigned char *) input, strlen(input));
   MD5Final(digest, &md5);
   ptr = output;
   for (x = 0; x < 16; x++)
      ptr += sprintf(ptr, "%2.2x", digest[x]);
}
int ast_mkdir ( const char *  path,
int  mode 
)

Recursively create directory path.

Parameters:
pathThe directory path to create
modeThe 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 1930 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(), record_exec(), reload_logger(), remove_from_queue(), setup_privacy_args(), sms_nextoutgoing(), sms_writefile(), testclient_exec(), testserver_exec(), and write_history().

{
   char *ptr;
   int len = strlen(path), count = 0, x, piececount = 0;
   char *tmp = ast_strdupa(path);
   char **pieces;
   char *fullpath = alloca(len + 1);
   int res = 0;

   for (ptr = tmp; *ptr; ptr++) {
      if (*ptr == '/')
         count++;
   }

   /* Count the components to the directory path */
   pieces = alloca(count * sizeof(*pieces));
   for (ptr = tmp; *ptr; ptr++) {
      if (*ptr == '/') {
         *ptr = '\0';
         pieces[piececount++] = ptr + 1;
      }
   }

   *fullpath = '\0';
   for (x = 0; x < piececount; x++) {
      /* This looks funky, but the buffer is always ideally-sized, so it's fine. */
      strcat(fullpath, "/");
      strcat(fullpath, pieces[x]);
      res = mkdir(fullpath, mode);
      if (res && errno != EEXIST)
         return errno;
   }
   return 0;
}
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 1987 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, ast_http_digest::uri, and ast_http_digest::username.

Referenced by auth_http_callback().

                                                                                               {
   int i;
   char *c, key[512], val[512];
   struct ast_str *str = ast_str_create(16);

   if (ast_strlen_zero(digest) || !d || !str) {
      ast_free(str);
      return -1;
   }

   ast_str_set(&str, 0, "%s", digest);

   c = ast_skip_blanks(ast_str_buffer(str));

   if (strncasecmp(c, "Digest ", strlen("Digest "))) {
      ast_log(LOG_WARNING, "Missing Digest.\n");
      ast_free(str);
      return -1;
   }
   c += strlen("Digest ");

   /* lookup for keys/value pair */
   while (*c && *(c = ast_skip_blanks(c))) {
      /* find key */
      i = 0;
      while (*c && *c != '=' && *c != ',' && !isspace(*c)) {
         key[i++] = *c++;
      }
      key[i] = '\0';
      c = ast_skip_blanks(c);
      if (*c == '=') {
         c = ast_skip_blanks(++c);
         i = 0;
         if (*c == '\"') {
            /* in quotes. Skip first and look for last */
            c++;
            while (*c && *c != '\"') {
               if (*c == '\\' && c[1] != '\0') { /* unescape chars */
                  c++;
               }
               val[i++] = *c++;
            }
         } else {
            /* token */
            while (*c && *c != ',' && !isspace(*c)) {
               val[i++] = *c++;
            }
         }
         val[i] = '\0';
      }

      while (*c && *c != ',') {
         c++;
      }
      if (*c) {
         c++;
      }

      if (!strcasecmp(key, "username")) {
         ast_string_field_set(d, username, val);
      } else if (!strcasecmp(key, "realm")) {
         ast_string_field_set(d, realm, val);
      } else if (!strcasecmp(key, "nonce")) {
         ast_string_field_set(d, nonce, val);
      } else if (!strcasecmp(key, "uri")) {
         ast_string_field_set(d, uri, val);
      } else if (!strcasecmp(key, "domain")) {
         ast_string_field_set(d, domain, val);
      } else if (!strcasecmp(key, "response")) {
         ast_string_field_set(d, response, val);
      } else if (!strcasecmp(key, "algorithm")) {
         if (strcasecmp(val, "MD5")) {
            ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", val);
            return -1;
         }
      } else if (!strcasecmp(key, "cnonce")) {
         ast_string_field_set(d, cnonce, val);
      } else if (!strcasecmp(key, "opaque")) {
         ast_string_field_set(d, opaque, val);
      } else if (!strcasecmp(key, "qop") && !strcasecmp(val, "auth")) {
         d->qop = 1;
      } else if (!strcasecmp(key, "nc")) {
         unsigned long u;
         if (sscanf(val, "%30lx", &u) != 1) {
            ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", val);
            return -1;
         }
         ast_string_field_set(d, nc, val);
      }
   }
   ast_free(str);

   /* Digest checkout */
   if (ast_strlen_zero(d->realm) || ast_strlen_zero(d->nonce)) {
      /* "realm" and "nonce" MUST be always exist */
      return -1;
   }

   if (!request) {
      /* Additional check for Digest response */
      if (ast_strlen_zero(d->username) || ast_strlen_zero(d->uri) || ast_strlen_zero(d->response)) {
         return -1;
      }

      if (pedantic && d->qop && (ast_strlen_zero(d->cnonce) || ast_strlen_zero(d->nc))) {
         return -1;
      }
   }

   return 0;
}
char* ast_process_quotes_and_slashes ( char *  start,
char  find,
char  replace_with 
)

Process a string to find and replace characters.

Parameters:
startThe string to analyze
findThe character to find
replace_withThe character that will replace the one we are looking for

Definition at line 1461 of file utils.c.

{
   char *dataPut = start;
   int inEscape = 0;
   int inQuotes = 0;

   for (; *start; start++) {
      if (inEscape) {
         *dataPut++ = *start;       /* Always goes verbatim */
         inEscape = 0;
      } else {
         if (*start == '\\') {
            inEscape = 1;      /* Do not copy \ into the data */
         } else if (*start == '\'') {
            inQuotes = 1 - inQuotes;   /* Do not copy ' into the data */
         } else {
            /* Replace , with |, unless in quotes */
            *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
         }
      }
   }
   if (start != dataPut)
      *dataPut = 0;
   return dataPut;
}
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 1062 of file utils.c.

References ast_log(), ast_pthread_create_stack(), errno, LOG_WARNING, and thr_arg::start_routine.

{
   unsigned char attr_destroy = 0;
   int res;

   if (!attr) {
      attr = alloca(sizeof(*attr));
      pthread_attr_init(attr);
      attr_destroy = 1;
   }

   if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
      ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno));

   res = ast_pthread_create_stack(thread, attr, start_routine, data, 
                                  stacksize, file, caller, line, start_fn);

   if (attr_destroy)
      pthread_attr_destroy(attr);

   return res;
}
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 1013 of file utils.c.

References asprintf(), ast_log(), ast_malloc, AST_STACKSIZE, thr_arg::data, dummy_start(), errno, LOG_WARNING, thr_arg::name, pthread_create, and thr_arg::start_routine.

Referenced by ast_pthread_create_detached_stack().

{
#if !defined(LOW_MEMORY)
   struct thr_arg *a;
#endif

   if (!attr) {
      attr = alloca(sizeof(*attr));
      pthread_attr_init(attr);
   }

#ifdef __linux__
   /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
      which is kind of useless. Change this here to
      PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
      priority will propagate down to new threads by default.
      This does mean that callers cannot set a different priority using
      PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
      the priority afterwards with pthread_setschedparam(). */
   if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
      ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
#endif

   if (!stacksize)
      stacksize = AST_STACKSIZE;

   if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
      ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));

#if !defined(LOW_MEMORY)
   if ((a = ast_malloc(sizeof(*a)))) {
      a->start_routine = start_routine;
      a->data = data;
      start_routine = dummy_start;
      if (asprintf(&a->name, "%-20s started at [%5d] %s %s()",
              start_fn, line, file, caller) < 0) {
         ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
         a->name = NULL;
      }
      data = a;
   }
#endif /* !LOW_MEMORY */

   return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
}
long int ast_random ( void  )

Definition at line 1437 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(), auth_http_callback(), authenticate_request(), build_gateway(), 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(), generic_http_callback(), 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(), try_calling(), and try_firmware().

{
   long int res;
#ifdef HAVE_DEV_URANDOM
   if (dev_urandom_fd >= 0) {
      int read_res = read(dev_urandom_fd, &res, sizeof(res));
      if (read_res > 0) {
         long int rm = RAND_MAX;
         res = res < 0 ? ~res : res;
         rm++;
         return res % rm;
      }
   }
#endif
#ifdef linux
   res = random();
#else
   ast_mutex_lock(&randomlock);
   res = random();
   ast_mutex_unlock(&randomlock);
#endif
   return res;
}
void ast_sha1_hash ( char *  output,
const char *  input 
)

Produce 40 char SHA1 hash of value.

Produces SHA1 hash based on input string.

Definition at line 249 of file utils.c.

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

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

{
   struct SHA1Context sha;
   char *ptr;
   int x;
   uint8_t Message_Digest[20];

   SHA1Reset(&sha);
   
   SHA1Input(&sha, (const unsigned char *) input, strlen(input));

   SHA1Result(&sha, Message_Digest);
   ptr = output;
   for (x = 0; x < 20; x++)
      ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
}
char* ast_strip_quoted ( char *  s,
const char *  beg_quotes,
const char *  end_quotes 
)

Strip leading/trailing whitespace and quotes from a string.

Parameters:
sThe string to be stripped (will be modified).
beg_quotesThe list of possible beginning quote characters.
end_quotesThe 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 1245 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().

{
   char *e;
   char *q;

   s = ast_strip(s);
   if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
      e = s + strlen(s) - 1;
      if (*e == *(end_quotes + (q - beg_quotes))) {
         s++;
         *e = '\0';
      }
   }

   return s;
}
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:
0if val is a NULL pointer.
-1if "true".
0otherwise.

Definition at line 1347 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(), actual_load_config(), 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_readconfig(), ast_tls_read_conf(), autopause2int(), build_device(), build_gateway(), build_peer(), build_user(), config_parse_variables(), connect_link(), dahdi_accept_r2_call_exec(), 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_mfcr2_call_files(), handle_t38_options(), init_logger_chain(), jingle_load_config(), load_config(), load_config_meetme(), load_module(), load_modules(), 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(), parkinglot_config_read(), parse_config(), parse_empty_options(), pbx_load_config(), pbx_load_users(), process_config(), process_dahdi(), 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(), smdi_load(), 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().

{
   if (ast_strlen_zero(s))
      return 0;

   /* Determine if this is a true value */
   if (!strcasecmp(s, "yes") ||
       !strcasecmp(s, "true") ||
       !strcasecmp(s, "y") ||
       !strcasecmp(s, "t") ||
       !strcasecmp(s, "1") ||
       !strcasecmp(s, "on"))
      return -1;

   return 0;
}
struct timeval ast_tvsub ( struct timeval  a,
struct timeval  b 
) [read]

Returns the difference of two timevals a - b.

Definition at line 1415 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().

{
   /* consistency checks to guarantee usec in 0..999999 */
   a = tvfix(a);
   b = tvfix(b);
   a.tv_sec -= b.tv_sec;
   a.tv_usec -= b.tv_usec;
   if (a.tv_usec < 0) {
      a.tv_sec-- ;
      a.tv_usec += ONE_MILLION;
   }
   return a;
}
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 1281 of file utils.c.

{
   char c, *ret, *dst;

   if (src == NULL)
      return NULL;
   for (ret = dst = src; (c = *src++); *dst++ = c ) {
      if (c != '\\')
         continue;   /* copy char at the end of the loop */
      switch ((c = *src++)) {
      case '\0':  /* special, trailing '\' */
         c = '\\';
         break;
      case 'b':   /* backspace */
         c = '\b';
         break;
      case 'f':   /* form feed */
         c = '\f';
         break;
      case 'n':
         c = '\n';
         break;
      case 'r':
         c = '\r';
         break;
      case 't':
         c = '\t';
         break;
      }
      /* default, use the char literally */
   }
   *dst = '\0';
   return ret;
}
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 1262 of file utils.c.

Referenced by sip_cli_notify().

{
   char *e;
   char *work = s;

   while ((e = strchr(work, ';'))) {
      if ((e > work) && (*(e-1) == '\\')) {
         memmove(e - 1, e, strlen(e) + 1);
         work = e;
      } else {
         work = e + 1;
      }
   }

   return s;
}
void ast_uri_decode ( char *  s)

ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string)

Decode URI, URN, URL (overwrite string)

Definition at line 450 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().

{
   char *o;
   unsigned int tmp;

   for (o = s; *s; s++, o++) {
      if (*s == '%' && s[1] != '\0' && s[2] != '\0' && sscanf(s + 1, "%2x", &tmp) == 1) {
         /* have '%', two chars and correct parsing */
         *o = tmp;
         s += 2;  /* Will be incremented once more when we break out */
      } else /* all other cases, just copy */
         *o = *s;
   }
   *o = '\0';
}
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 386 of file utils.c.

References string.

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

{
   const char *ptr  = string; /* Start with the string */
   char *out = outbuf;
   const char *mark = "-_.!~*'()"; /* no encode set, RFC 2396 section 2.3, RFC 3261 sec 25 */

   while (*ptr && out - outbuf < buflen - 1) {
      if ((const signed char) *ptr < 32 || *ptr == 0x7f || *ptr == '%' ||
            (do_special_char &&
            !(*ptr >= '0' && *ptr <= '9') &&      /* num */
            !(*ptr >= 'A' && *ptr <= 'Z') &&      /* ALPHA */
            !(*ptr >= 'a' && *ptr <= 'z') &&      /* alpha */
            !strchr(mark, *ptr))) {               /* mark set */
         if (out - outbuf >= buflen - 3) {
            break;
         }

         out += sprintf(out, "%%%02X", (unsigned char) *ptr);
      } else {
         *out = *ptr;   /* Continue copying the string */
         out++;
      }
      ptr++;
   }

   if (buflen) {
      *out = '\0';
   }

   return outbuf;
}
int ast_utils_init ( void  )

Definition at line 1965 of file utils.c.

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

Referenced by main().

{
#ifdef HAVE_DEV_URANDOM
   dev_urandom_fd = open("/dev/urandom", O_RDONLY);
#endif
   base64_init();
#ifdef DEBUG_THREADS
#if !defined(LOW_MEMORY)
   ast_cli_register_multiple(utils_cli, ARRAY_LEN(utils_cli));
#endif
#endif
   return 0;
}
char* ast_utils_which ( const char *  binary,
char *  fullpath,
size_t  fullpath_size 
)

Resolve a binary to a full pathname.

Parameters:
binaryName of the executable to resolve
fullpathBuffer to hold the complete pathname
fullpath_sizeSize of fullpath
Return values:
NULLbinary was not found or the environment variable PATH is not set
Returns:
fullpath

Definition at line 2115 of file utils.c.

References ast_strdupa, and strsep().

Referenced by ast_bt_get_symbols().

{
   const char *envPATH = getenv("PATH");
   char *tpath, *path;
   struct stat unused;
   if (!envPATH) {
      return NULL;
   }
   tpath = ast_strdupa(envPATH);
   while ((path = strsep(&tpath, ":"))) {
      snprintf(fullpath, fullpath_size, "%s/%s", path, binary);
      if (!stat(fullpath, &unused)) {
         return fullpath;
      }
   }
   return NULL;
}
int ast_wait_for_input ( int  fd,
int  ms 
)

Definition at line 1087 of file utils.c.

References ast_poll.

Referenced by _sip_tcp_helper_thread(), action_waitevent(), ast_tcptls_server_root(), dahdi_test_timer(), get_input(), and moh_class_destructor().

{
   struct pollfd pfd[1];
   memset(pfd, 0, sizeof(pfd));
   pfd[0].fd = fd;
   pfd[0].events = POLLIN|POLLPRI;
   return ast_poll(pfd, 1, ms);
}
static int ast_wait_for_output ( int  fd,
int  timeoutms 
) [static]

Definition at line 1096 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().

{
   struct pollfd pfd = {
      .fd = fd,
      .events = POLLOUT,
   };
   int res;
   struct timeval start = ast_tvnow();
   int elapsed = 0;

   /* poll() until the fd is writable without blocking */
   while ((res = ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
      if (res == 0) {
         /* timed out. */
#ifndef STANDALONE
         ast_debug(1, "Timed out trying to write\n");
#endif
         return -1;
      } else if (res == -1) {
         /* poll() returned an error, check to see if it was fatal */

         if (errno == EINTR || errno == EAGAIN) {
            elapsed = ast_tvdiff_ms(ast_tvnow(), start);
            if (elapsed >= timeoutms) {
               return -1;
            }
            /* This was an acceptable error, go back into poll() */
            continue;
         }

         /* Fatal error, bail. */
         ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno));

         return -1;
      }
      elapsed = ast_tvdiff_ms(ast_tvnow(), start);
      if (elapsed >= timeoutms) {
         return -1;
      }
   }

   return 0;
}
static void base64_init ( void  ) [static]

Definition at line 350 of file utils.c.

Referenced by ast_utils_init().

{
   int x;
   memset(b2a, -1, sizeof(b2a));
   /* Initialize base-64 Conversion table */
   for (x = 0; x < 26; x++) {
      /* A-Z */
      base64[x] = 'A' + x;
      b2a['A' + x] = x;
      /* a-z */
      base64[x + 26] = 'a' + x;
      b2a['a' + x] = x + 26;
      /* 0-9 */
      if (x < 10) {
         base64[x + 52] = '0' + x;
         b2a['0' + x] = x + 52;
      }
   }
   base64[62] = '+';
   base64[63] = '/';
   b2a[(int)'+'] = 62;
   b2a[(int)'/'] = 63;
}
static void* dummy_start ( void *  data) [static]

Definition at line 969 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().

{
   void *ret;
   struct thr_arg a = *((struct thr_arg *) data);  /* make a local copy */
#ifdef DEBUG_THREADS
   struct thr_lock_info *lock_info;
   pthread_mutexattr_t mutex_attr;
#endif

   /* note that even though data->name is a pointer to allocated memory,
      we are not freeing it here because ast_register_thread is going to
      keep a copy of the pointer and then ast_unregister_thread will
      free the memory
   */
   ast_free(data);
   ast_register_thread(a.name);
   pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());

#ifdef DEBUG_THREADS
   if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
      return NULL;

   lock_info->thread_id = pthread_self();
   lock_info->thread_name = strdup(a.name);

   pthread_mutexattr_init(&mutex_attr);
   pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND);
   pthread_mutex_init(&lock_info->lock, &mutex_attr);
   pthread_mutexattr_destroy(&mutex_attr);

   pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
   AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry);
   pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
#endif /* DEBUG_THREADS */

   ret = a.start_routine(a.data);

   pthread_cleanup_pop(1);

   return ret;
}
static size_t optimal_alloc_size ( size_t  size) [static]

Definition at line 1526 of file utils.c.

References ALLOCATOR_OVERHEAD.

Referenced by __ast_calloc_with_stringfields(), and add_string_pool().

{
   unsigned int count;

   size += ALLOCATOR_OVERHEAD;

   for (count = 1; size; size >>= 1, count++);

   return (1 << count) - ALLOCATOR_OVERHEAD;
}
static struct timeval tvfix ( struct timeval  a) [static, read]

Definition at line 1386 of file utils.c.

References ast_log(), LOG_WARNING, and ONE_MILLION.

Referenced by ast_tvadd(), and ast_tvsub().

{
   if (a.tv_usec >= ONE_MILLION) {
      ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
         (long)a.tv_sec, (long int) a.tv_usec);
      a.tv_sec += a.tv_usec / ONE_MILLION;
      a.tv_usec %= ONE_MILLION;
   } else if (a.tv_usec < 0) {
      ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
         (long)a.tv_sec, (long int) a.tv_usec);
      a.tv_usec = 0;
   }
   return a;
}

Variable Documentation

struct { ... } __ast_string_field_empty_buffer [static]
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 478 of file utils.c.

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

Definition at line 1855 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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]

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

Definition at line 1434 of file utils.c.

Referenced by ast_random().

char string[1]