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 "asterisk/config.h"
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 | AST_API_MODULE |
#define | ERANGE 34 |
#define | ONE_MILLION 1000000 |
Functions | |
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) |
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. | |
AST_THREADSTORAGE_CUSTOM_SCOPE (inet_ntoa_buf, NULL, ast_free_ptr, static) | |
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) |
char * | ast_utils_which (const char *binary, char *fullpath, size_t fullpath_size) |
Resolve a binary to a full pathname. | |
int | ast_wait_for_input (int fd, int ms) |
static int | ast_wait_for_output (int fd, int timeoutms) |
static void | base64_init (void) |
static void * | dummy_start (void *data) |
static 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_INIT_VALUE |
static char | b2a [256] |
static char | base64 [64] |
static ast_mutex_t | fetchadd_m = AST_MUTEX_INIT_VALUE |
static ast_mutex_t | randomlock = AST_MUTEX_INIT_VALUE |
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 utils.c.
#define ERANGE 34 |
duh? ERANGE value copied from web...
Definition at line 73 of file utils.c.
Referenced by gethostbyname_r(), and reload_queue_members().
#define ONE_MILLION 1000000 |
Definition at line 1347 of file utils.c.
Referenced by ast_tvadd(), ast_tvsub(), and tvfix().
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 1570 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.
{ char *result = NULL; size_t space = mgr->size - mgr->used; if (__builtin_expect(needed > space, 0)) { size_t new_size = mgr->size * 2; while (new_size < needed) 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 } result = (*pool_head)->base + mgr->used; mgr->used += 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 1516 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.
{ 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; return add_string_pool(mgr, pool_head, needed, file, lineno, func); } if (needed < 0) { /* reset all pools */ if (*pool_head == NULL) { ast_log(LOG_WARNING, "trying to reset empty pool\n"); return -1; } cur = *pool_head; } else { /* preserve the last pool */ if (*pool_head == NULL) { ast_log(LOG_WARNING, "trying to reset empty pool\n"); return -1; } mgr->used = 0; preserve = *pool_head; cur = preserve->prev; } if (preserve) { preserve->prev = NULL; } 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 1676 of file utils.c.
References __ast_string_field_ptr_build_va().
{ va_list ap1, ap2; va_start(ap1, format); va_start(ap2, format); /* va_copy does not exist on FreeBSD */ __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2); va_end(ap1); va_end(ap2); }
void __ast_string_field_ptr_build_va | ( | struct ast_string_field_mgr * | mgr, |
struct ast_string_field_pool ** | pool_head, | ||
ast_string_field * | ptr, | ||
const char * | format, | ||
va_list | ap1, | ||
va_list | ap2 | ||
) |
Definition at line 1620 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().
{ size_t needed; size_t available; size_t space = mgr->size - mgr->used; char *target; /* if the field already has space allocated, try to reuse it; otherwise, use the empty space at the end of the current pool */ if ((*ptr)[0] != '\0') { target = (char *) *ptr; available = strlen(target) + 1; } else { target = (*pool_head)->base + mgr->used; available = space; } needed = vsnprintf(target, available, format, ap1) + 1; va_end(ap1); if (needed > available) { /* if the space needed can be satisfied by using the current pool (which could only occur if we tried to use the field's allocated space and failed), then use that space; otherwise allocate a new pool */ if (needed > space) { size_t new_size = mgr->size * 2; while (new_size < needed) 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; #else if (add_string_pool(mgr, pool_head, new_size, NULL, 0, NULL)) return; #endif } target = (*pool_head)->base + mgr->used; vsprintf(target, format, ap2); } if (*ptr != target) { mgr->last_alloc = *ptr = target; mgr->used += needed; } }
int __ast_string_field_ptr_grow | ( | struct ast_string_field_mgr * | mgr, |
size_t | needed, | ||
const ast_string_field * | ptr | ||
) |
Definition at line 1597 of file utils.c.
References ast_string_field_mgr::last_alloc, ast_string_field_mgr::size, and ast_string_field_mgr::used.
{ int grow = needed - (strlen(*ptr) + 1); size_t space = mgr->size - mgr->used; if (grow <= 0) { return 0; } if (*ptr != mgr->last_alloc) { return 1; } if (space < grow) { return 1; } mgr->used += grow; return 0; }
int _ast_asprintf | ( | char ** | ret, |
const char * | file, | ||
int | lineno, | ||
const char * | func, | ||
const char * | fmt, | ||
... | |||
) |
Definition at line 1817 of file utils.c.
References MALLOC_FAILURE_MSG, and vasprintf.
{ int res; va_list ap; va_start(ap, fmt); if ((res = vasprintf(ret, fmt, ap)) == -1) { MALLOC_FAILURE_MSG; } va_end(ap); return res; }
static int add_string_pool | ( | struct ast_string_field_mgr * | mgr, |
struct ast_string_field_pool ** | pool_head, | ||
size_t | size, | ||
const char * | file, | ||
int | lineno, | ||
const char * | func | ||
) | [static] |
add a new block to the pool. We can only allocate from the topmost pool, so the fields in *mgr reflect the size of that only.
Definition at line 1482 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().
{ struct ast_string_field_pool *pool; #if defined(__AST_DEBUG_MALLOC) if (!(pool = __ast_calloc(1, sizeof(*pool) + size, file, lineno, func))) { return -1; } #else if (!(pool = ast_calloc(1, sizeof(*pool) + size))) { return -1; } #endif pool->prev = *pool_head; *pool_head = pool; mgr->size = size; mgr->used = 0; mgr->last_alloc = NULL; return 0; }
int ast_atomic_fetchadd_int_slow | ( | volatile int * | p, |
int | v | ||
) |
Definition at line 1694 of file utils.c.
References ast_mutex_lock(), ast_mutex_unlock(), and fetchadd_m.
{ int ret; ast_mutex_lock(&fetchadd_m); ret = *p; *p += v; ast_mutex_unlock(&fetchadd_m); return ret; }
int ast_base64decode | ( | unsigned char * | dst, |
const char * | src, | ||
int | max | ||
) |
decode BASE64 encoded text
Decode data from base64.
Definition at line 267 of file utils.c.
Referenced by __ast_check_signature(), aes_helper(), base64_decode(), and osp_validate_token().
{ int cnt = 0; unsigned int byte = 0; unsigned int bits = 0; int incnt = 0; while(*src && *src != '=' && (cnt < max)) { /* Shift in 6 bits of input */ byte <<= 6; byte |= (b2a[(int)(*src)]) & 0x3f; bits += 6; src++; incnt++; /* If we have at least 8 bits left over, take that character off the top */ if (bits >= 8) { bits -= 8; *dst = (byte >> bits) & 0xff; dst++; cnt++; } } /* Dont 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 345 of file utils.c.
References ast_base64encode_full().
Referenced by __ast_sign(), aes_helper(), aji_start_sasl(), base64_encode(), build_secret(), and osp_check_destination().
{ return ast_base64encode_full(dst, src, srclen, max, 0); }
int ast_base64encode_full | ( | char * | dst, |
const unsigned char * | src, | ||
int | srclen, | ||
int | max, | ||
int | linebreaks | ||
) |
encode text to BASE64 coding
Definition at line 294 of file utils.c.
Referenced by ast_base64encode().
{ int cnt = 0; int col = 0; unsigned int byte = 0; int bits = 0; int cntin = 0; /* Reserve space for null byte at end of string */ max--; while ((cntin < srclen) && (cnt < max)) { byte <<= 8; byte |= *(src++); bits += 8; cntin++; if ((bits == 24) && (cnt + 4 <= max)) { *dst++ = base64[(byte >> 18) & 0x3f]; *dst++ = base64[(byte >> 12) & 0x3f]; *dst++ = base64[(byte >> 6) & 0x3f]; *dst++ = base64[byte & 0x3f]; cnt += 4; col += 4; bits = 0; byte = 0; } if (linebreaks && (cnt < max) && (col == 64)) { *dst++ = '\n'; cnt++; col = 0; } } if (bits && (cnt + 4 <= max)) { /* Add one last character for the remaining bits, padding the rest with 0 */ byte <<= 24 - bits; *dst++ = base64[(byte >> 18) & 0x3f]; *dst++ = base64[(byte >> 12) & 0x3f]; if (bits == 16) *dst++ = base64[(byte >> 6) & 0x3f]; else *dst++ = '='; *dst++ = '='; cnt += 4; } if (linebreaks && (cnt < max)) { *dst++ = '\n'; cnt++; } *dst = '\0'; return cnt; }
int ast_build_string | ( | char ** | buffer, |
size_t * | space, | ||
const char * | fmt, | ||
... | |||
) |
Build a string in a buffer, designed to be called repeatedly.
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 1301 of file utils.c.
References ast_build_string_va().
Referenced by config_odbc(), handle_speechrecognize(), lua_func_read(), lua_pbx_exec(), pp_each_extension_exec(), and pp_each_user_exec().
{ 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 1282 of file utils.c.
Referenced by ast_build_string().
{ int result; if (!buffer || !*buffer || !space || !*space) return -1; result = vsnprintf(*buffer, *space, fmt, ap); if (result < 0) return -1; else if (result > *space) result = *space; *buffer += result; *space -= result; return 0; }
int ast_careful_fwrite | ( | FILE * | f, |
int | fd, | ||
const char * | s, | ||
size_t | len, | ||
int | timeoutms | ||
) |
Write data to a file stream with a timeout.
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 1156 of file utils.c.
References ast_log(), ast_tvdiff_ms(), ast_tvnow(), ast_wait_for_output(), errno, fwrite, and LOG_ERROR.
Referenced by send_string().
{ 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 1115 of file utils.c.
References ast_log(), ast_tvdiff_ms(), ast_tvnow(), ast_wait_for_output(), errno, and LOG_ERROR.
Referenced by ast_agi_send(), and ast_cli().
{ struct timeval start = ast_tvnow(); int res = 0; int elapsed = 0; while (len) { if (ast_wait_for_output(fd, timeoutms - elapsed)) { return -1; } res = write(fd, s, len); if (res < 0 && errno != EAGAIN && errno != EINTR) { /* fatal error from write() */ ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno)); return -1; } if (res < 0) { /* It was an acceptable error */ res = 0; } /* Update how much data we have left to write */ len -= res; s += res; res = 0; elapsed = ast_tvdiff_ms(ast_tvnow(), start); if (elapsed >= timeoutms) { /* We've taken too long to write * This is only an error condition if we haven't finished writing. */ res = len ? -1 : 0; break; } } return res; }
void ast_enable_packet_fragmentation | ( | int | sock | ) |
Disable PMTU discovery on a socket.
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 1757 of file utils.c.
References ast_log(), and LOG_WARNING.
Referenced by ast_netsock_bindaddr(), and reload_config().
{ #if defined(HAVE_IP_MTU_DISCOVER) int val = IP_PMTUDISC_DONT; if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val))) ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n"); #endif /* HAVE_IP_MTU_DISCOVER */ }
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 1330 of file utils.c.
References ast_strlen_zero().
Referenced by __ast_rtp_reload(), __ast_udptl_reload(), acf_transaction_write(), aji_create_client(), aji_load_config(), build_peer(), build_user(), dahdi_set_dnd(), find_realtime(), func_channel_write_real(), handle_common_options(), init_acf_query(), load_config(), load_odbc_config(), parse_empty_options(), reload_config(), run_agi(), set_config(), set_insecure_flags(), sla_build_trunk(), and strings_to_mask().
int ast_get_time_t | ( | const char * | src, |
time_t * | dst, | ||
time_t | _default, | ||
int * | consumed | ||
) |
get values from config variables.
Definition at line 1734 of file utils.c.
References ast_strlen_zero().
Referenced by build_peer(), cache_lookup_internal(), handle_saydatetime(), load_password(), play_message_datetime(), process_clearcache(), realtime_peer(), and sayunixtime_exec().
{ long t; int scanned; if (dst == NULL) return -1; *dst = _default; if (ast_strlen_zero(src)) return -1; /* only integer at the moment, but one day we could accept more formats */ if (sscanf(src, "%30ld%n", &t, &scanned) == 1) { *dst = t; if (consumed) *consumed = scanned; return 0; } else return -1; }
int ast_get_timeval | ( | const char * | src, |
struct timeval * | dst, | ||
struct timeval | _default, | ||
int * | consumed | ||
) |
get values from config variables.
Definition at line 1707 of file utils.c.
References ast_strlen_zero().
Referenced by acf_strftime().
{ long double dtv = 0.0; int scanned; if (dst == NULL) return -1; *dst = _default; if (ast_strlen_zero(src)) return -1; /* only integer at the moment, but one day we could accept more formats */ if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) { dst->tv_sec = dtv; dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0; if (consumed) *consumed = scanned; return 0; } else return -1; }
struct hostent* ast_gethostbyname | ( | const char * | host, |
struct ast_hostent * | hp | ||
) | [read] |
Re-entrant (thread safe) version of gethostbyname that replaces the standard gethostbyname (which is not thread safe)
Thread-safe gethostbyname function to use in Asterisk.
Definition at line 183 of file utils.c.
References ast_hostent::buf, gethostbyname_r(), ast_hostent::hp, and s.
Referenced by __ast_http_load(), __init_manager(), __set_address_from_contact(), app_exec(), ast_find_ourip(), ast_get_ip_or_srv(), ast_parse_arg(), build_peer(), check_via(), config_load(), config_parse_variables(), create_addr(), festival_exec(), get_ip_and_port_from_sdp(), gtalk_load_config(), gtalk_update_stun(), handle_cli_udptl_set_debug(), iax_template_parse(), jingle_load_config(), jingle_update_stun(), launch_netscript(), parse_register_contact(), process_sdp(), process_sdp_c(), process_via(), 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().
{ 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 433 of file utils.c.
References ast_threadstorage_get(), and buf.
Referenced by __attempt_transmit(), __find_callno(), __iax2_show_peers(), __sip_xmit(), _sip_show_peer(), _sip_show_peers(), _skinny_show_device(), _skinny_show_devices(), 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_with_duration(), ast_sip_ouraddrfor(), ast_tcptls_client_create(), 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(), config_load(), copy_via_headers(), create_addr_from_peer(), create_client(), create_dtmf_frame(), dnsmgr_refresh(), do_message(), dump_addr(), dump_ipaddr(), dundi_rexmit(), dundi_show_peer(), dundi_show_peers(), dundi_show_trans(), dundi_showframe(), dundi_xmit(), external_rtp_create(), find_command(), find_peer(), find_subchannel_and_lock(), find_tpeer(), function_iaxpeer(), function_sipchaninfo_read(), function_sippeer(), generic_http_callback(), get_input(), gtalk_create_candidates(), 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_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_notify(), handle_response_refer(), handle_show_http(), handle_showmanconn(), 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(), manager_iax2_show_registry(), 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_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_chanstats_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().
{ 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, | ||
char *const | w[] | ||
) |
Definition at line 1453 of file utils.c.
References len().
Referenced by __ast_cli_generator(), ast_agi_register(), ast_agi_unregister(), ast_cli_command_full(), cli_console_sendtext(), console_sendtext(), find_best(), handle_cli_agi_show(), handle_cli_check_permissions(), handle_help(), help1(), help_workhorse(), set_full_cmd(), and write_htmldump().
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 233 of file utils.c.
References MD5Final(), MD5Init(), and MD5Update().
Referenced by auth_exec(), 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 1767 of file utils.c.
References ast_strdupa, errno, and len().
Referenced by ast_monitor_change_fname(), ast_monitor_start(), conf_run(), create_dirpath(), dictate_exec(), init_logger(), load_module(), mixmonitor_exec(), record_exec(), reload_logger(), remove_from_queue(), setup_privacy_args(), sms_nextoutgoing(), sms_writefile(), testclient_exec(), testserver_exec(), and write_history().
{ char *ptr; int len = strlen(path), count = 0, x, piececount = 0; char *tmp = ast_strdupa(path); char **pieces; char *fullpath = alloca(len + 1); int res = 0; for (ptr = tmp; *ptr; ptr++) { if (*ptr == '/') count++; } /* Count the components to the directory path */ pieces = alloca(count * sizeof(*pieces)); for (ptr = tmp; *ptr; ptr++) { if (*ptr == '/') { *ptr = '\0'; pieces[piececount++] = ptr + 1; } } *fullpath = '\0'; for (x = 0; x < piececount; x++) { /* This looks funky, but the buffer is always ideally-sized, so it's fine. */ strcat(fullpath, "/"); strcat(fullpath, pieces[x]); res = mkdir(fullpath, mode); if (res && errno != EEXIST) return errno; } return 0; }
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 1427 of file utils.c.
{ char *dataPut = start; int inEscape = 0; int inQuotes = 0; for (; *start; start++) { if (inEscape) { *dataPut++ = *start; /* Always goes verbatim */ inEscape = 0; } else { if (*start == '\\') { inEscape = 1; /* Do not copy \ into the data */ } else if (*start == '\'') { inQuotes = 1 - inQuotes; /* Do not copy ' into the data */ } else { /* Replace , with |, unless in quotes */ *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start); } } } if (start != dataPut) *dataPut = 0; return dataPut; }
int ast_pthread_create_detached_stack | ( | pthread_t * | thread, |
pthread_attr_t * | attr, | ||
void *(*)(void *) | start_routine, | ||
void * | data, | ||
size_t | stacksize, | ||
const char * | file, | ||
const char * | caller, | ||
int | line, | ||
const char * | start_fn | ||
) |
Definition at line 1028 of file utils.c.
References ast_log(), ast_pthread_create_stack(), errno, LOG_WARNING, and thr_arg::start_routine.
{ unsigned char attr_destroy = 0; int res; if (!attr) { attr = alloca(sizeof(*attr)); pthread_attr_init(attr); attr_destroy = 1; } if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED))) ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno)); res = ast_pthread_create_stack(thread, attr, start_routine, data, stacksize, file, caller, line, start_fn); if (attr_destroy) pthread_attr_destroy(attr); return res; }
int ast_pthread_create_stack | ( | pthread_t * | thread, |
pthread_attr_t * | attr, | ||
void *(*)(void *) | start_routine, | ||
void * | data, | ||
size_t | stacksize, | ||
const char * | file, | ||
const char * | caller, | ||
int | line, | ||
const char * | start_fn | ||
) |
Definition at line 979 of file utils.c.
References asprintf, ast_log(), ast_malloc, AST_STACKSIZE, thr_arg::data, dummy_start(), errno, LOG_WARNING, thr_arg::name, pthread_create, and thr_arg::start_routine.
Referenced by ast_pthread_create_detached_stack().
{ #if !defined(LOW_MEMORY) struct thr_arg *a; #endif if (!attr) { attr = alloca(sizeof(*attr)); pthread_attr_init(attr); } #ifdef __linux__ /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED, which is kind of useless. Change this here to PTHREAD_INHERIT_SCHED; that way the -p option to set realtime priority will propagate down to new threads by default. This does mean that callers cannot set a different priority using PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set the priority afterwards with pthread_setschedparam(). */ if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED))) ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno)); #endif if (!stacksize) stacksize = AST_STACKSIZE; if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE))) ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno)); #if !defined(LOW_MEMORY) if ((a = ast_malloc(sizeof(*a)))) { a->start_routine = start_routine; a->data = data; start_routine = dummy_start; if (asprintf(&a->name, "%-20s started at [%5d] %s %s()", start_fn, line, file, caller) < 0) { ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); a->name = NULL; } data = a; } #endif /* !LOW_MEMORY */ return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */ }
long int ast_random | ( | void | ) |
Definition at line 1403 of file utils.c.
References ast_mutex_lock(), ast_mutex_unlock(), and randomlock.
Referenced by acf_rand_exec(), action_challenge(), add_sdp(), agent_new(), agi_handle_command(), ast_lock_path_lockfile(), ast_moh_files_next(), ast_rtp_change_source(), ast_rtp_new_init(), 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_key_rotate(), iax2_start_transfer(), jingle_alloc(), jingle_create_candidates(), jingle_new(), load_module(), local_new(), make_email_file(), make_our_tag(), moh_files_alloc(), ogg_vorbis_rewrite(), osp_create_uuid(), page_exec(), park_space_reserve(), process_weights(), reg_source_db(), registry_authrequest(), reqprep(), say_periodic_announcement(), sendmail(), set_nonce_randdata(), sip_alloc(), socket_read(), start_rtp(), stun_req_id(), transmit_invite(), transmit_register(), transmit_response_using_temp(), try_calling(), and try_firmware().
{ long int res; #ifdef HAVE_DEV_URANDOM if (dev_urandom_fd >= 0) { int read_res = read(dev_urandom_fd, &res, sizeof(res)); if (read_res > 0) { long int rm = RAND_MAX; res = res < 0 ? ~res : res; rm++; return res % rm; } } #endif #ifdef linux res = random(); #else ast_mutex_lock(&randomlock); res = random(); ast_mutex_unlock(&randomlock); #endif return res; }
void ast_sha1_hash | ( | char * | output, |
char * | input | ||
) |
Produce 40 char SHA1 hash of value.
Produces SHA1 hash based on input string.
Definition at line 249 of file utils.c.
References SHA1Input(), SHA1Reset(), and SHA1Result().
Referenced by aji_act_hook(), handle_call_token(), jabber_make_auth(), and sha1().
{ struct SHA1Context sha; char *ptr; int x; uint8_t Message_Digest[20]; SHA1Reset(&sha); SHA1Input(&sha, (const unsigned char *) input, strlen(input)); SHA1Result(&sha, Message_Digest); ptr = output; for (x = 0; x < 20; x++) ptr += sprintf(ptr, "%2.2x", Message_Digest[x]); }
char* ast_strip_quoted | ( | char * | s, |
const char * | beg_quotes, | ||
const char * | end_quotes | ||
) |
Strip leading/trailing whitespace and quotes from a string.
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 1211 of file utils.c.
References ast_strip(), and s.
Referenced by ast_register_file_version(), get_rdnis(), iftime(), load_values_config(), parse_cookies(), parse_dial_string(), and sip_register().
AST_THREADSTORAGE_CUSTOM_SCOPE | ( | inet_ntoa_buf | , |
NULL | , | ||
ast_free_ptr | , | ||
static | |||
) |
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 1313 of file utils.c.
References ast_strlen_zero().
Referenced by __ast_http_load(), __ast_rtp_reload(), __ast_udptl_reload(), __init_manager(), _parse(), acf_curlopt_write(), acf_transaction_write(), 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_plc_reload(), ast_readconfig(), build_device(), build_gateway(), build_peer(), build_user(), config_parse_variables(), connect_link(), dahdi_set_dnd(), do_reload(), do_timelimit(), festival_exec(), func_channel_write_real(), func_inheritance_write(), get_encrypt_methods(), gtalk_load_config(), handle_common_options(), handle_logger_set_level(), handle_t38_options(), init_logger_chain(), jingle_load_config(), load_config(), load_config_meetme(), load_module(), load_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(), parse_empty_options(), pbx_load_config(), pbx_load_users(), process_dahdi(), process_echocancel(), queue_set_global_params(), queue_set_param(), read_agent_config(), realtime_directory(), reload_config(), run_startup_commands(), search_directory(), search_directory_sub(), set_active(), set_config(), sla_load_config(), smdi_load(), speex_write(), start_monitor_action(), strings_to_mask(), and update_common_options().
struct timeval ast_tvadd | ( | struct timeval | a, |
struct timeval | b | ||
) | [read] |
Returns the sum of two timevals a + b.
Definition at line 1367 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_channel_cmpwhentohangup_tv(), ast_channel_setwhentohangup_tv(), ast_generic_bridge(), ast_poll2(), ast_rtp_sendcng(), ast_rtp_senddigit_begin(), ast_rtp_senddigit_end_with_duration(), ast_sched_runq(), ast_smoother_read(), ast_translate(), calc_rxstamp(), calc_timestamp(), cli_tps_ping(), conf_run(), dial_exec_full(), do_cdr(), do_timing(), iax2_process_thread(), jb_get_and_deliver(), mb_poll_thread(), monmp3thread(), mp3_exec(), mwi_monitor_handler(), NBScat_exec(), sched_run(), sched_settime(), schedule_delivery(), sla_process_timers(), smdi_message_wait(), and timeout_write().
{ /* 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 1381 of file utils.c.
References ONE_MILLION, and tvfix().
Referenced by ast_channel_bridge(), ast_poll2(), ast_rwlock_timedrdlock(), ast_rwlock_timedwrlock(), ast_sched_dump(), ast_translate(), ast_waitfor_nandfds(), calc_rxstamp(), calc_timestamp(), cli_tps_ping(), conf_run(), handle_showcalls(), and handle_showuptime().
{ /* 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 1247 of file utils.c.
{ char c, *ret, *dst; if (src == NULL) return NULL; for (ret = dst = src; (c = *src++); *dst++ = c ) { if (c != '\\') continue; /* copy char at the end of the loop */ switch ((c = *src++)) { case '\0': /* special, trailing '\' */ c = '\\'; break; case 'b': /* backspace */ c = '\b'; break; case 'f': /* form feed */ c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; } /* default, use the char literally */ } *dst = '\0'; return ret; }
char* ast_unescape_semicolon | ( | char * | s | ) |
Strip backslash for "escaped" semicolons, the string to be stripped (will be modified).
Definition at line 1228 of file utils.c.
References s.
Referenced by transmit_invite(), and transmit_notify_custom().
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 416 of file utils.c.
References s.
Referenced by acf_curl_exec(), check_user_full(), config_curl(), get_also_info(), get_destination(), get_refer_info(), handle_request_invite(), http_decode(), parse_moved_contact(), realtime_curl(), realtime_multi_curl(), register_verify(), sip_new(), and uridecode().
{ char *o; unsigned int tmp; for (o = s; *s; s++, o++) { if (*s == '%' && s[1] != '\0' && s[2] != '\0' && sscanf(s + 1, "%2x", &tmp) == 1) { /* have '%', two chars and correct parsing */ *o = tmp; s += 2; /* Will be incremented once more when we break out */ } else /* all other cases, just copy */ *o = *s; } *o = '\0'; }
char* ast_uri_encode | ( | const char * | string, |
char * | outbuf, | ||
int | buflen, | ||
int | doreserved | ||
) |
ast_uri_encode: Turn text string to URI-encoded XX version
Turn text string to URI-encoded XX version.
Note: The doreserved option is needed for replaces header in SIP transfers.
Definition at line 386 of file utils.c.
Referenced by build_contact(), config_curl(), destroy_curl(), initreqprep(), launch_asyncagi(), realtime_curl(), realtime_multi_curl(), require_curl(), store_curl(), update2_curl(), update_curl(), and uriencode().
{ char *reserved = ";/?:@&=+$,# "; /* Reserved chars */ const char *ptr = string; /* Start with the string */ char *out = outbuf; /* If there's no characters to convert, just go through and copy the string */ while (*ptr && out - outbuf < buflen - 1) { if ((*ptr < 32) || (doreserved && strchr(reserved, *ptr))) { if (out - outbuf >= buflen - 3) { break; } out += sprintf(out, "%%%02x", (unsigned char) *ptr); } else { *out = *ptr; /* copy the character */ out++; } ptr++; } if (buflen) { *out = '\0'; } return outbuf; }
int ast_utils_init | ( | void | ) |
Definition at line 1802 of file utils.c.
References ARRAY_LEN, ast_cli_register_multiple(), and base64_init().
Referenced by main().
{ #ifdef HAVE_DEV_URANDOM dev_urandom_fd = open("/dev/urandom", O_RDONLY); #endif base64_init(); #ifdef DEBUG_THREADS #if !defined(LOW_MEMORY) ast_cli_register_multiple(utils_cli, ARRAY_LEN(utils_cli)); #endif #endif return 0; }
char* ast_utils_which | ( | const char * | binary, |
char * | fullpath, | ||
size_t | fullpath_size | ||
) |
Resolve a binary to a full pathname.
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 1832 of file utils.c.
References ast_strdupa, and strsep().
{ 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 1053 of file utils.c.
References ast_poll.
Referenced by _sip_tcp_helper_thread(), action_waitevent(), ast_tcptls_server_root(), dahdi_test_timer(), get_input(), and moh_class_destructor().
{ struct pollfd pfd[1]; memset(pfd, 0, sizeof(pfd)); pfd[0].fd = fd; pfd[0].events = POLLIN|POLLPRI; return ast_poll(pfd, 1, ms); }
static int ast_wait_for_output | ( | int | fd, |
int | timeoutms | ||
) | [static] |
Definition at line 1062 of file utils.c.
References ast_debug, ast_log(), ast_poll, ast_tvdiff_ms(), ast_tvnow(), errno, and LOG_ERROR.
Referenced by ast_careful_fwrite(), and ast_carefulwrite().
{ struct pollfd pfd = { .fd = fd, .events = POLLOUT, }; int res; struct timeval start = ast_tvnow(); int elapsed = 0; /* poll() until the fd is writable without blocking */ while ((res = ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) { if (res == 0) { /* timed out. */ #ifndef STANDALONE ast_debug(1, "Timed out trying to write\n"); #endif return -1; } else if (res == -1) { /* poll() returned an error, check to see if it was fatal */ if (errno == EINTR || errno == EAGAIN) { elapsed = ast_tvdiff_ms(ast_tvnow(), start); if (elapsed >= timeoutms) { return -1; } /* This was an acceptable error, go back into poll() */ continue; } /* Fatal error, bail. */ ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno)); return -1; } elapsed = ast_tvdiff_ms(ast_tvnow(), start); if (elapsed >= timeoutms) { return -1; } } return 0; }
static void base64_init | ( | void | ) | [static] |
Definition at line 350 of file utils.c.
Referenced by ast_utils_init().
{ int x; memset(b2a, -1, sizeof(b2a)); /* Initialize base-64 Conversion table */ for (x = 0; x < 26; x++) { /* A-Z */ base64[x] = 'A' + x; b2a['A' + x] = x; /* a-z */ base64[x + 26] = 'a' + x; b2a['a' + x] = x + 26; /* 0-9 */ if (x < 10) { base64[x + 52] = '0' + x; b2a['0' + x] = x + 52; } } base64[62] = '+'; base64[63] = '/'; b2a[(int)'+'] = 62; b2a[(int)'/'] = 63; }
static void* dummy_start | ( | void * | data | ) | [static] |
Definition at line 935 of file utils.c.
References ast_free, AST_LIST_INSERT_TAIL, AST_MUTEX_KIND, ast_register_thread(), ast_threadstorage_get(), ast_unregister_thread(), thr_arg::data, lock_info, thr_arg::name, pthread_mutex_init, pthread_mutex_lock, pthread_mutex_unlock, thr_arg::start_routine, and strdup.
Referenced by ast_pthread_create_stack().
{ void *ret; struct thr_arg a = *((struct thr_arg *) data); /* make a local copy */ #ifdef DEBUG_THREADS struct thr_lock_info *lock_info; pthread_mutexattr_t mutex_attr; #endif /* note that even though data->name is a pointer to allocated memory, we are not freeing it here because ast_register_thread is going to keep a copy of the pointer and then ast_unregister_thread will free the memory */ ast_free(data); ast_register_thread(a.name); pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self()); #ifdef DEBUG_THREADS if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info)))) return NULL; lock_info->thread_id = pthread_self(); lock_info->thread_name = strdup(a.name); pthread_mutexattr_init(&mutex_attr); pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND); pthread_mutex_init(&lock_info->lock, &mutex_attr); pthread_mutexattr_destroy(&mutex_attr); pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */ AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry); pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */ #endif /* DEBUG_THREADS */ ret = a.start_routine(a.data); pthread_cleanup_pop(1); return ret; }
static 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.
Definition at line 83 of file utils.c.
References __mutex, ast_mutex_lock(), ast_mutex_unlock(), ERANGE, and gethostbyname.
Referenced by ast_gethostbyname().
{ int hsave; struct hostent *ph; ast_mutex_lock(&__mutex); /* begin critical area */ hsave = h_errno; ph = gethostbyname(name); *h_errnop = h_errno; /* copy h_errno to *h_herrnop */ if (ph == NULL) { *result = NULL; } else { char **p, **q; char *pbuf; int nbytes = 0; int naddr = 0, naliases = 0; /* determine if we have enough space in buf */ /* count how many addresses */ for (p = ph->h_addr_list; *p != 0; p++) { nbytes += ph->h_length; /* addresses */ nbytes += sizeof(*p); /* pointers */ naddr++; } nbytes += sizeof(*p); /* one more for the terminating NULL */ /* count how many aliases, and total length of strings */ for (p = ph->h_aliases; *p != 0; p++) { nbytes += (strlen(*p)+1); /* aliases */ nbytes += sizeof(*p); /* pointers */ naliases++; } nbytes += sizeof(*p); /* one more for the terminating NULL */ /* here nbytes is the number of bytes required in buffer */ /* as a terminator must be there, the minimum value is ph->h_length */ if (nbytes > buflen) { *result = NULL; ast_mutex_unlock(&__mutex); /* end critical area */ return ERANGE; /* not enough space in buf!! */ } /* There is enough space. Now we need to do a deep copy! */ /* Allocation in buffer: from [0] to [(naddr-1) * sizeof(*p)]: pointers to addresses at [naddr * sizeof(*p)]: NULL from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] : pointers to aliases at [(naddr+naliases+1) * sizeof(*p)]: NULL then naddr addresses (fixed length), and naliases aliases (asciiz). */ *ret = *ph; /* copy whole structure (not its address!) */ /* copy addresses */ q = (char **)buf; /* pointer to pointers area (type: char **) */ ret->h_addr_list = q; /* update pointer to address list */ pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */ for (p = ph->h_addr_list; *p != 0; p++) { memcpy(pbuf, *p, ph->h_length); /* copy address bytes */ *q++ = pbuf; /* the pointer is the one inside buf... */ pbuf += ph->h_length; /* advance pbuf */ } *q++ = NULL; /* address list terminator */ /* copy aliases */ ret->h_aliases = q; /* update pointer to aliases list */ for (p = ph->h_aliases; *p != 0; p++) { strcpy(pbuf, *p); /* copy alias strings */ *q++ = pbuf; /* the pointer is the one inside buf... */ pbuf += strlen(*p); /* advance pbuf */ *pbuf++ = 0; /* string terminator */ } *q++ = NULL; /* terminator */ strcpy(pbuf, ph->h_name); /* copy alias strings */ ret->h_name = pbuf; pbuf += strlen(ph->h_name); /* advance pbuf */ *pbuf++ = 0; /* string terminator */ *result = ret; /* and let *result point to structure */ } h_errno = hsave; /* restore h_errno */ ast_mutex_unlock(&__mutex); /* end critical area */ return (*result == NULL); /* return 0 on success, non-zero on error */ }
static struct timeval tvfix | ( | struct timeval | a | ) | [static, read] |
Definition at line 1352 of file utils.c.
References ast_log(), LOG_WARNING, and ONE_MILLION.
Referenced by ast_tvadd(), and ast_tvsub().
{ if (a.tv_usec >= ONE_MILLION) { ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n", (long)a.tv_sec, (long int) a.tv_usec); a.tv_sec += a.tv_usec / ONE_MILLION; a.tv_usec %= ONE_MILLION; } else if (a.tv_usec < 0) { ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n", (long)a.tv_sec, (long int) a.tv_usec); a.tv_usec = 0; } return a; }
const char __ast_string_field_empty[] = "" |
ast_mutex_t __mutex = AST_MUTEX_INIT_VALUE [static] |
Definition at line 76 of file utils.c.
Referenced by gethostbyname_r().
char base64[64] [static] |
Definition at line 66 of file utils.c.
Referenced by aji_start_sasl().
ast_mutex_t fetchadd_m = AST_MUTEX_INIT_VALUE [static] |
Definition at line 1692 of file utils.c.
Referenced by ast_atomic_fetchadd_int_slow().
ast_mutex_t randomlock = AST_MUTEX_INIT_VALUE [static] |
glibc puts a lock inside random(3), so that the results are thread-safe. BSD libc (and others) do not.
Definition at line 1400 of file utils.c.
Referenced by ast_random().