Wed Oct 28 11:46:22 2009

Asterisk developer's documentation


utils.c File Reference

Utility functions. More...

#include "asterisk.h"
#include <ctype.h>
#include <sys/stat.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 dependency graph for utils.c:

Go to the source code of this file.

Data Structures

struct  thr_arg

Defines

#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 ERANGE   34
#define ONE_MILLION   1000000

Functions

int __ast_str_helper (struct ast_str **buf, size_t max_len, int append, const char *fmt, va_list ap)
 Core functionality of ast_str_(set|append)_va.
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, size_t needed, 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.
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, char *const w[])
void ast_md5_hash (char *output, char *input)
 Produce 32 char MD5 hash of value.
int ast_mkdir (const char *path, int mode)
 Recursively create directory path.
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, 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 doreserved)
 ast_uri_encode: Turn text string to URI-encoded XX version
int ast_utils_init (void)
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 int gethostbyname_r (const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop)
 Reentrant replacement for gethostbyname for BSD-based systems.
static struct timeval tvfix (struct timeval a)

Variables

const char __ast_string_field_empty [] = ""
static ast_mutex_t __mutex = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
static char b2a [256]
static char base64 [64]
static ast_mutex_t fetchadd_m = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
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 = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
 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 AST_API_MODULE

Definition at line 59 of file utils.c.

#define AST_API_MODULE

Definition at line 59 of file utils.c.

#define AST_API_MODULE

Definition at line 59 of file utils.c.

#define AST_API_MODULE

Definition at line 59 of file utils.c.

#define AST_API_MODULE

Definition at line 59 of file utils.c.

#define AST_API_MODULE

Definition at line 59 of file utils.c.

#define ERANGE   34

duh? ERANGE value copied from web...

Definition at line 69 of file utils.c.

Referenced by gethostbyname_r(), and reload_queue_members().

#define ONE_MILLION   1000000

Definition at line 1236 of file utils.c.

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


Function Documentation

int __ast_str_helper ( struct ast_str **  buf,
size_t  max_len,
int  append,
const char *  fmt,
va_list  ap 
)

Core functionality of ast_str_(set|append)_va.

core handler for dynamic strings. This is not meant to be called directly, but rather through the various wrapper macros ast_str_set(...) ast_str_append(...) ast_str_set_va(...) ast_str_append_va(...)

Definition at line 1656 of file utils.c.

References AST_DYNSTR_BUILD_FAILED, AST_DYNSTR_BUILD_RETRY, ast_str_make_space(), and ast_verbose().

01658 {
01659    int res, need;
01660    int offset = (append && (*buf)->len) ? (*buf)->used : 0;
01661 
01662    if (max_len < 0)
01663       max_len = (*buf)->len;  /* don't exceed the allocated space */
01664    /*
01665     * Ask vsnprintf how much space we need. Remember that vsnprintf
01666     * does not count the final '\0' so we must add 1.
01667     */
01668    res = vsnprintf((*buf)->str + offset, (*buf)->len - offset, fmt, ap);
01669 
01670    need = res + offset + 1;
01671    /*
01672     * If there is not enough space and we are below the max length,
01673     * reallocate the buffer and return a message telling to retry.
01674     */
01675    if (need > (*buf)->len && (max_len == 0 || (*buf)->len < max_len) ) {
01676       if (max_len && max_len < need)   /* truncate as needed */
01677          need = max_len;
01678       else if (max_len == 0)  /* if unbounded, give more room for next time */
01679          need += 16 + need/4;
01680       if (0)   /* debugging */
01681          ast_verbose("extend from %d to %d\n", (int)(*buf)->len, need);
01682       if (ast_str_make_space(buf, need)) {
01683          ast_verbose("failed to extend from %d to %d\n", (int)(*buf)->len, need);
01684          return AST_DYNSTR_BUILD_FAILED;
01685       }
01686       (*buf)->str[offset] = '\0';   /* Truncate the partial write. */
01687 
01688       /* va_end() and va_start() must be done before calling
01689        * vsnprintf() again. */
01690       return AST_DYNSTR_BUILD_RETRY;
01691    }
01692    /* update space used, keep in mind the truncation */
01693    (*buf)->used = (res + offset > (*buf)->len) ? (*buf)->len : res + offset;
01694 
01695    return res;
01696 }

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 1459 of file utils.c.

References add_string_pool(), ast_string_field_mgr::last_alloc, ast_string_field_mgr::size, and ast_string_field_mgr::used.

01461 {
01462    char *result = NULL;
01463    size_t space = mgr->size - mgr->used;
01464 
01465    if (__builtin_expect(needed > space, 0)) {
01466       size_t new_size = mgr->size * 2;
01467 
01468       while (new_size < needed)
01469          new_size *= 2;
01470 
01471 #if defined(__AST_DEBUG_MALLOC)
01472       if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
01473          return NULL;
01474 #else
01475       if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
01476          return NULL;
01477 #endif
01478    }
01479 
01480    result = (*pool_head)->base + mgr->used;
01481    mgr->used += needed;
01482    mgr->last_alloc = result;
01483    return result;
01484 }

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 1405 of file utils.c.

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

01407 {
01408    const char **p = (const char **) pool_head + 1;
01409    struct ast_string_field_pool *cur = NULL;
01410    struct ast_string_field_pool *preserve = NULL;
01411 
01412    /* clear fields - this is always necessary */
01413    while ((struct ast_string_field_mgr *) p != mgr)
01414       *p++ = __ast_string_field_empty;
01415    mgr->last_alloc = NULL;
01416 #if defined(__AST_DEBUG_MALLOC)
01417    mgr->owner_file = file;
01418    mgr->owner_func = func;
01419    mgr->owner_line = lineno;
01420 #endif
01421    if (needed > 0) {    /* allocate the initial pool */
01422       *pool_head = NULL;
01423       return add_string_pool(mgr, pool_head, needed, file, lineno, func);
01424    }
01425    if (needed < 0) {    /* reset all pools */
01426       if (*pool_head == NULL) {
01427          ast_log(LOG_WARNING, "trying to reset empty pool\n");
01428          return -1;
01429       }
01430       cur = *pool_head;
01431    } else {       /* preserve the last pool */
01432       if (*pool_head == NULL) {
01433          ast_log(LOG_WARNING, "trying to reset empty pool\n");
01434          return -1;
01435       }
01436       mgr->used = 0;
01437       preserve = *pool_head;
01438       cur = preserve->prev;
01439    }
01440 
01441    if (preserve) {
01442       preserve->prev = NULL;
01443    }
01444 
01445    while (cur) {
01446       struct ast_string_field_pool *prev = cur->prev;
01447 
01448       if (cur != preserve) {
01449          ast_free(cur);
01450       }
01451       cur = prev;
01452    }
01453 
01454    *pool_head = preserve;
01455 
01456    return 0;
01457 }

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 1565 of file utils.c.

References __ast_string_field_ptr_build_va().

01568 {
01569    va_list ap1, ap2;
01570 
01571    va_start(ap1, format);
01572    va_start(ap2, format);     /* va_copy does not exist on FreeBSD */
01573 
01574    __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2);
01575 
01576    va_end(ap1);
01577    va_end(ap2);
01578 }

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 1509 of file utils.c.

References add_string_pool(), available(), ast_string_field_mgr::last_alloc, ast_string_field_mgr::size, and ast_string_field_mgr::used.

Referenced by __ast_string_field_ptr_build().

01512 {
01513    size_t needed;
01514    size_t available;
01515    size_t space = mgr->size - mgr->used;
01516    char *target;
01517 
01518    /* if the field already has space allocated, try to reuse it;
01519       otherwise, use the empty space at the end of the current
01520       pool
01521    */
01522    if ((*ptr)[0] != '\0') {
01523       target = (char *) *ptr;
01524       available = strlen(target) + 1;
01525    } else {
01526       target = (*pool_head)->base + mgr->used;
01527       available = space;
01528    }
01529 
01530    needed = vsnprintf(target, available, format, ap1) + 1;
01531 
01532    va_end(ap1);
01533 
01534    if (needed > available) {
01535       /* if the space needed can be satisfied by using the current
01536          pool (which could only occur if we tried to use the field's
01537          allocated space and failed), then use that space; otherwise
01538          allocate a new pool
01539       */
01540       if (needed > space) {
01541          size_t new_size = mgr->size * 2;
01542 
01543          while (new_size < needed)
01544             new_size *= 2;
01545          
01546 #if defined(__AST_DEBUG_MALLOC)
01547          if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
01548             return;
01549 #else
01550          if (add_string_pool(mgr, pool_head, new_size, NULL, 0, NULL))
01551             return;
01552 #endif
01553       }
01554 
01555       target = (*pool_head)->base + mgr->used;
01556       vsprintf(target, format, ap2);
01557    }
01558 
01559    if (*ptr != target) {
01560       mgr->last_alloc = *ptr = target;
01561       mgr->used += needed;
01562    }
01563 }

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

Definition at line 1486 of file utils.c.

References ast_string_field_mgr::last_alloc, ast_string_field_mgr::size, and ast_string_field_mgr::used.

01488 {
01489    int grow = needed - (strlen(*ptr) + 1);
01490    size_t space = mgr->size - mgr->used;
01491 
01492    if (grow <= 0) {
01493       return 0;
01494    }
01495 
01496    if (*ptr != mgr->last_alloc) {
01497       return 1;
01498    }
01499 
01500    if (space < grow) {
01501       return 1;
01502    }
01503 
01504    mgr->used += grow;
01505 
01506    return 0;
01507 }

static void __init_inet_ntoa_buf ( void   )  [static]

Definition at line 65 of file utils.c.

00082 {

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

Definition at line 1758 of file utils.c.

References MALLOC_FAILURE_MSG, and vasprintf.

01759 {
01760    int res;
01761    va_list ap;
01762 
01763    va_start(ap, fmt);
01764    if ((res = vasprintf(ret, fmt, ap)) == -1) {
01765       MALLOC_FAILURE_MSG;
01766    }
01767    va_end(ap);
01768 
01769    return res;
01770 }

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 1371 of file utils.c.

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

Referenced by __ast_string_field_alloc_space(), __ast_string_field_init(), and __ast_string_field_ptr_build_va().

01373 {
01374    struct ast_string_field_pool *pool;
01375 
01376 #if defined(__AST_DEBUG_MALLOC)
01377    if (!(pool = __ast_calloc(1, sizeof(*pool) + size, file, lineno, func))) {
01378       return -1;
01379    }
01380 #else
01381    if (!(pool = ast_calloc(1, sizeof(*pool) + size))) {
01382       return -1;
01383    }
01384 #endif
01385 
01386    pool->prev = *pool_head;
01387    *pool_head = pool;
01388    mgr->size = size;
01389    mgr->used = 0;
01390    mgr->last_alloc = NULL;
01391 
01392    return 0;
01393 }

int ast_atomic_fetchadd_int_slow ( volatile int *  p,
int  v 
)

Definition at line 1583 of file utils.c.

References ast_mutex_lock(), ast_mutex_unlock(), and fetchadd_m.

01584 {
01585    int ret;
01586    ast_mutex_lock(&fetchadd_m);
01587    ret = *p;
01588    *p += v;
01589    ast_mutex_unlock(&fetchadd_m);
01590    return ret;
01591 }

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

decode BASE64 encoded text

Decode data from base64.

Definition at line 261 of file utils.c.

Referenced by __ast_check_signature(), base64_decode(), and osp_validate_token().

00262 {
00263    int cnt = 0;
00264    unsigned int byte = 0;
00265    unsigned int bits = 0;
00266    int incnt = 0;
00267    while (*src && (cnt < max)) {
00268       /* Shift in 6 bits of input */
00269       byte <<= 6;
00270       byte |= (b2a[(int)(*src)]) & 0x3f;
00271       bits += 6;
00272       src++;
00273       incnt++;
00274       /* If we have at least 8 bits left over, take that character 
00275          off the top */
00276       if (bits >= 8)  {
00277          bits -= 8;
00278          *dst = (byte >> bits) & 0xff;
00279          dst++;
00280          cnt++;
00281       }
00282    }
00283    /* Dont worry about left over bits, they're extra anyway */
00284    return cnt;
00285 }

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 339 of file utils.c.

References ast_base64encode_full().

Referenced by __ast_sign(), aji_start_sasl(), base64_encode(), build_secret(), and osp_check_destination().

00340 {
00341    return ast_base64encode_full(dst, src, srclen, max, 0);
00342 }

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

encode text to BASE64 coding

Definition at line 288 of file utils.c.

Referenced by ast_base64encode().

00289 {
00290    int cnt = 0;
00291    int col = 0;
00292    unsigned int byte = 0;
00293    int bits = 0;
00294    int cntin = 0;
00295    /* Reserve space for null byte at end of string */
00296    max--;
00297    while ((cntin < srclen) && (cnt < max)) {
00298       byte <<= 8;
00299       byte |= *(src++);
00300       bits += 8;
00301       cntin++;
00302       if ((bits == 24) && (cnt + 4 <= max)) {
00303          *dst++ = base64[(byte >> 18) & 0x3f];
00304          *dst++ = base64[(byte >> 12) & 0x3f];
00305          *dst++ = base64[(byte >> 6) & 0x3f];
00306          *dst++ = base64[byte & 0x3f];
00307          cnt += 4;
00308          col += 4;
00309          bits = 0;
00310          byte = 0;
00311       }
00312       if (linebreaks && (cnt < max) && (col == 64)) {
00313          *dst++ = '\n';
00314          cnt++;
00315          col = 0;
00316       }
00317    }
00318    if (bits && (cnt + 4 <= max)) {
00319       /* Add one last character for the remaining bits, 
00320          padding the rest with 0 */
00321       byte <<= 24 - bits;
00322       *dst++ = base64[(byte >> 18) & 0x3f];
00323       *dst++ = base64[(byte >> 12) & 0x3f];
00324       if (bits == 16)
00325          *dst++ = base64[(byte >> 6) & 0x3f];
00326       else
00327          *dst++ = '=';
00328       *dst++ = '=';
00329       cnt += 4;
00330    }
00331    if (linebreaks && (cnt < max)) {
00332       *dst++ = '\n';
00333       cnt++;
00334    }
00335    *dst = '\0';
00336    return cnt;
00337 }

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.

  • 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 1190 of file utils.c.

References ast_build_string_va().

Referenced by config_odbc(), config_pgsql(), handle_speechrecognize(), lua_func_read(), lua_pbx_exec(), and pp_each_user_exec().

01191 {
01192    va_list ap;
01193    int result;
01194 
01195    va_start(ap, fmt);
01196    result = ast_build_string_va(buffer, space, fmt, ap);
01197    va_end(ap);
01198 
01199    return result;
01200 }

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 1171 of file utils.c.

Referenced by ast_build_string().

01172 {
01173    int result;
01174 
01175    if (!buffer || !*buffer || !space || !*space)
01176       return -1;
01177 
01178    result = vsnprintf(*buffer, *space, fmt, ap);
01179 
01180    if (result < 0)
01181       return -1;
01182    else if (result > *space)
01183       result = *space;
01184 
01185    *buffer += result;
01186    *space -= result;
01187    return 0;
01188 }

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 1045 of file utils.c.

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

Referenced by send_string().

01046 {
01047    struct timeval start = ast_tvnow();
01048    int n = 0;
01049    int elapsed = 0;
01050 
01051    while (len) {
01052       if (ast_wait_for_output(fd, timeoutms - elapsed)) {
01053          /* poll returned a fatal error, so bail out immediately. */
01054          return -1;
01055       }
01056 
01057       /* Clear any errors from a previous write */
01058       clearerr(f);
01059 
01060       n = fwrite(src, 1, len, f);
01061 
01062       if (ferror(f) && errno != EINTR && errno != EAGAIN) {
01063          /* fatal error from fwrite() */
01064          if (!feof(f)) {
01065             /* Don't spam the logs if it was just that the connection is closed. */
01066             ast_log(LOG_ERROR, "fwrite() returned error: %s\n", strerror(errno));
01067          }
01068          n = -1;
01069          break;
01070       }
01071 
01072       /* Update for data already written to the socket */
01073       len -= n;
01074       src += n;
01075 
01076       elapsed = ast_tvdiff_ms(ast_tvnow(), start);
01077       if (elapsed >= timeoutms) {
01078          /* We've taken too long to write 
01079           * This is only an error condition if we haven't finished writing. */
01080          n = len ? -1 : 0;
01081          break;
01082       }
01083    }
01084 
01085    while (fflush(f)) {
01086       if (errno == EAGAIN || errno == EINTR) {
01087          continue;
01088       }
01089       if (!feof(f)) {
01090          /* Don't spam the logs if it was just that the connection is closed. */
01091          ast_log(LOG_ERROR, "fflush() returned error: %s\n", strerror(errno));
01092       }
01093       n = -1;
01094       break;
01095    }
01096 
01097    return n < 0 ? -1 : 0;
01098 }

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

01005 {
01006    struct timeval start = ast_tvnow();
01007    int res = 0;
01008    int elapsed = 0;
01009 
01010    while (len) {
01011       if (ast_wait_for_output(fd, timeoutms - elapsed)) {
01012          return -1;
01013       }
01014 
01015       res = write(fd, s, len);
01016 
01017       if (res < 0 && errno != EAGAIN && errno != EINTR) {
01018          /* fatal error from write() */
01019          ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
01020          return -1;
01021       }
01022 
01023       if (res < 0) {
01024          /* It was an acceptable error */
01025          res = 0;
01026       }
01027 
01028       /* Update how much data we have left to write */
01029       len -= res;
01030       s += res;
01031       res = 0;
01032 
01033       elapsed = ast_tvdiff_ms(ast_tvnow(), start);
01034       if (elapsed >= timeoutms) {
01035          /* We've taken too long to write 
01036           * This is only an error condition if we haven't finished writing. */
01037          res = len ? -1 : 0;
01038          break;
01039       }
01040    }
01041 
01042    return res;
01043 }

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 1698 of file utils.c.

References ast_log(), and LOG_WARNING.

Referenced by ast_netsock_bindaddr(), and reload_config().

01699 {
01700 #if defined(HAVE_IP_MTU_DISCOVER)
01701    int val = IP_PMTUDISC_DONT;
01702    
01703    if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
01704       ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
01705 #endif /* HAVE_IP_MTU_DISCOVER */
01706 }

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 1219 of file utils.c.

References ast_strlen_zero().

Referenced by __ast_rtp_reload(), __ast_udptl_reload(), aji_create_client(), aji_load_config(), build_peer(), build_user(), dahdi_set_dnd(), func_channel_write(), handle_common_options(), init_acf_query(), load_config(), load_odbc_config(), reload(), reload_config(), run_agi(), set_config(), set_insecure_flags(), sla_build_trunk(), and strings_to_mask().

01220 {
01221    if (ast_strlen_zero(s))
01222       return 0;
01223 
01224    /* Determine if this is a false value */
01225    if (!strcasecmp(s, "no") ||
01226        !strcasecmp(s, "false") ||
01227        !strcasecmp(s, "n") ||
01228        !strcasecmp(s, "f") ||
01229        !strcasecmp(s, "0") ||
01230        !strcasecmp(s, "off"))
01231       return -1;
01232 
01233    return 0;
01234 }

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

get values from config variables.

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

01624 {
01625    long t;
01626    int scanned;
01627 
01628    if (dst == NULL)
01629       return -1;
01630 
01631    *dst = _default;
01632 
01633    if (ast_strlen_zero(src))
01634       return -1;
01635 
01636    /* only integer at the moment, but one day we could accept more formats */
01637    if (sscanf(src, "%30ld%n", &t, &scanned) == 1) {
01638       *dst = t;
01639       if (consumed)
01640          *consumed = scanned;
01641       return 0;
01642    } else
01643       return -1;
01644 }

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

get values from config variables.

Definition at line 1596 of file utils.c.

References ast_strlen_zero().

Referenced by acf_strftime().

01597 {
01598    long double dtv = 0.0;
01599    int scanned;
01600 
01601    if (dst == NULL)
01602       return -1;
01603 
01604    *dst = _default;
01605 
01606    if (ast_strlen_zero(src))
01607       return -1;
01608 
01609    /* only integer at the moment, but one day we could accept more formats */
01610    if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) {
01611       dst->tv_sec = dtv;
01612       dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
01613       if (consumed)
01614          *consumed = scanned;
01615       return 0;
01616    } else
01617       return -1;
01618 }

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 179 of file utils.c.

References ast_hostent::buf, gethostbyname_r(), ast_hostent::hp, and s.

Referenced by __ast_http_load(), __init_manager(), __set_address_from_contact(), ast_dnsmgr_lookup(), ast_find_ourip(), ast_get_ip_or_srv(), ast_parse_arg(), build_peer(), check_via(), create_addr(), dnsmgr_refresh(), festival_exec(), get_ip_and_port_from_sdp(), gtalk_load_config(), gtalk_update_stun(), handle_cli_udptl_debug_deprecated(), handle_cli_udptl_set_debug(), iax_template_parse(), jingle_load_config(), jingle_update_stun(), launch_netscript(), parse_register_contact(), process_sdp(), realtime_peer(), realtime_user(), reload_config(), rpt_exec(), rtcp_do_debug_ip(), rtp_do_debug_ip(), set_config(), set_destination(), and sip_do_debug_ip().

00180 {
00181    int res;
00182    int herrno;
00183    int dots = 0;
00184    const char *s;
00185    struct hostent *result = NULL;
00186    /* Although it is perfectly legitimate to lookup a pure integer, for
00187       the sake of the sanity of people who like to name their peers as
00188       integers, we break with tradition and refuse to look up a
00189       pure integer */
00190    s = host;
00191    res = 0;
00192    while (s && *s) {
00193       if (*s == '.')
00194          dots++;
00195       else if (!isdigit(*s))
00196          break;
00197       s++;
00198    }
00199    if (!s || !*s) {
00200       /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
00201       if (dots != 3)
00202          return NULL;
00203       memset(hp, 0, sizeof(struct ast_hostent));
00204       hp->hp.h_addrtype = AF_INET;
00205       hp->hp.h_addr_list = (void *) hp->buf;
00206       hp->hp.h_addr = hp->buf + sizeof(void *);
00207       if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
00208          return &hp->hp;
00209       return NULL;
00210       
00211    }
00212 #ifdef HAVE_GETHOSTBYNAME_R_5
00213    result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
00214 
00215    if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
00216       return NULL;
00217 #else
00218    res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
00219 
00220    if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
00221       return NULL;
00222 #endif
00223    return &hp->hp;
00224 }

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 428 of file utils.c.

References ast_threadstorage_get(), buf, and inet_ntoa_buf.

Referenced by __attempt_transmit(), __find_callno(), __iax2_show_peers(), __sip_xmit(), _sip_show_peer(), _sip_show_peers(), acf_channel_read(), action_login(), add_sdp(), ast_append_ha(), ast_apply_ha(), ast_netsock_bindaddr(), ast_parse_arg(), ast_rtcp_read(), ast_rtcp_write_rr(), ast_rtcp_write_sr(), ast_rtp_raw_write(), ast_rtp_read(), ast_rtp_sendcng(), ast_rtp_senddigit_begin(), ast_rtp_senddigit_continuation(), ast_rtp_senddigit_end(), ast_sip_ouraddrfor(), ast_tcptls_client_start(), ast_tcptls_server_start(), ast_udptl_bridge(), ast_udptl_read(), ast_udptl_write(), authenticate(), bridge_native_loop(), bridge_p2p_rtp_write(), build_callid_pvt(), build_callid_registry(), build_contact(), build_peer(), build_reply_digest(), build_rpid(), build_via(), calltoken_required(), check_access(), check_peer_ok(), check_via(), copy_via_headers(), create_addr_from_peer(), create_client(), dnsmgr_refresh(), 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(), function_sipchaninfo_read(), function_sippeer(), generic_http_callback(), get_input(), gtalk_create_candidates(), gtalk_update_stun(), handle_call_token(), handle_cli_iax2_show_callno_limits(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_peer(), handle_cli_iax2_show_registry(), handle_cli_udptl_debug_deprecated(), handle_cli_udptl_set_debug(), handle_command_response(), handle_error(), handle_incoming(), handle_mgcp_show_endpoints(), handle_open_receive_channel_ack_message(), handle_request(), handle_request_bye(), handle_request_do(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_refer(), handle_show_http(), handle_showmanconn(), handle_skinny_show_device(), handle_skinny_show_devices(), handle_skinny_show_settings(), httpstatus_callback(), iax2_ack_registry(), iax2_prov_app(), iax2_trunk_queue(), iax_server(), iax_showframe(), initreqprep(), jingle_create_candidates(), load_module(), manager_iax2_show_peer_list(), mgcpsock_read(), oh323_addrcmp_str(), oh323_call(), oh323_set_rtp_peer(), parse_register_contact(), parsing(), peercnt_add(), peercnt_modify(), peercnt_remove(), phoneprov_callback(), process_request(), process_rfc3389(), process_sdp(), purge_sessions(), raw_hangup(), realtime_peer(), realtime_update_peer(), realtime_user(), reg_source_db(), register_verify(), registry_rerequest(), reload_config(), resend_response(), retrans_pkt(), rpt_exec(), rtcp_do_debug_ip(), rtp_do_debug_ip(), sched_delay_remove(), send_dtmf(), send_packet(), send_raw_client(), send_request(), send_response(), send_trunk(), session_do(), set_config(), set_destination(), set_peercnt_limit(), setup_incoming_call(), show_channels_cb(), show_main_page(), sip_do_debug_ip(), sip_do_debug_peer(), sip_poke_peer(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_show_channel(), sip_show_settings(), sip_show_tcp(), skinny_session(), skinny_set_rtp_peer(), socket_process(), socket_process_meta(), start_rtp(), timing_read(), transmit_notify_with_mwi(), unistim_info(), unistimsock_read(), and update_registry().

00429 {
00430    char *buf;
00431 
00432    if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
00433       return "";
00434 
00435    return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
00436 }

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

Definition at line 1342 of file utils.c.

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

01343 {
01344    int x, ofs = 0;
01345    const char *src;
01346 
01347    /* Join words into a string */
01348    if (!s)
01349       return;
01350    for (x = 0; ofs < len && w[x]; x++) {
01351       if (x > 0)
01352          s[ofs++] = ' ';
01353       for (src = w[x]; *src && ofs < len; src++)
01354          s[ofs++] = *src;
01355    }
01356    if (ofs == len)
01357       ofs--;
01358    s[ofs] = '\0';
01359 }

void ast_md5_hash ( char *  output,
char *  input 
)

Produce 32 char MD5 hash of value.

Produces MD5 hash based on input string.

Definition at line 227 of file utils.c.

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

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

00228 {
00229    struct MD5Context md5;
00230    unsigned char digest[16];
00231    char *ptr;
00232    int x;
00233 
00234    MD5Init(&md5);
00235    MD5Update(&md5, (unsigned char *)input, strlen(input));
00236    MD5Final(digest, &md5);
00237    ptr = output;
00238    for (x = 0; x < 16; x++)
00239       ptr += sprintf(ptr, "%2.2x", digest[x]);
00240 }

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

01709 {
01710    char *ptr;
01711    int len = strlen(path), count = 0, x, piececount = 0;
01712    char *tmp = ast_strdupa(path);
01713    char **pieces;
01714    char *fullpath = alloca(len + 1);
01715    int res = 0;
01716 
01717    for (ptr = tmp; *ptr; ptr++) {
01718       if (*ptr == '/')
01719          count++;
01720    }
01721 
01722    /* Count the components to the directory path */
01723    pieces = alloca(count * sizeof(*pieces));
01724    for (ptr = tmp; *ptr; ptr++) {
01725       if (*ptr == '/') {
01726          *ptr = '\0';
01727          pieces[piececount++] = ptr + 1;
01728       }
01729    }
01730 
01731    *fullpath = '\0';
01732    for (x = 0; x < piececount; x++) {
01733       /* This looks funky, but the buffer is always ideally-sized, so it's fine. */
01734       strcat(fullpath, "/");
01735       strcat(fullpath, pieces[x]);
01736       res = mkdir(fullpath, mode);
01737       if (res && errno != EEXIST)
01738          return errno;
01739    }
01740    return 0;
01741 }

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 1316 of file utils.c.

01317 {
01318    char *dataPut = start;
01319    int inEscape = 0;
01320    int inQuotes = 0;
01321 
01322    for (; *start; start++) {
01323       if (inEscape) {
01324          *dataPut++ = *start;       /* Always goes verbatim */
01325          inEscape = 0;
01326       } else {
01327          if (*start == '\\') {
01328             inEscape = 1;      /* Do not copy \ into the data */
01329          } else if (*start == '\'') {
01330             inQuotes = 1 - inQuotes;   /* Do not copy ' into the data */
01331          } else {
01332             /* Replace , with |, unless in quotes */
01333             *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
01334          }
01335       }
01336    }
01337    if (start != dataPut)
01338       *dataPut = 0;
01339    return dataPut;
01340 }

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 919 of file utils.c.

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

00922 {
00923    unsigned char attr_destroy = 0;
00924    int res;
00925 
00926    if (!attr) {
00927       attr = alloca(sizeof(*attr));
00928       pthread_attr_init(attr);
00929       attr_destroy = 1;
00930    }
00931 
00932    if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
00933       ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno));
00934 
00935    res = ast_pthread_create_stack(thread, attr, start_routine, data, 
00936                                   stacksize, file, caller, line, start_fn);
00937 
00938    if (attr_destroy)
00939       pthread_attr_destroy(attr);
00940 
00941    return res;
00942 }

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

00873 {
00874 #if !defined(LOW_MEMORY)
00875    struct thr_arg *a;
00876 #endif
00877 
00878    if (!attr) {
00879       attr = alloca(sizeof(*attr));
00880       pthread_attr_init(attr);
00881    }
00882 
00883 #ifdef __linux__
00884    /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
00885       which is kind of useless. Change this here to
00886       PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
00887       priority will propagate down to new threads by default.
00888       This does mean that callers cannot set a different priority using
00889       PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
00890       the priority afterwards with pthread_setschedparam(). */
00891    if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
00892       ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
00893 #endif
00894 
00895    if (!stacksize)
00896       stacksize = AST_STACKSIZE;
00897 
00898    if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
00899       ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));
00900 
00901 #if !defined(LOW_MEMORY)
00902    if ((a = ast_malloc(sizeof(*a)))) {
00903       a->start_routine = start_routine;
00904       a->data = data;
00905       start_routine = dummy_start;
00906       if (asprintf(&a->name, "%-20s started at [%5d] %s %s()",
00907               start_fn, line, file, caller) < 0) {
00908          ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00909          a->name = NULL;
00910       }
00911       data = a;
00912    }
00913 #endif /* !LOW_MEMORY */
00914 
00915    return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
00916 }

long int ast_random ( void   ) 

Definition at line 1292 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_new_init(), ast_rtp_new_source(), ast_rtp_new_with_bindaddr(), ast_udptl_new_with_bindaddr(), authenticate_request(), build_gateway(), build_iv(), build_rand_pad(), build_reply_digest(), calc_metric(), calc_rxstamp(), callno_hash(), dahdi_new(), generate_random_string(), generic_http_callback(), get_trans_id(), gtalk_alloc(), gtalk_create_candidates(), gtalk_new(), handle_response_invite(), iax2_start_transfer(), jingle_alloc(), jingle_create_candidates(), jingle_new(), load_module(), local_new(), make_email_file(), make_our_tag(), moh_files_alloc(), ogg_vorbis_rewrite(), osp_create_uuid(), page_exec(), process_weights(), reg_source_db(), registry_authrequest(), reqprep(), 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().

01293 {
01294    long int res;
01295 #ifdef HAVE_DEV_URANDOM
01296    if (dev_urandom_fd >= 0) {
01297       int read_res = read(dev_urandom_fd, &res, sizeof(res));
01298       if (read_res > 0) {
01299          long int rm = RAND_MAX;
01300          res = res < 0 ? ~res : res;
01301          rm++;
01302          return res % rm;
01303       }
01304    }
01305 #endif
01306 #ifdef linux
01307    res = random();
01308 #else
01309    ast_mutex_lock(&randomlock);
01310    res = random();
01311    ast_mutex_unlock(&randomlock);
01312 #endif
01313    return res;
01314 }

void ast_sha1_hash ( char *  output,
char *  input 
)

Produce 40 char SHA1 hash of value.

Produces SHA1 hash based on input string.

Definition at line 243 of file utils.c.

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

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

00244 {
00245    struct SHA1Context sha;
00246    char *ptr;
00247    int x;
00248    uint8_t Message_Digest[20];
00249 
00250    SHA1Reset(&sha);
00251    
00252    SHA1Input(&sha, (const unsigned char *) input, strlen(input));
00253 
00254    SHA1Result(&sha, Message_Digest);
00255    ptr = output;
00256    for (x = 0; x < 20; x++)
00257       ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
00258 }

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 1100 of file utils.c.

References ast_strip().

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

01101 {
01102    char *e;
01103    char *q;
01104 
01105    s = ast_strip(s);
01106    if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
01107       e = s + strlen(s) - 1;
01108       if (*e == *(end_quotes + (q - beg_quotes))) {
01109          s++;
01110          *e = '\0';
01111       }
01112    }
01113 
01114    return s;
01115 }

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 1202 of file utils.c.

References ast_strlen_zero().

Referenced by __ast_http_load(), __ast_rtp_reload(), __ast_udptl_reload(), __init_manager(), _parse(), action_agent_logoff(), action_bridge(), action_originate(), action_updateconfig(), aji_create_client(), aji_load_config(), apply_general_options(), apply_option(), apply_outgoing(), ast_jb_read_conf(), ast_readconfig(), build_device(), build_gateway(), build_peer(), build_user(), dahdi_set_dnd(), do_reload(), do_timelimit(), festival_exec(), func_channel_write(), func_inheritance_write(), function_ilink(), get_encrypt_methods(), gtalk_load_config(), handle_common_options(), 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_pause_queue_member(), message_template_build(), misdn_answer(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), process_dahdi(), process_echocancel(), queue_set_param(), read_agent_config(), reload(), reload_config(), reload_queues(), run_startup_commands(), search_directory(), set_active(), set_config(), sla_load_config(), smdi_load(), start_monitor_action(), strings_to_mask(), and update_common_options().

01203 {
01204    if (ast_strlen_zero(s))
01205       return 0;
01206 
01207    /* Determine if this is a true value */
01208    if (!strcasecmp(s, "yes") ||
01209        !strcasecmp(s, "true") ||
01210        !strcasecmp(s, "y") ||
01211        !strcasecmp(s, "t") ||
01212        !strcasecmp(s, "1") ||
01213        !strcasecmp(s, "on"))
01214       return -1;
01215 
01216    return 0;
01217 }

struct timeval ast_tvadd ( struct timeval  a,
struct timeval  b 
) [read]

Returns the sum of two timevals a + b.

Definition at line 1256 of file utils.c.

References ONE_MILLION, and tvfix().

Referenced by __get_from_jb(), agent_hangup(), agent_read(), ast_audiohook_trigger_wait(), ast_channel_bridge(), ast_generic_bridge(), ast_rtp_sendcng(), ast_rtp_senddigit_begin(), ast_rtp_senddigit_end(), ast_sched_runq(), ast_smoother_read(), ast_translate(), calc_timestamp(), conf_run(), do_cdr(), iax2_process_thread(), jb_get_and_deliver(), mb_poll_thread(), monmp3thread(), mp3_exec(), mwi_monitor_handler(), NBScat_exec(), sched_settime(), sched_thread(), schedule_delivery(), sla_process_timers(), and smdi_message_wait().

01257 {
01258    /* consistency checks to guarantee usec in 0..999999 */
01259    a = tvfix(a);
01260    b = tvfix(b);
01261    a.tv_sec += b.tv_sec;
01262    a.tv_usec += b.tv_usec;
01263    if (a.tv_usec >= ONE_MILLION) {
01264       a.tv_sec++;
01265       a.tv_usec -= ONE_MILLION;
01266    }
01267    return a;
01268 }

struct timeval ast_tvsub ( struct timeval  a,
struct timeval  b 
) [read]

Returns the difference of two timevals a - b.

Definition at line 1270 of file utils.c.

References ONE_MILLION, and tvfix().

Referenced by ast_channel_bridge(), ast_rwlock_timedrdlock(), ast_rwlock_timedwrlock(), ast_sched_dump(), ast_translate(), calc_rxstamp(), calc_timestamp(), conf_run(), handle_showcalls(), and handle_showuptime().

01271 {
01272    /* consistency checks to guarantee usec in 0..999999 */
01273    a = tvfix(a);
01274    b = tvfix(b);
01275    a.tv_sec -= b.tv_sec;
01276    a.tv_usec -= b.tv_usec;
01277    if (a.tv_usec < 0) {
01278       a.tv_sec-- ;
01279       a.tv_usec += ONE_MILLION;
01280    }
01281    return a;
01282 }

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 1136 of file utils.c.

01137 {
01138    char c, *ret, *dst;
01139 
01140    if (src == NULL)
01141       return NULL;
01142    for (ret = dst = src; (c = *src++); *dst++ = c ) {
01143       if (c != '\\')
01144          continue;   /* copy char at the end of the loop */
01145       switch ((c = *src++)) {
01146       case '\0':  /* special, trailing '\' */
01147          c = '\\';
01148          break;
01149       case 'b':   /* backspace */
01150          c = '\b';
01151          break;
01152       case 'f':   /* form feed */
01153          c = '\f';
01154          break;
01155       case 'n':
01156          c = '\n';
01157          break;
01158       case 'r':
01159          c = '\r';
01160          break;
01161       case 't':
01162          c = '\t';
01163          break;
01164       }
01165       /* default, use the char literally */
01166    }
01167    *dst = '\0';
01168    return ret;
01169 }

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 1117 of file utils.c.

Referenced by sip_notify().

01118 {
01119    char *e;
01120    char *work = s;
01121 
01122    while ((e = strchr(work, ';'))) {
01123       if ((e > work) && (*(e-1) == '\\')) {
01124          memmove(e - 1, e, strlen(e) + 1);
01125          work = e;
01126       } else {
01127          work = e + 1;
01128       }
01129    }
01130 
01131    return s;
01132 }

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 411 of file utils.c.

Referenced by check_user_full(), config_curl(), get_also_info(), get_destination(), get_refer_info(), handle_request_invite(), http_decode(), realtime_curl(), realtime_multi_curl(), register_verify(), sip_new(), and uridecode().

00412 {
00413    char *o;
00414    unsigned int tmp;
00415 
00416    for (o = s; *s; s++, o++) {
00417       if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
00418          /* have '%', two chars and correct parsing */
00419          *o = tmp;
00420          s += 2;  /* Will be incremented once more when we break out */
00421       } else /* all other cases, just copy */
00422          *o = *s;
00423    }
00424    *o = '\0';
00425 }

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

ast_uri_encode: Turn text string to URI-encoded XX version

Turn text string to URI-encoded XX version.

Note:
At this point, we're converting from ISO-8859-x (8-bit), not UTF8 as in the SIP protocol spec If doreserved == 1 we will convert reserved characters also. RFC 2396, section 2.4 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.
Note: The doreserved option is needed for replaces header in SIP transfers.

Definition at line 380 of file utils.c.

References ast_copy_string(), and buf.

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

00381 {
00382    char *reserved = ";/?:@&=+$,# "; /* Reserved chars */
00383 
00384    const char *ptr  = string; /* Start with the string */
00385    char *out = NULL;
00386    char *buf = NULL;
00387 
00388    ast_copy_string(outbuf, string, buflen);
00389 
00390    /* If there's no characters to convert, just go through and don't do anything */
00391    while (*ptr) {
00392       if ((*ptr < 32 || (unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
00393          /* Oops, we need to start working here */
00394          if (!buf) {
00395             buf = outbuf;
00396             out = buf + (ptr - string) ;  /* Set output ptr */
00397          }
00398          out += sprintf(out, "%%%02x", (unsigned char) *ptr);
00399       } else if (buf) {
00400          *out = *ptr;   /* Continue copying the string */
00401          out++;
00402       } 
00403       ptr++;
00404    }
00405    if (buf)
00406       *out = '\0';
00407    return outbuf;
00408 }

int ast_utils_init ( void   ) 

Definition at line 1743 of file utils.c.

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

Referenced by main().

01744 {
01745 #ifdef HAVE_DEV_URANDOM
01746    dev_urandom_fd = open("/dev/urandom", O_RDONLY);
01747 #endif
01748    base64_init();
01749 #ifdef DEBUG_THREADS
01750 #if !defined(LOW_MEMORY)
01751    ast_cli_register_multiple(utils_cli, ARRAY_LEN(utils_cli));
01752 #endif
01753 #endif
01754    return 0;
01755 }

int ast_wait_for_input ( int  fd,
int  ms 
)

Definition at line 944 of file utils.c.

References ast_poll.

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

00945 {
00946    struct pollfd pfd[1];
00947    memset(pfd, 0, sizeof(pfd));
00948    pfd[0].fd = fd;
00949    pfd[0].events = POLLIN|POLLPRI;
00950    return ast_poll(pfd, 1, ms);
00951 }

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

Definition at line 953 of file utils.c.

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

Referenced by ast_careful_fwrite(), and ast_carefulwrite().

00954 {
00955    struct pollfd pfd = {
00956       .fd = fd,
00957       .events = POLLOUT,
00958    };
00959    int res;
00960    struct timeval start = ast_tvnow();
00961    int elapsed = 0;
00962 
00963    /* poll() until the fd is writable without blocking */
00964    while ((res = ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
00965       if (res == 0) {
00966          /* timed out. */
00967          ast_log(LOG_NOTICE, "Timed out trying to write\n");
00968          return -1;
00969       } else if (res == -1) {
00970          /* poll() returned an error, check to see if it was fatal */
00971 
00972          if (errno == EINTR || errno == EAGAIN) {
00973             elapsed = ast_tvdiff_ms(ast_tvnow(), start);
00974             if (elapsed >= timeoutms) {
00975                return -1;
00976             }
00977             /* This was an acceptable error, go back into poll() */
00978             continue;
00979          }
00980 
00981          /* Fatal error, bail. */
00982          ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno));
00983 
00984          return -1;
00985       }
00986       elapsed = ast_tvdiff_ms(ast_tvnow(), start);
00987       if (elapsed >= timeoutms) {
00988          return -1;
00989       }
00990    }
00991 
00992    return 0;
00993 }

static void base64_init ( void   )  [static]

Definition at line 344 of file utils.c.

Referenced by ast_utils_init().

00345 {
00346    int x;
00347    memset(b2a, -1, sizeof(b2a));
00348    /* Initialize base-64 Conversion table */
00349    for (x = 0; x < 26; x++) {
00350       /* A-Z */
00351       base64[x] = 'A' + x;
00352       b2a['A' + x] = x;
00353       /* a-z */
00354       base64[x + 26] = 'a' + x;
00355       b2a['a' + x] = x + 26;
00356       /* 0-9 */
00357       if (x < 10) {
00358          base64[x + 52] = '0' + x;
00359          b2a['0' + x] = x + 52;
00360       }
00361    }
00362    base64[62] = '+';
00363    base64[63] = '/';
00364    b2a[(int)'+'] = 62;
00365    b2a[(int)'/'] = 63;
00366 }

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

Definition at line 826 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, thr_arg::name, pthread_mutex_init, pthread_mutex_lock, pthread_mutex_unlock, thr_arg::start_routine, and strdup.

Referenced by ast_pthread_create_stack().

00827 {
00828    void *ret;
00829    struct thr_arg a = *((struct thr_arg *) data);  /* make a local copy */
00830 #ifdef DEBUG_THREADS
00831    struct thr_lock_info *lock_info;
00832    pthread_mutexattr_t mutex_attr;
00833 #endif
00834 
00835    /* note that even though data->name is a pointer to allocated memory,
00836       we are not freeing it here because ast_register_thread is going to
00837       keep a copy of the pointer and then ast_unregister_thread will
00838       free the memory
00839    */
00840    ast_free(data);
00841    ast_register_thread(a.name);
00842    pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());
00843 
00844 #ifdef DEBUG_THREADS
00845    if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
00846       return NULL;
00847 
00848    lock_info->thread_id = pthread_self();
00849    lock_info->thread_name = strdup(a.name);
00850 
00851    pthread_mutexattr_init(&mutex_attr);
00852    pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND);
00853    pthread_mutex_init(&lock_info->lock, &mutex_attr);
00854    pthread_mutexattr_destroy(&mutex_attr);
00855 
00856    pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
00857    AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry);
00858    pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
00859 #endif /* DEBUG_THREADS */
00860 
00861    ret = a.start_routine(a.data);
00862 
00863    pthread_cleanup_pop(1);
00864 
00865    return ret;
00866 }

static int gethostbyname_r ( const char *  name,
struct hostent *  ret,
char *  buf,
size_t  buflen,
struct hostent **  result,
int *  h_errnop 
) [static]

Reentrant replacement for gethostbyname for BSD-based systems.

Note:
This routine is derived from code originally written and placed in the public domain by Enzo Michelangeli <em@em.no-ip.com>

Definition at line 79 of file utils.c.

References __mutex, ast_mutex_lock(), ast_mutex_unlock(), ERANGE, and gethostbyname.

Referenced by ast_gethostbyname().

00082 {
00083    int hsave;
00084    struct hostent *ph;
00085    ast_mutex_lock(&__mutex); /* begin critical area */
00086    hsave = h_errno;
00087 
00088    ph = gethostbyname(name);
00089    *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
00090    if (ph == NULL) {
00091       *result = NULL;
00092    } else {
00093       char **p, **q;
00094       char *pbuf;
00095       int nbytes = 0;
00096       int naddr = 0, naliases = 0;
00097       /* determine if we have enough space in buf */
00098 
00099       /* count how many addresses */
00100       for (p = ph->h_addr_list; *p != 0; p++) {
00101          nbytes += ph->h_length; /* addresses */
00102          nbytes += sizeof(*p); /* pointers */
00103          naddr++;
00104       }
00105       nbytes += sizeof(*p); /* one more for the terminating NULL */
00106 
00107       /* count how many aliases, and total length of strings */
00108       for (p = ph->h_aliases; *p != 0; p++) {
00109          nbytes += (strlen(*p)+1); /* aliases */
00110          nbytes += sizeof(*p);  /* pointers */
00111          naliases++;
00112       }
00113       nbytes += sizeof(*p); /* one more for the terminating NULL */
00114 
00115       /* here nbytes is the number of bytes required in buffer */
00116       /* as a terminator must be there, the minimum value is ph->h_length */
00117       if (nbytes > buflen) {
00118          *result = NULL;
00119          ast_mutex_unlock(&__mutex); /* end critical area */
00120          return ERANGE; /* not enough space in buf!! */
00121       }
00122 
00123       /* There is enough space. Now we need to do a deep copy! */
00124       /* Allocation in buffer:
00125          from [0] to [(naddr-1) * sizeof(*p)]:
00126          pointers to addresses
00127          at [naddr * sizeof(*p)]:
00128          NULL
00129          from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
00130          pointers to aliases
00131          at [(naddr+naliases+1) * sizeof(*p)]:
00132          NULL
00133          then naddr addresses (fixed length), and naliases aliases (asciiz).
00134       */
00135 
00136       *ret = *ph;   /* copy whole structure (not its address!) */
00137 
00138       /* copy addresses */
00139       q = (char **)buf; /* pointer to pointers area (type: char **) */
00140       ret->h_addr_list = q; /* update pointer to address list */
00141       pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
00142       for (p = ph->h_addr_list; *p != 0; p++) {
00143          memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
00144          *q++ = pbuf; /* the pointer is the one inside buf... */
00145          pbuf += ph->h_length; /* advance pbuf */
00146       }
00147       *q++ = NULL; /* address list terminator */
00148 
00149       /* copy aliases */
00150       ret->h_aliases = q; /* update pointer to aliases list */
00151       for (p = ph->h_aliases; *p != 0; p++) {
00152          strcpy(pbuf, *p); /* copy alias strings */
00153          *q++ = pbuf; /* the pointer is the one inside buf... */
00154          pbuf += strlen(*p); /* advance pbuf */
00155          *pbuf++ = 0; /* string terminator */
00156       }
00157       *q++ = NULL; /* terminator */
00158 
00159       strcpy(pbuf, ph->h_name); /* copy alias strings */
00160       ret->h_name = pbuf;
00161       pbuf += strlen(ph->h_name); /* advance pbuf */
00162       *pbuf++ = 0; /* string terminator */
00163 
00164       *result = ret;  /* and let *result point to structure */
00165 
00166    }
00167    h_errno = hsave;  /* restore h_errno */
00168    ast_mutex_unlock(&__mutex); /* end critical area */
00169 
00170    return (*result == NULL); /* return 0 on success, non-zero on error */
00171 }

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

Definition at line 1241 of file utils.c.

References ast_log(), LOG_WARNING, and ONE_MILLION.

Referenced by ast_tvadd(), and ast_tvsub().

01242 {
01243    if (a.tv_usec >= ONE_MILLION) {
01244       ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
01245          a.tv_sec, (long int) a.tv_usec);
01246       a.tv_sec += a.tv_usec / ONE_MILLION;
01247       a.tv_usec %= ONE_MILLION;
01248    } else if (a.tv_usec < 0) {
01249       ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
01250          a.tv_sec, (long int) a.tv_usec);
01251       a.tv_usec = 0;
01252    }
01253    return a;
01254 }


Variable Documentation

const char __ast_string_field_empty[] = ""

the empty string

Definition at line 1365 of file utils.c.

Referenced by __ast_string_field_init().

ast_mutex_t __mutex = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Definition at line 72 of file utils.c.

Referenced by gethostbyname_r().

char b2a[256] [static]

Definition at line 63 of file utils.c.

char base64[64] [static]

Definition at line 62 of file utils.c.

Referenced by aji_start_sasl().

ast_mutex_t fetchadd_m = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Definition at line 1581 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 65 of file utils.c.

Referenced by ast_inet_ntoa().

ast_mutex_t randomlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

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

Definition at line 1289 of file utils.c.

Referenced by ast_random().


Generated on Wed Oct 28 11:46:22 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6