Utility functions. More...
#include "asterisk.h"#include <ctype.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/syscall.h>#include "asterisk/network.h"#include "asterisk/ast_version.h"#include "asterisk/lock.h"#include "asterisk/io.h"#include "asterisk/md5.h"#include "asterisk/sha1.h"#include "asterisk/cli.h"#include "asterisk/linkedlists.h"#include "asterisk/strings.h"#include "asterisk/time.h"#include "asterisk/stringfields.h"#include "asterisk/utils.h"#include "asterisk/threadstorage.h"#include "asterisk/config.h"
Go to the source code of this file.
Data Structures | |
| struct | thr_arg |
Defines | |
| #define | ALLOCATOR_OVERHEAD 48 |
| #define | AST_API_MODULE /* ensure that inlinable API functions will be built in lock.h if required */ |
| #define | AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */ |
| #define | AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */ |
| #define | AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */ |
| #define | AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */ |
| #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 ap) |
| 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_do_crash (void) |
| Force a crash if DO_CRASH is defined. | |
| void | ast_enable_packet_fragmentation (int sock) |
| Disable PMTU discovery on a socket. | |
| char * | ast_escape_quoted (const char *string, char *outbuf, int buflen) |
| Escape characters found in a quoted string. | |
| 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_tid (void) |
| Get current thread ID. | |
| 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) |
| int | ast_regex_string_to_regex_pattern (const char *regex_string, struct ast_str **regex_pattern) |
| Given a string regex_string in the form of "/regex/", convert it into the form of "regex". | |
| int | ast_remaining_ms (struct timeval start, int max_ms) |
| Calculate remaining milliseconds given a starting timestamp and upper bound. | |
| void | ast_replace_subargument_delimiter (char *s) |
| Replace '^' in a string with ','. | |
| void | ast_sha1_hash (char *output, const char *input) |
| Produce 40 char SHA1 hash of value. | |
| void | ast_sha1_hash_uint (uint8_t *digest, const char *input) |
| Produce a 20 byte 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, struct ast_flags spec) |
| Decode URI, URN, URL (overwrite string) | |
| char * | ast_uri_encode (const char *string, char *outbuf, int buflen, struct ast_flags spec) |
| 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) |
| int | ast_xml_escape (const char *string, char *const outbuf, const size_t buflen) |
| Escape reserved characters for use in XML. | |
| 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) |
| static void | utils_shutdown (void) |
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 |
| struct ast_flags | ast_uri_http = {AST_URI_UNRESERVED} |
| struct ast_flags | ast_uri_http_legacy = {AST_URI_LEGACY_SPACE | AST_URI_UNRESERVED} |
| struct ast_flags | ast_uri_sip_user = {AST_URI_UNRESERVED | AST_URI_SIP_USER_UNRESERVED} |
| 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. | |
Utility functions.
Definition in file main/utils.c.
| #define ALLOCATOR_OVERHEAD 48 |
Definition at line 1727 of file main/utils.c.
Referenced by optimal_alloc_size().
| #define AST_API_MODULE /* ensure that inlinable API functions will be built in lock.h if required */ |
Definition at line 75 of file main/utils.c.
| #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */ |
Definition at line 75 of file main/utils.c.
| #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */ |
Definition at line 75 of file main/utils.c.
| #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */ |
Definition at line 75 of file main/utils.c.
| #define AST_API_MODULE /* ensure that inlinable API functions will be built in this module if required */ |
Definition at line 75 of file main/utils.c.
| #define AST_API_MODULE |
Definition at line 75 of file main/utils.c.
| #define AST_API_MODULE |
Definition at line 75 of file main/utils.c.
| #define ONE_MILLION 1000000 |
Definition at line 1558 of file main/utils.c.
Referenced by ast_tvadd(), ast_tvsub(), and tvfix().
| 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 2006 of file main/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 1847 of file main/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 1780 of file main/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 1995 of file main/utils.c.
References __ast_string_field_ptr_build_va().
{
va_list ap;
va_start(ap, format);
__ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap);
va_end(ap);
}
| 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 | ap | ||
| ) |
Definition at line 1931 of file main/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;
va_list ap2;
/* 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);
}
va_copy(ap2, ap);
needed = vsnprintf(target, available, format, ap2) + 1;
va_end(ap2);
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, ap);
va_end(ap); /* XXX va_end without va_start? */
__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 1888 of file main/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 1910 of file main/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 81 of file main/utils.c.
{
| int _ast_asprintf | ( | char ** | ret, |
| const char * | file, | ||
| int | lineno, | ||
| const char * | func, | ||
| const char * | fmt, | ||
| ... | |||
| ) |
Definition at line 2315 of file main/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 1744 of file main/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 2058 of file main/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 291 of file main/utils.c.
Referenced by action_messagesend(), aes_helper(), ast_check_signature(), base64_helper(), custom_presence_callback(), h264_format_attr_sdp_parse(), osp_validate_token(), sdp_crypto_process(), and sdp_crypto_setup().
{
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.
| 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 369 of file main/utils.c.
References ast_base64encode_full().
Referenced by aes_helper(), aji_start_sasl(), ast_sign(), base64_helper(), build_secret(), h264_format_attr_sdp_generate(), osp_check_destination(), presence_read(), sdp_crypto_setup(), websocket_callback(), and xmpp_client_authenticate_sasl().
{
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 318 of file main/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.
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 |
| 0 | on success |
| non-zero | on failure. |
Definition at line 1492 of file main/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.
| 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 1473 of file main/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.
| 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. |
| 0 | success |
| -1 | error |
Definition at line 1347 of file main/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.
Definition at line 1306 of file main/utils.c.
References ast_log(), ast_tvdiff_ms(), ast_tvnow(), ast_wait_for_output(), errno, and LOG_ERROR.
Referenced by ast_agi_send(), ast_cli(), and cleanup_module().
{
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_do_crash | ( | void | ) |
Force a crash if DO_CRASH is defined.
Definition at line 2366 of file main/utils.c.
{
#if defined(DO_CRASH)
abort();
/*
* Just in case abort() doesn't work or something else super
* silly, and for Qwell's amusement.
*/
*((int *) 0) = 0;
#endif /* defined(DO_CRASH) */
}
| void ast_enable_packet_fragmentation | ( | int | sock | ) |
Disable PMTU discovery on a socket.
| sock | The socket to manipulate |
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 2121 of file main/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 | ||
| ) |
Escape characters found in a quoted string.
| string | string to be escaped |
| outbuf | resulting escaped string |
| buflen | size of output buffer |
Definition at line 460 of file main/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".
| 0 | if val is a NULL pointer. |
| -1 | if "true". |
| 0 | otherwise. |
Definition at line 1541 of file main/utils.c.
References ast_strlen_zero().
Referenced by acf_faxopt_write(), acf_transaction_write(), actual_load_config(), aji_create_client(), aji_load_config(), aoc_cli_debug_enable(), bool_handler_fn(), boolflag_handler_fn(), build_peer(), build_user(), dahdi_datetime_send_option(), dahdi_set_dnd(), find_realtime(), func_channel_write_real(), handle_common_options(), handle_queue_set_member_ringinuse(), init_acf_query(), load_config(), load_odbc_config(), manager_mute_mixmonitor(), manager_queue_member_ringinuse(), parse_empty_options(), process_dahdi(), reload_config(), reload_single_member(), rt_handle_member_record(), rtp_reload(), run_agi(), set_config(), set_insecure_flags(), sip_parse_nat_option(), 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_tid | ( | void | ) |
Get current thread ID.
| None |
Definition at line 2330 of file main/utils.c.
Referenced by ast_log_full(), and ast_register_thread().
{
int ret = -1;
#if defined (__linux) && defined(SYS_gettid)
ret = syscall(SYS_gettid); /* available since Linux 1.4.11 */
#elif defined(__sun)
ret = pthread_self();
#elif defined(__APPLE__)
ret = mach_thread_self();
mach_port_deallocate(mach_task_self(), ret);
#elif defined(__FreeBSD__) && defined(HAVE_SYS_THR_H)
long lwpid;
thr_self(&lwpid); /* available since sys/thr.h creation 2003 */
ret = lwpid;
#endif
return ret;
}
| int ast_get_time_t | ( | const char * | src, |
| time_t * | dst, | ||
| time_t | _default, | ||
| int * | consumed | ||
| ) |
get values from config variables.
Definition at line 2098 of file main/utils.c.
References ast_strlen_zero().
Referenced by build_peer(), cache_lookup_internal(), dundi_show_cache(), dundi_show_hints(), 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 2071 of file main/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 195 of file main/utils.c.
References ast_hostent::buf, and ast_hostent::hp.
Referenced by 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(), process_sdp(), realtime_peer(), realtime_user(), reload_config(), 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 553 of file main/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(), _stun_show_status(), acf_channel_read(), add_sdp(), ast_apply_ha(), ast_parse_arg(), authenticate(), calltoken_required(), check_access(), config_load(), create_client(), data_get_xml_add_child(), data_result_manager_output(), data_result_print_cli_node(), dump_addr(), dump_ipaddr(), dundi_rexmit(), dundi_show_peer(), dundi_show_peers(), dundi_show_trans(), dundi_showframe(), dundi_xmit(), external_rtp_create(), find_command(), find_peer(), find_subchannel_and_lock(), find_tpeer(), function_iaxpeer(), gtalk_show_settings(), 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_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(), raw_hangup(), realtime_peer(), realtime_user(), register_verify(), registry_rerequest(), reload_config(), resend_response(), rtp_reload(), sched_delay_remove(), score_address(), send_packet(), send_raw_client(), send_request(), send_response(), send_start_rtp(), send_trunk(), set_config(), set_peercnt_limit(), setup_incoming_call(), show_main_page(), skinny_session(), skinny_set_rtp_peer(), socket_process_helper(), socket_process_meta(), start_rtp(), stun_monitor_request(), timing_read(), transmit_serverres(), transmit_startmediatransmission(), unistim_show_devices(), unistim_show_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 1690 of file main/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().
| 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 245 of file main/utils.c.
References MD5Final(), MD5Init(), and MD5Update().
Referenced by __init_manager(), auth_exec(), auth_http_callback(), build_reply_digest(), check_auth(), and md5().
| int ast_mkdir | ( | const char * | path, |
| int | mode | ||
| ) |
Recursively create directory path.
| path | The directory path to create |
| mode | The permissions with which to try to create the directory |
Creates a directory path, creating parent directories as needed.
Definition at line 2131 of file main/utils.c.
References ast_alloca, errno, and len().
Referenced by ast_monitor_change_fname(), ast_monitor_start(), conf_rec_name(), conf_run(), create_dirpath(), dictate_exec(), filename_parse(), init_logger(), load_module(), 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 = ast_alloca(len + 1);
int res = 0;
for (ptr = tmp; *ptr; ptr++) {
if (*ptr == '/')
count++;
}
/* Count the components to the directory path */
pieces = ast_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.
Definition at line 2200 of file main/utils.c.
References ast_free, ast_log(), ast_skip_blanks(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_string_field_ptr_set, ast_string_field_set, ast_strlen_zero(), ast_unescape_c(), ast_http_digest::cnonce, ast_http_digest::domain, LOG_WARNING, ast_http_digest::nc, ast_http_digest::nonce, ast_http_digest::opaque, 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().
{
char *c;
struct ast_str *str = ast_str_create(16);
/* table of recognised keywords, and places where they should be copied */
const struct x {
const char *key;
const ast_string_field *field;
} *i, keys[] = {
{ "username=", &d->username },
{ "realm=", &d->realm },
{ "nonce=", &d->nonce },
{ "uri=", &d->uri },
{ "domain=", &d->domain },
{ "response=", &d->response },
{ "cnonce=", &d->cnonce },
{ "opaque=", &d->opaque },
/* Special cases that cannot be directly copied */
{ "algorithm=", NULL },
{ "qop=", NULL },
{ "nc=", NULL },
{ NULL, 0 },
};
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 && *(c = ast_skip_blanks(c))) {
/* find key */
for (i = keys; i->key != NULL; i++) {
char *src, *separator;
int unescape = 0;
if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
continue;
}
/* Found. Skip keyword, take text in quotes or up to the separator. */
c += strlen(i->key);
if (*c == '"') {
src = ++c;
separator = "\"";
unescape = 1;
} else {
src = c;
separator = ",";
}
strsep(&c, separator); /* clear separator and move ptr */
if (unescape) {
ast_unescape_c(src);
}
if (i->field) {
ast_string_field_ptr_set(d, i->field, src);
} else {
/* Special cases that require additional procesing */
if (!strcasecmp(i->key, "algorithm=")) {
if (strcasecmp(src, "MD5")) {
ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", src);
ast_free(str);
return -1;
}
} else if (!strcasecmp(i->key, "qop=") && !strcasecmp(src, "auth")) {
d->qop = 1;
} else if (!strcasecmp(i->key, "nc=")) {
unsigned long u;
if (sscanf(src, "%30lx", &u) != 1) {
ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", src);
ast_free(str);
return -1;
}
ast_string_field_set(d, nc, src);
}
}
break;
}
if (i->key == NULL) { /* not found, try ',' */
strsep(&c, ",");
}
}
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.
| 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 1664 of file main/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 1219 of file main/utils.c.
References ast_alloca, ast_log(), ast_pthread_create_stack(), errno, LOG_WARNING, and thr_arg::start_routine.
{
unsigned char attr_destroy = 0;
int res;
if (!attr) {
attr = ast_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 1171 of file main/utils.c.
References ast_alloca, ast_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 = ast_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 (ast_asprintf(&a->name, "%-20s started at [%5d] %s %s()",
start_fn, line, file, caller) < 0) {
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 1631 of file main/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(), app_exec(), 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_localtag_registry(), build_nonce(), 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_add_ice_udp_candidates_to_transport(), jingle_alloc(), jingle_create_candidates(), jingle_new(), load_module(), 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(), rec_request(), reg_source_db(), registry_authrequest(), reqprep(), say_periodic_announcement(), sendmail(), 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;
}
| int ast_regex_string_to_regex_pattern | ( | const char * | regex_string, |
| struct ast_str ** | regex_pattern | ||
| ) |
Given a string regex_string in the form of "/regex/", convert it into the form of "regex".
This function will trim one leading / and one trailing / from a given input string ast_str regex_pattern must be preallocated before calling this function
| regex_string | the string containing /regex/ |
| regex_pattern | the destination ast_str which will contain "regex" after execution |
Definition at line 1504 of file main/utils.c.
References ast_str_set(), and ast_str_truncate().
Referenced by action_hangup().
{
int regex_len = strlen(regex_string);
int ret = 3;
/* Chop off the leading / if there is one */
if ((regex_len >= 1) && (regex_string[0] == '/')) {
ast_str_set(regex_pattern, 0, "%s", regex_string + 1);
ret -= 2;
}
/* Chop off the ending / if there is one */
if ((regex_len > 1) && (regex_string[regex_len - 1] == '/')) {
ast_str_truncate(*regex_pattern, -1);
ret -= 1;
}
return ret;
}
| int ast_remaining_ms | ( | struct timeval | start, |
| int | max_ms | ||
| ) |
Calculate remaining milliseconds given a starting timestamp and upper bound.
If the upper bound is negative, then this indicates that there is no upper bound on the amount of time to wait. This will result in a negative return.
| start | When timing started being calculated |
| max_ms | The maximum number of milliseconds to wait from start. May be negative. |
Definition at line 1606 of file main/utils.c.
References ast_tvdiff_ms(), and ast_tvnow().
Referenced by __analog_ss_thread(), __ast_answer(), __ast_request_and_dial(), agent_ack_sleep(), analog_ss_thread(), ast_recvtext(), ast_safe_sleep_conditional(), ast_waitfordigit_full(), async_wait(), dahdi_bridge(), disable_t38(), do_idle_thread(), find_cache(), generic_fax_exec(), local_bridge_loop(), receivefax_t38_init(), record_exec(), remote_bridge_loop(), sendfax_t38_init(), wait_for_answer(), and waitforring_exec().
{
int ms;
if (max_ms < 0) {
ms = max_ms;
} else {
ms = max_ms - ast_tvdiff_ms(ast_tvnow(), start);
if (ms < 0) {
ms = 0;
}
}
return ms;
}
| void ast_replace_subargument_delimiter | ( | char * | s | ) |
Replace '^' in a string with ','.
| s | String within which to replace characters |
Definition at line 1655 of file main/utils.c.
Referenced by app_exec(), bridge_exec(), dial_exec_full(), and try_calling().
{
for (; *s; s++) {
if (*s == '^') {
*s = ',';
}
}
}
| 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 261 of file main/utils.c.
References SHA1Input(), SHA1Reset(), and SHA1Result().
Referenced by aji_act_hook(), handle_call_token(), jabber_make_auth(), sha1(), xmpp_client_authenticate_digest(), and xmpp_component_authenticate().
{
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]);
}
| void ast_sha1_hash_uint | ( | uint8_t * | digest, |
| const char * | input | ||
| ) |
Produce a 20 byte SHA1 hash of value.
Produces SHA1 hash based on input string, stored in uint8_t array.
Definition at line 279 of file main/utils.c.
References SHA1Input(), SHA1Reset(), and SHA1Result().
Referenced by websocket_callback().
{
struct SHA1Context sha;
SHA1Reset(&sha);
SHA1Input(&sha, (const unsigned char *) input, strlen(input));
SHA1Result(&sha, digest);
}
| char* ast_strip_quoted | ( | char * | s, |
| const char * | beg_quotes, | ||
| const char * | end_quotes | ||
| ) |
Strip leading/trailing whitespace and quotes from a string.
| 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. |
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 1402 of file main/utils.c.
References ast_strip().
Referenced by ast_register_file_version(), get_rdnis(), iftime(), load_values_config(), parse_allowed_methods(), parse_cookies(), parse_dial_string(), and sip_parse_register_line().
{
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".
| 0 | if val is a NULL pointer. |
| -1 | if "true". |
| 0 | otherwise. |
Definition at line 1524 of file main/utils.c.
References ast_strlen_zero().
Referenced by __ast_http_load(), __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_rtp_dtls_cfg_parse(), ast_tls_read_conf(), autopause2int(), bool_handler_fn(), boolflag_handler_fn(), build_device(), build_gateway(), build_peer(), build_user(), client_bitfield_handler(), config_parse_variables(), custom_bitfield_handler(), 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(), global_bitfield_handler(), gtalk_load_config(), handle_common_options(), handle_logger_set_level(), handle_mfcr2_call_files(), handle_queue_set_member_ringinuse(), handle_t38_options(), init_logger_chain(), jingle_load_config(), load_config(), load_config_meetme(), load_format_config(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), local_ast_moh_start(), login_exec(), manager_add_queue_member(), manager_mutestream(), manager_pause_queue_member(), manager_queue_member_ringinuse(), message_template_build(), misdn_answer(), new_realtime_sqlite3_db(), 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(), reload_single_member(), rt_handle_member_record(), rtp_reload(), run_agi(), run_startup_commands(), search_directory(), search_directory_sub(), set_active(), set_config(), sla_load_config(), smdi_load(), speex_write(), stackpeek_read(), 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_tvadd | ( | struct timeval | a, |
| struct timeval | b | ||
| ) | [read] |
Returns the sum of two timevals a + b.
Definition at line 1578 of file main/utils.c.
References ONE_MILLION, and tvfix().
Referenced by __get_from_jb(), acf_jabberreceive_read(), agent_hangup(), ast_audiohook_trigger_wait(), ast_channel_bridge(), ast_channel_cmpwhentohangup_tv(), ast_channel_setwhentohangup_tv(), ast_generic_bridge(), ast_poll2(), ast_rtp_dtmf_begin(), ast_rtp_dtmf_end_with_duration(), ast_rtp_sendcng(), ast_sched_runq(), ast_smoother_read(), ast_translate(), calc_rxstamp(), calc_timestamp(), cli_tps_ping(), conf_run(), dial_exec_full(), do_cdr(), do_timing(), hook_event_cb(), iax2_process_thread(), jb_get_and_deliver(), mb_poll_thread(), monmp3thread(), mp3_exec(), mwi_monitor_handler(), NBScat_exec(), sched_run(), sched_settime(), schedule_delivery(), sla_process_timers(), smdi_message_wait(), and timeout_write().
{
/* 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 >= ONE_MILLION) {
a.tv_sec++;
a.tv_usec -= ONE_MILLION;
}
return a;
}
| struct timeval ast_tvsub | ( | struct timeval | a, |
| struct timeval | b | ||
| ) | [read] |
Returns the difference of two timevals a - b.
Definition at line 1592 of file main/utils.c.
References ONE_MILLION, and tvfix().
Referenced by 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).
Definition at line 1438 of file main/utils.c.
Referenced by ast_parse_digest().
{
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).
Definition at line 1419 of file main/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, |
| struct ast_flags | spec | ||
| ) |
Decode URI, URN, URL (overwrite string)
| s | string to be decoded |
| spec | flags describing how the decoding should be performed |
Definition at line 441 of file main/utils.c.
References ast_test_flag, and AST_URI_LEGACY_SPACE.
Referenced by acf_curl_helper(), ast_http_get_post_vars(), config_curl(), get_destination(), get_name_and_number(), get_refer_info(), handle_request_invite(), handle_uri(), parse_moved_contact(), realtime_curl(), realtime_multi_curl(), sip_new(), sip_uri_cmp(), and uridecode().
{
char *o;
unsigned int tmp;
for (o = s; *s; s++, o++) {
if (ast_test_flag(&spec, AST_URI_LEGACY_SPACE) && *s == '+') {
/* legacy mode, decode '+' as space */
*o = ' ';
} else 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, | ||
| struct ast_flags | spec | ||
| ) |
Turn text string to URI-encoded XX version.
This function encodes characters according to the rules presented in RFC 2396 and/or RFC 3261 section 19.1.2 and section 25.1.
Outbuf needs to have more memory allocated than the instring to have room for the expansion. Every byte that is converted is replaced by three ASCII characters.
| string | string to be converted |
| outbuf | resulting encoded string |
| buflen | size of output buffer |
| spec | flags describing how the encoding should be performed |
Definition at line 402 of file main/utils.c.
References ast_test_flag, AST_URI_ALPHANUM, AST_URI_LEGACY_SPACE, AST_URI_MARK, AST_URI_SIP_USER_UNRESERVED, and 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 */
const char *user_unreserved = "&=+$,;?/"; /* user-unreserved set, RFC 3261 sec 25 */
while (*ptr && out - outbuf < buflen - 1) {
if (ast_test_flag(&spec, AST_URI_LEGACY_SPACE) && *ptr == ' ') {
/* for legacy encoding, encode spaces as '+' */
*out = '+';
out++;
} else if (!(ast_test_flag(&spec, AST_URI_MARK)
&& strchr(mark, *ptr))
&& !(ast_test_flag(&spec, AST_URI_ALPHANUM)
&& ((*ptr >= '0' && *ptr <= '9')
|| (*ptr >= 'A' && *ptr <= 'Z')
|| (*ptr >= 'a' && *ptr <= 'z')))
&& !(ast_test_flag(&spec, AST_URI_SIP_USER_UNRESERVED)
&& strchr(user_unreserved, *ptr))) {
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 2177 of file main/utils.c.
References ARRAY_LEN, ast_cli_register_multiple(), ast_register_atexit(), base64_init(), and utils_shutdown().
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
ast_register_atexit(utils_shutdown);
return 0;
}
| char* ast_utils_which | ( | const char * | binary, |
| char * | fullpath, | ||
| size_t | fullpath_size | ||
| ) |
Resolve a binary to a full pathname.
| binary | Name of the executable to resolve |
| fullpath | Buffer to hold the complete pathname |
| fullpath_size | Size of fullpath |
| NULL | binary was not found or the environment variable PATH is not set |
Definition at line 2348 of file main/utils.c.
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 1244 of file main/utils.c.
References ast_poll.
Referenced by action_waitevent(), ast_tcptls_server_root(), dahdi_test_timer(), get_input(), moh_class_destructor(), sip_tcp_read(), sip_tls_read(), sip_websocket_callback(), websocket_echo_callback(), and ws_safe_read().
{
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 1253 of file main/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;
}
| int ast_xml_escape | ( | const char * | string, |
| char * | outbuf, | ||
| size_t | buflen | ||
| ) |
Escape reserved characters for use in XML.
ast_xml_escape If outbuf is too short, the output string will be truncated. Regardless, the output will always be null terminated.
| string | String to be converted |
| outbuf | Resulting encoded string |
| buflen | Size of output buffer |
Definition at line 489 of file main/utils.c.
References ast_assert, entity, len(), and string.
Referenced by state_notify_build_xml().
{
char *dst = outbuf;
char *end = outbuf + buflen - 1; /* save one for the null terminator */
/* Handle the case for the empty output buffer */
if (buflen == 0) {
return -1;
}
/* Escaping rules from http://www.w3.org/TR/REC-xml/#syntax */
/* This also prevents partial entities at the end of a string */
while (*string && dst < end) {
const char *entity = NULL;
int len = 0;
switch (*string) {
case '<':
entity = "<";
len = 4;
break;
case '&':
entity = "&";
len = 5;
break;
case '>':
/* necessary if ]]> is in the string; easier to escape them all */
entity = ">";
len = 4;
break;
case '\'':
/* necessary in single-quoted strings; easier to escape them all */
entity = "'";
len = 6;
break;
case '"':
/* necessary in double-quoted strings; easier to escape them all */
entity = """;
len = 6;
break;
default:
*dst++ = *string++;
break;
}
if (entity) {
ast_assert(len == strlen(entity));
if (end - dst < len) {
/* no room for the entity; stop */
break;
}
/* just checked for length; strcpy is fine */
strcpy(dst, entity);
dst += len;
++string;
}
}
/* Write null terminator */
*dst = '\0';
/* If any chars are left in string, return failure */
return *string == '\0' ? 0 : -1;
}
| static void base64_init | ( | void | ) | [static] |
Definition at line 374 of file main/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 1129 of file main/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;
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 */
/* 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());
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 1729 of file main/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 1563 of file main/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;
}
| static void utils_shutdown | ( | void | ) | [static] |
Definition at line 2166 of file main/utils.c.
References ARRAY_LEN, and ast_cli_unregister_multiple().
Referenced by ast_utils_init().
{
#ifdef HAVE_DEV_URANDOM
close(dev_urandom_fd);
dev_urandom_fd = -1;
#endif
#if defined(DEBUG_THREADS) && !defined(LOW_MEMORY)
ast_cli_unregister_multiple(utils_cli, ARRAY_LEN(utils_cli));
#endif
}
Definition at line 1725 of file main/utils.c.
Referenced by __ast_calloc_with_stringfields(), and __ast_string_field_init().
struct { ... } __ast_string_field_empty_buffer [static] |
Definition at line 1721 of file main/utils.c.
Referenced by __ast_calloc_with_stringfields().
| struct ast_flags ast_uri_http = {AST_URI_UNRESERVED} |
Definition at line 398 of file main/utils.c.
Referenced by acf_curl_helper(), config_curl(), destroy_curl(), launch_asyncagi(), realtime_curl(), realtime_multi_curl(), require_curl(), store_curl(), update2_curl(), update_curl(), uridecode(), and uriencode().
Definition at line 399 of file main/utils.c.
Referenced by acf_curl_helper(), ast_http_get_post_vars(), and handle_uri().
Definition at line 400 of file main/utils.c.
Referenced by add_rpid(), build_contact(), get_destination(), get_name_and_number(), get_refer_info(), handle_request_invite(), initreqprep(), parse_moved_contact(), sip_new(), and sip_uri_cmp().
char b2a[256] [static] |
Definition at line 79 of file main/utils.c.
char base64[64] [static] |
Definition at line 78 of file main/utils.c.
Referenced by aji_start_sasl(), websocket_callback(), and xmpp_client_authenticate_sasl().
int dev_urandom_fd [static] |
Definition at line 564 of file main/utils.c.
ast_mutex_t fetchadd_m = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 2056 of file main/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 81 of file main/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 1628 of file main/utils.c.
Referenced by ast_random().
| char string[1] |
Definition at line 1722 of file main/utils.c.