#include "asterisk.h"
#include <ctype.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "asterisk/network.h"
#include "asterisk/lock.h"
#include "asterisk/io.h"
#include "asterisk/md5.h"
#include "asterisk/sha1.h"
#include "asterisk/cli.h"
#include "asterisk/linkedlists.h"
#include "asterisk/strings.h"
#include "asterisk/time.h"
#include "asterisk/stringfields.h"
#include "asterisk/utils.h"
#include "asterisk/threadstorage.h"
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 | ONE_MILLION 1000000 |
Functions | |
int | __ast_str_helper (struct ast_str **buf, size_t max_len, int append, const char *fmt, va_list ap) |
Core functionality of ast_str_(set|append)_va. | |
ast_string_field | __ast_string_field_alloc_space (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, size_t needed) |
int | __ast_string_field_init (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, int needed, const char *file, int lineno, const char *func) |
void | __ast_string_field_ptr_build (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, ast_string_field *ptr, const char *format,...) |
void | __ast_string_field_ptr_build_va (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, ast_string_field *ptr, const char *format, va_list ap1, va_list ap2) |
int | __ast_string_field_ptr_grow (struct ast_string_field_mgr *mgr, size_t needed, const ast_string_field *ptr) |
static void | __init_inet_ntoa_buf (void) |
int | _ast_asprintf (char **ret, const char *file, int lineno, const char *func, const char *fmt,...) |
static int | add_string_pool (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, size_t size, const char *file, int lineno, const char *func) |
add a new block to the pool. We can only allocate from the topmost pool, so the fields in *mgr reflect the size of that only. | |
int | ast_atomic_fetchadd_int_slow (volatile int *p, int v) |
int | ast_base64decode (unsigned char *dst, const char *src, int max) |
Decode data from base64. | |
int | ast_base64encode (char *dst, const unsigned char *src, int srclen, int max) |
Encode data in base64. | |
int | ast_base64encode_full (char *dst, const unsigned char *src, int srclen, int max, int linebreaks) |
encode text to BASE64 coding | |
int | ast_build_string (char **buffer, size_t *space, const char *fmt,...) |
Build a string in a buffer, designed to be called repeatedly. | |
int | ast_build_string_va (char **buffer, size_t *space, const char *fmt, va_list ap) |
Build a string in a buffer, designed to be called repeatedly. | |
int | ast_careful_fwrite (FILE *f, int fd, const char *src, size_t len, int timeoutms) |
Write data to a file stream with a timeout. | |
int | ast_carefulwrite (int fd, char *s, int len, int timeoutms) |
Try to write string, but wait no more than ms milliseconds before timing out. | |
void | ast_enable_packet_fragmentation (int sock) |
Disable PMTU discovery on a socket. | |
int | ast_false (const char *s) |
Make sure something is false. Determine if a string containing a boolean value is "false". This function checks to see whether a string passed to it is an indication of an "false" value. It checks to see if the string is "no", "false", "n", "f", "off" or "0". | |
int | ast_get_time_t (const char *src, time_t *dst, time_t _default, int *consumed) |
get values from config variables. | |
int | ast_get_timeval (const char *src, struct timeval *dst, struct timeval _default, int *consumed) |
get values from config variables. | |
hostent * | ast_gethostbyname (const char *host, struct ast_hostent *hp) |
Thread-safe gethostbyname function to use in Asterisk. | |
const char * | ast_inet_ntoa (struct in_addr ia) |
thread-safe replacement for inet_ntoa(). | |
void | ast_join (char *s, size_t len, char *const w[]) |
void | ast_md5_hash (char *output, char *input) |
Produces MD5 hash based on input string. | |
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) |
Produces SHA1 hash based on input string. | |
char * | ast_strip_quoted (char *s, const char *beg_quotes, const char *end_quotes) |
Strip leading/trailing whitespace and quotes from a string. | |
int | ast_true (const char *s) |
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1". | |
timeval | ast_tvadd (struct timeval a, struct timeval b) |
Returns the sum of two timevals a + b. | |
timeval | ast_tvsub (struct timeval a, struct timeval b) |
Returns the difference of two timevals a - b. | |
char * | ast_unescape_c (char *src) |
Convert some C escape sequences. | |
char * | ast_unescape_semicolon (char *s) |
Strip backslash for "escaped" semicolons, the string to be stripped (will be modified). | |
void | ast_uri_decode (char *s) |
Decode URI, URN, URL (overwrite string). | |
char * | ast_uri_encode (const char *string, char *outbuf, int buflen, int doreserved) |
Turn text string to URI-encoded XX version. | |
int | ast_utils_init (void) |
int | ast_wait_for_input (int fd, int ms) |
static int | ast_wait_for_output (int fd, int timeoutms) |
static void | base64_init (void) |
static void * | dummy_start (void *data) |
static struct timeval | tvfix (struct timeval a) |
Variables | |
const char | __ast_string_field_empty [] = "" |
static char | b2a [256] |
static char | base64 [64] |
static int | dev_urandom_fd |
static ast_mutex_t | fetchadd_m = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
static struct ast_threadstorage | inet_ntoa_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_inet_ntoa_buf , .custom_init = NULL , } |
static ast_mutex_t | randomlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
glibc puts a lock inside random(3), so that the results are thread-safe. BSD libc (and others) do not. |
Definition in file utils.c.
#define ONE_MILLION 1000000 |
int __ast_str_helper | ( | struct ast_str ** | buf, | |
size_t | max_len, | |||
int | append, | |||
const char * | fmt, | |||
va_list | ap | |||
) |
Core functionality of ast_str_(set|append)_va.
core handler for dynamic strings. This is not meant to be called directly, but rather through the various wrapper macros ast_str_set(...) ast_str_append(...) ast_str_set_va(...) ast_str_append_va(...)
Definition at line 1656 of file utils.c.
References AST_DYNSTR_BUILD_FAILED, AST_DYNSTR_BUILD_RETRY, ast_str_make_space(), ast_verbose(), and buf.
01658 { 01659 int res, need; 01660 int offset = (append && (*buf)->len) ? (*buf)->used : 0; 01661 01662 if (max_len < 0) 01663 max_len = (*buf)->len; /* don't exceed the allocated space */ 01664 /* 01665 * Ask vsnprintf how much space we need. Remember that vsnprintf 01666 * does not count the final '\0' so we must add 1. 01667 */ 01668 res = vsnprintf((*buf)->str + offset, (*buf)->len - offset, fmt, ap); 01669 01670 need = res + offset + 1; 01671 /* 01672 * If there is not enough space and we are below the max length, 01673 * reallocate the buffer and return a message telling to retry. 01674 */ 01675 if (need > (*buf)->len && (max_len == 0 || (*buf)->len < max_len) ) { 01676 if (max_len && max_len < need) /* truncate as needed */ 01677 need = max_len; 01678 else if (max_len == 0) /* if unbounded, give more room for next time */ 01679 need += 16 + need/4; 01680 if (0) /* debugging */ 01681 ast_verbose("extend from %d to %d\n", (int)(*buf)->len, need); 01682 if (ast_str_make_space(buf, need)) { 01683 ast_verbose("failed to extend from %d to %d\n", (int)(*buf)->len, need); 01684 return AST_DYNSTR_BUILD_FAILED; 01685 } 01686 (*buf)->str[offset] = '\0'; /* Truncate the partial write. */ 01687 01688 /* va_end() and va_start() must be done before calling 01689 * vsnprintf() again. */ 01690 return AST_DYNSTR_BUILD_RETRY; 01691 } 01692 /* update space used, keep in mind the truncation */ 01693 (*buf)->used = (res + offset > (*buf)->len) ? (*buf)->len : res + offset; 01694 01695 return res; 01696 }
ast_string_field __ast_string_field_alloc_space | ( | struct ast_string_field_mgr * | mgr, | |
struct ast_string_field_pool ** | pool_head, | |||
size_t | needed | |||
) |
Definition at line 1459 of file utils.c.
References add_string_pool(), ast_string_field_mgr::last_alloc, ast_string_field_mgr::size, and ast_string_field_mgr::used.
01461 { 01462 char *result = NULL; 01463 size_t space = mgr->size - mgr->used; 01464 01465 if (__builtin_expect(needed > space, 0)) { 01466 size_t new_size = mgr->size * 2; 01467 01468 while (new_size < needed) 01469 new_size *= 2; 01470 01471 #if defined(__AST_DEBUG_MALLOC) 01472 if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func)) 01473 return NULL; 01474 #else 01475 if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__)) 01476 return NULL; 01477 #endif 01478 } 01479 01480 result = (*pool_head)->base + mgr->used; 01481 mgr->used += needed; 01482 mgr->last_alloc = result; 01483 return result; 01484 }
int __ast_string_field_init | ( | struct ast_string_field_mgr * | mgr, | |
struct ast_string_field_pool ** | pool_head, | |||
int | needed, | |||
const char * | file, | |||
int | lineno, | |||
const char * | func | |||
) |
Definition at line 1405 of file utils.c.
References add_string_pool(), ast_free, ast_log(), ast_string_field_mgr::last_alloc, LOG_WARNING, ast_string_field_pool::prev, and ast_string_field_mgr::used.
01407 { 01408 const char **p = (const char **) pool_head + 1; 01409 struct ast_string_field_pool *cur = NULL; 01410 struct ast_string_field_pool *preserve = NULL; 01411 01412 /* clear fields - this is always necessary */ 01413 while ((struct ast_string_field_mgr *) p != mgr) 01414 *p++ = __ast_string_field_empty; 01415 mgr->last_alloc = NULL; 01416 #if defined(__AST_DEBUG_MALLOC) 01417 mgr->owner_file = file; 01418 mgr->owner_func = func; 01419 mgr->owner_line = lineno; 01420 #endif 01421 if (needed > 0) { /* allocate the initial pool */ 01422 *pool_head = NULL; 01423 return add_string_pool(mgr, pool_head, needed, file, lineno, func); 01424 } 01425 if (needed < 0) { /* reset all pools */ 01426 if (*pool_head == NULL) { 01427 ast_log(LOG_WARNING, "trying to reset empty pool\n"); 01428 return -1; 01429 } 01430 cur = *pool_head; 01431 } else { /* preserve the last pool */ 01432 if (*pool_head == NULL) { 01433 ast_log(LOG_WARNING, "trying to reset empty pool\n"); 01434 return -1; 01435 } 01436 mgr->used = 0; 01437 preserve = *pool_head; 01438 cur = preserve->prev; 01439 } 01440 01441 if (preserve) { 01442 preserve->prev = NULL; 01443 } 01444 01445 while (cur) { 01446 struct ast_string_field_pool *prev = cur->prev; 01447 01448 if (cur != preserve) { 01449 ast_free(cur); 01450 } 01451 cur = prev; 01452 } 01453 01454 *pool_head = preserve; 01455 01456 return 0; 01457 }
void __ast_string_field_ptr_build | ( | struct ast_string_field_mgr * | mgr, | |
struct ast_string_field_pool ** | pool_head, | |||
ast_string_field * | ptr, | |||
const char * | format, | |||
... | ||||
) |
Definition at line 1565 of file utils.c.
References __ast_string_field_ptr_build_va().
01568 { 01569 va_list ap1, ap2; 01570 01571 va_start(ap1, format); 01572 va_start(ap2, format); /* va_copy does not exist on FreeBSD */ 01573 01574 __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2); 01575 01576 va_end(ap1); 01577 va_end(ap2); 01578 }
void __ast_string_field_ptr_build_va | ( | struct ast_string_field_mgr * | mgr, | |
struct ast_string_field_pool ** | pool_head, | |||
ast_string_field * | ptr, | |||
const char * | format, | |||
va_list | ap1, | |||
va_list | ap2 | |||
) |
Definition at line 1509 of file utils.c.
References add_string_pool(), available(), ast_string_field_mgr::last_alloc, ast_string_field_mgr::size, and ast_string_field_mgr::used.
Referenced by __ast_string_field_ptr_build().
01512 { 01513 size_t needed; 01514 size_t available; 01515 size_t space = mgr->size - mgr->used; 01516 char *target; 01517 01518 /* if the field already has space allocated, try to reuse it; 01519 otherwise, use the empty space at the end of the current 01520 pool 01521 */ 01522 if ((*ptr)[0] != '\0') { 01523 target = (char *) *ptr; 01524 available = strlen(target) + 1; 01525 } else { 01526 target = (*pool_head)->base + mgr->used; 01527 available = space; 01528 } 01529 01530 needed = vsnprintf(target, available, format, ap1) + 1; 01531 01532 va_end(ap1); 01533 01534 if (needed > available) { 01535 /* if the space needed can be satisfied by using the current 01536 pool (which could only occur if we tried to use the field's 01537 allocated space and failed), then use that space; otherwise 01538 allocate a new pool 01539 */ 01540 if (needed > space) { 01541 size_t new_size = mgr->size * 2; 01542 01543 while (new_size < needed) 01544 new_size *= 2; 01545 01546 #if defined(__AST_DEBUG_MALLOC) 01547 if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func)) 01548 return; 01549 #else 01550 if (add_string_pool(mgr, pool_head, new_size, NULL, 0, NULL)) 01551 return; 01552 #endif 01553 } 01554 01555 target = (*pool_head)->base + mgr->used; 01556 vsprintf(target, format, ap2); 01557 } 01558 01559 if (*ptr != target) { 01560 mgr->last_alloc = *ptr = target; 01561 mgr->used += needed; 01562 } 01563 }
int __ast_string_field_ptr_grow | ( | struct ast_string_field_mgr * | mgr, | |
size_t | needed, | |||
const ast_string_field * | ptr | |||
) |
Definition at line 1486 of file utils.c.
References ast_string_field_mgr::last_alloc, ast_string_field_mgr::size, and ast_string_field_mgr::used.
01488 { 01489 int grow = needed - (strlen(*ptr) + 1); 01490 size_t space = mgr->size - mgr->used; 01491 01492 if (grow <= 0) { 01493 return 0; 01494 } 01495 01496 if (*ptr != mgr->last_alloc) { 01497 return 1; 01498 } 01499 01500 if (space < grow) { 01501 return 1; 01502 } 01503 01504 mgr->used += grow; 01505 01506 return 0; 01507 }
int _ast_asprintf | ( | char ** | ret, | |
const char * | file, | |||
int | lineno, | |||
const char * | func, | |||
const char * | fmt, | |||
... | ||||
) |
Definition at line 1758 of file utils.c.
References MALLOC_FAILURE_MSG, and vasprintf.
01759 { 01760 int res; 01761 va_list ap; 01762 01763 va_start(ap, fmt); 01764 if ((res = vasprintf(ret, fmt, ap)) == -1) { 01765 MALLOC_FAILURE_MSG; 01766 } 01767 va_end(ap); 01768 01769 return res; 01770 }
static int add_string_pool | ( | struct ast_string_field_mgr * | mgr, | |
struct ast_string_field_pool ** | pool_head, | |||
size_t | size, | |||
const char * | file, | |||
int | lineno, | |||
const char * | func | |||
) | [static] |
add a new block to the pool. We can only allocate from the topmost pool, so the fields in *mgr reflect the size of that only.
Definition at line 1371 of file utils.c.
References __ast_calloc(), ast_calloc, ast_string_field_mgr::last_alloc, ast_string_field_mgr::size, and ast_string_field_mgr::used.
Referenced by __ast_string_field_alloc_space(), __ast_string_field_init(), and __ast_string_field_ptr_build_va().
01373 { 01374 struct ast_string_field_pool *pool; 01375 01376 #if defined(__AST_DEBUG_MALLOC) 01377 if (!(pool = __ast_calloc(1, sizeof(*pool) + size, file, lineno, func))) { 01378 return -1; 01379 } 01380 #else 01381 if (!(pool = ast_calloc(1, sizeof(*pool) + size))) { 01382 return -1; 01383 } 01384 #endif 01385 01386 pool->prev = *pool_head; 01387 *pool_head = pool; 01388 mgr->size = size; 01389 mgr->used = 0; 01390 mgr->last_alloc = NULL; 01391 01392 return 0; 01393 }
int ast_atomic_fetchadd_int_slow | ( | volatile int * | p, | |
int | v | |||
) |
Definition at line 1583 of file utils.c.
References ast_mutex_lock(), ast_mutex_unlock(), and fetchadd_m.
01584 { 01585 int ret; 01586 ast_mutex_lock(&fetchadd_m); 01587 ret = *p; 01588 *p += v; 01589 ast_mutex_unlock(&fetchadd_m); 01590 return ret; 01591 }
int ast_base64decode | ( | unsigned char * | dst, | |
const char * | src, | |||
int | max | |||
) |
Decode data from base64.
dst | the destination buffer | |
src | the source buffer | |
max | The maximum number of bytes to write into the destination buffer. Note that this function will not ensure that the destination buffer is NULL terminated. So, in general, this parameter should be sizeof(dst) - 1. |
Definition at line 261 of file utils.c.
Referenced by __ast_check_signature(), base64_decode(), and osp_validate_token().
00262 { 00263 int cnt = 0; 00264 unsigned int byte = 0; 00265 unsigned int bits = 0; 00266 int incnt = 0; 00267 while (*src && (cnt < max)) { 00268 /* Shift in 6 bits of input */ 00269 byte <<= 6; 00270 byte |= (b2a[(int)(*src)]) & 0x3f; 00271 bits += 6; 00272 src++; 00273 incnt++; 00274 /* If we have at least 8 bits left over, take that character 00275 off the top */ 00276 if (bits >= 8) { 00277 bits -= 8; 00278 *dst = (byte >> bits) & 0xff; 00279 dst++; 00280 cnt++; 00281 } 00282 } 00283 /* Dont worry about left over bits, they're extra anyway */ 00284 return cnt; 00285 }
int ast_base64encode | ( | char * | dst, | |
const unsigned char * | src, | |||
int | srclen, | |||
int | max | |||
) |
Encode data in base64.
dst | the destination buffer | |
src | the source data to be encoded | |
srclen | the number of bytes present in the source buffer | |
max | the maximum number of bytes to write into the destination buffer, *including* the terminating NULL character. |
Definition at line 339 of file utils.c.
References ast_base64encode_full().
Referenced by __ast_sign(), aji_start_sasl(), base64_encode(), build_secret(), and osp_check_destination().
00340 { 00341 return ast_base64encode_full(dst, src, srclen, max, 0); 00342 }
int ast_base64encode_full | ( | char * | dst, | |
const unsigned char * | src, | |||
int | srclen, | |||
int | max, | |||
int | linebreaks | |||
) |
encode text to BASE64 coding
Definition at line 288 of file utils.c.
Referenced by ast_base64encode().
00289 { 00290 int cnt = 0; 00291 int col = 0; 00292 unsigned int byte = 0; 00293 int bits = 0; 00294 int cntin = 0; 00295 /* Reserve space for null byte at end of string */ 00296 max--; 00297 while ((cntin < srclen) && (cnt < max)) { 00298 byte <<= 8; 00299 byte |= *(src++); 00300 bits += 8; 00301 cntin++; 00302 if ((bits == 24) && (cnt + 4 <= max)) { 00303 *dst++ = base64[(byte >> 18) & 0x3f]; 00304 *dst++ = base64[(byte >> 12) & 0x3f]; 00305 *dst++ = base64[(byte >> 6) & 0x3f]; 00306 *dst++ = base64[byte & 0x3f]; 00307 cnt += 4; 00308 col += 4; 00309 bits = 0; 00310 byte = 0; 00311 } 00312 if (linebreaks && (cnt < max) && (col == 64)) { 00313 *dst++ = '\n'; 00314 cnt++; 00315 col = 0; 00316 } 00317 } 00318 if (bits && (cnt + 4 <= max)) { 00319 /* Add one last character for the remaining bits, 00320 padding the rest with 0 */ 00321 byte <<= 24 - bits; 00322 *dst++ = base64[(byte >> 18) & 0x3f]; 00323 *dst++ = base64[(byte >> 12) & 0x3f]; 00324 if (bits == 16) 00325 *dst++ = base64[(byte >> 6) & 0x3f]; 00326 else 00327 *dst++ = '='; 00328 *dst++ = '='; 00329 cnt += 4; 00330 } 00331 if (linebreaks && (cnt < max)) { 00332 *dst++ = '\n'; 00333 cnt++; 00334 } 00335 *dst = '\0'; 00336 return cnt; 00337 }
int ast_build_string | ( | char ** | buffer, | |
size_t * | space, | |||
const char * | fmt, | |||
... | ||||
) |
Build a string in a buffer, designed to be called repeatedly.
0 | on success | |
non-zero | on failure. |
Definition at line 1190 of file utils.c.
References ast_build_string_va().
Referenced by config_odbc(), config_pgsql(), handle_speechrecognize(), lua_func_read(), lua_pbx_exec(), and pp_each_user_exec().
01191 { 01192 va_list ap; 01193 int result; 01194 01195 va_start(ap, fmt); 01196 result = ast_build_string_va(buffer, space, fmt, ap); 01197 va_end(ap); 01198 01199 return result; 01200 }
int ast_build_string_va | ( | char ** | buffer, | |
size_t * | space, | |||
const char * | fmt, | |||
va_list | ap | |||
) |
Build a string in a buffer, designed to be called repeatedly.
This is a wrapper for snprintf, that properly handles the buffer pointer and buffer space available.
buffer | current position in buffer to place string into (will be updated on return) | |
space | remaining space in buffer (will be updated on return) | |
fmt | printf-style format string | |
ap | varargs list of arguments for format |
Definition at line 1171 of file utils.c.
Referenced by ast_build_string().
01172 { 01173 int result; 01174 01175 if (!buffer || !*buffer || !space || !*space) 01176 return -1; 01177 01178 result = vsnprintf(*buffer, *space, fmt, ap); 01179 01180 if (result < 0) 01181 return -1; 01182 else if (result > *space) 01183 result = *space; 01184 01185 *buffer += result; 01186 *space -= result; 01187 return 0; 01188 }
int ast_careful_fwrite | ( | FILE * | f, | |
int | fd, | |||
const char * | s, | |||
size_t | len, | |||
int | timeoutms | |||
) |
Write data to a file stream with a timeout.
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 1045 of file utils.c.
References ast_log(), ast_tvdiff_ms(), ast_tvnow(), ast_wait_for_output(), errno, and LOG_ERROR.
Referenced by send_string().
01046 { 01047 struct timeval start = ast_tvnow(); 01048 int n = 0; 01049 int elapsed = 0; 01050 01051 while (len) { 01052 if (ast_wait_for_output(fd, timeoutms - elapsed)) { 01053 /* poll returned a fatal error, so bail out immediately. */ 01054 return -1; 01055 } 01056 01057 /* Clear any errors from a previous write */ 01058 clearerr(f); 01059 01060 n = fwrite(src, 1, len, f); 01061 01062 if (ferror(f) && errno != EINTR && errno != EAGAIN) { 01063 /* fatal error from fwrite() */ 01064 if (!feof(f)) { 01065 /* Don't spam the logs if it was just that the connection is closed. */ 01066 ast_log(LOG_ERROR, "fwrite() returned error: %s\n", strerror(errno)); 01067 } 01068 n = -1; 01069 break; 01070 } 01071 01072 /* Update for data already written to the socket */ 01073 len -= n; 01074 src += n; 01075 01076 elapsed = ast_tvdiff_ms(ast_tvnow(), start); 01077 if (elapsed >= timeoutms) { 01078 /* We've taken too long to write 01079 * This is only an error condition if we haven't finished writing. */ 01080 n = len ? -1 : 0; 01081 break; 01082 } 01083 } 01084 01085 while (fflush(f)) { 01086 if (errno == EAGAIN || errno == EINTR) { 01087 continue; 01088 } 01089 if (!feof(f)) { 01090 /* Don't spam the logs if it was just that the connection is closed. */ 01091 ast_log(LOG_ERROR, "fflush() returned error: %s\n", strerror(errno)); 01092 } 01093 n = -1; 01094 break; 01095 } 01096 01097 return n < 0 ? -1 : 0; 01098 }
int ast_carefulwrite | ( | int | fd, | |
char * | s, | |||
int | len, | |||
int | timeoutms | |||
) |
Try to write string, but wait no more than ms milliseconds before timing out.
Try to write string, but wait no more than ms milliseconds before timing out.
Definition at line 1004 of file utils.c.
References ast_log(), ast_tvdiff_ms(), ast_tvnow(), ast_wait_for_output(), errno, and LOG_ERROR.
Referenced by ast_agi_send(), and ast_cli().
01005 { 01006 struct timeval start = ast_tvnow(); 01007 int res = 0; 01008 int elapsed = 0; 01009 01010 while (len) { 01011 if (ast_wait_for_output(fd, timeoutms - elapsed)) { 01012 return -1; 01013 } 01014 01015 res = write(fd, s, len); 01016 01017 if (res < 0 && errno != EAGAIN && errno != EINTR) { 01018 /* fatal error from write() */ 01019 ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno)); 01020 return -1; 01021 } 01022 01023 if (res < 0) { 01024 /* It was an acceptable error */ 01025 res = 0; 01026 } 01027 01028 /* Update how much data we have left to write */ 01029 len -= res; 01030 s += res; 01031 res = 0; 01032 01033 elapsed = ast_tvdiff_ms(ast_tvnow(), start); 01034 if (elapsed >= timeoutms) { 01035 /* We've taken too long to write 01036 * This is only an error condition if we haven't finished writing. */ 01037 res = len ? -1 : 0; 01038 break; 01039 } 01040 } 01041 01042 return res; 01043 }
void ast_enable_packet_fragmentation | ( | int | sock | ) |
Disable PMTU discovery on a socket.
sock | The socket to manipulate |
Because of this, UDP packets sent by Asterisk that are larger than the MTU of any hop in the path will be lost. This function can be called on a socket to ensure that the DF bit will not be set.
Definition at line 1698 of file utils.c.
References ast_log(), and LOG_WARNING.
Referenced by ast_netsock_bindaddr().
01699 { 01700 #if defined(HAVE_IP_MTU_DISCOVER) 01701 int val = IP_PMTUDISC_DONT; 01702 01703 if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val))) 01704 ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n"); 01705 #endif /* HAVE_IP_MTU_DISCOVER */ 01706 }
int ast_false | ( | const char * | val | ) |
Make sure something is false. Determine if a string containing a boolean value is "false". This function checks to see whether a string passed to it is an indication of an "false" value. It checks to see if the string is "no", "false", "n", "f", "off" or "0".
0 | if val is a NULL pointer. | |
-1 | if "true". | |
0 | otherwise. |
Definition at line 1219 of file utils.c.
References ast_strlen_zero().
Referenced by __ast_rtp_reload(), __ast_udptl_reload(), aji_create_client(), aji_load_config(), dahdi_set_dnd(), func_channel_write(), handle_common_options(), init_acf_query(), load_config(), load_odbc_config(), reload(), run_agi(), set_insecure_flags(), and strings_to_mask().
01220 { 01221 if (ast_strlen_zero(s)) 01222 return 0; 01223 01224 /* Determine if this is a false value */ 01225 if (!strcasecmp(s, "no") || 01226 !strcasecmp(s, "false") || 01227 !strcasecmp(s, "n") || 01228 !strcasecmp(s, "f") || 01229 !strcasecmp(s, "0") || 01230 !strcasecmp(s, "off")) 01231 return -1; 01232 01233 return 0; 01234 }
int ast_get_time_t | ( | const char * | src, | |
time_t * | dst, | |||
time_t | _default, | |||
int * | consumed | |||
) |
get values from config variables.
Definition at line 1623 of file utils.c.
References ast_strlen_zero().
Referenced by build_peer(), cache_lookup_internal(), handle_saydatetime(), load_password(), play_message_datetime(), process_clearcache(), and sayunixtime_exec().
01624 { 01625 long t; 01626 int scanned; 01627 01628 if (dst == NULL) 01629 return -1; 01630 01631 *dst = _default; 01632 01633 if (ast_strlen_zero(src)) 01634 return -1; 01635 01636 /* only integer at the moment, but one day we could accept more formats */ 01637 if (sscanf(src, "%ld%n", &t, &scanned) == 1) { 01638 *dst = t; 01639 if (consumed) 01640 *consumed = scanned; 01641 return 0; 01642 } else 01643 return -1; 01644 }
int ast_get_timeval | ( | const char * | src, | |
struct timeval * | dst, | |||
struct timeval | _default, | |||
int * | consumed | |||
) |
get values from config variables.
Definition at line 1596 of file utils.c.
References ast_strlen_zero().
Referenced by acf_strftime().
01597 { 01598 long double dtv = 0.0; 01599 int scanned; 01600 01601 if (dst == NULL) 01602 return -1; 01603 01604 *dst = _default; 01605 01606 if (ast_strlen_zero(src)) 01607 return -1; 01608 01609 /* only integer at the moment, but one day we could accept more formats */ 01610 if (sscanf(src, "%Lf%n", &dtv, &scanned) > 0) { 01611 dst->tv_sec = dtv; 01612 dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0; 01613 if (consumed) 01614 *consumed = scanned; 01615 return 0; 01616 } else 01617 return -1; 01618 }
struct hostent* ast_gethostbyname | ( | const char * | host, | |
struct ast_hostent * | hp | |||
) |
Thread-safe gethostbyname function to use in Asterisk.
Definition at line 179 of file utils.c.
Referenced by __ast_http_load(), __init_manager(), __set_address_from_contact(), ast_dnsmgr_lookup(), ast_find_ourip(), ast_get_ip_or_srv(), ast_parse_arg(), check_via(), create_addr(), dnsmgr_refresh(), festival_exec(), get_ip_and_port_from_sdp(), gtalk_load_config(), gtalk_update_stun(), handle_cli_udptl_debug_deprecated(), handle_cli_udptl_set_debug(), iax_template_parse(), jingle_load_config(), jingle_update_stun(), launch_netscript(), parse_register_contact(), process_sdp(), realtime_peer(), realtime_user(), reload_config(), rtcp_do_debug_ip(), rtp_do_debug_ip(), set_config(), set_destination(), and sip_do_debug_ip().
00180 { 00181 int res; 00182 int herrno; 00183 int dots = 0; 00184 const char *s; 00185 struct hostent *result = NULL; 00186 /* Although it is perfectly legitimate to lookup a pure integer, for 00187 the sake of the sanity of people who like to name their peers as 00188 integers, we break with tradition and refuse to look up a 00189 pure integer */ 00190 s = host; 00191 res = 0; 00192 while (s && *s) { 00193 if (*s == '.') 00194 dots++; 00195 else if (!isdigit(*s)) 00196 break; 00197 s++; 00198 } 00199 if (!s || !*s) { 00200 /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */ 00201 if (dots != 3) 00202 return NULL; 00203 memset(hp, 0, sizeof(struct ast_hostent)); 00204 hp->hp.h_addrtype = AF_INET; 00205 hp->hp.h_addr_list = (void *) hp->buf; 00206 hp->hp.h_addr = hp->buf + sizeof(void *); 00207 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0) 00208 return &hp->hp; 00209 return NULL; 00210 00211 } 00212 #ifdef HAVE_GETHOSTBYNAME_R_5 00213 result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno); 00214 00215 if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0]) 00216 return NULL; 00217 #else 00218 res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno); 00219 00220 if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0]) 00221 return NULL; 00222 #endif 00223 return &hp->hp; 00224 }
const char* ast_inet_ntoa | ( | struct in_addr | ia | ) |
thread-safe replacement for inet_ntoa().
Definition at line 428 of file utils.c.
References ast_threadstorage_get(), and inet_ntoa_buf.
Referenced by __attempt_transmit(), __find_callno(), __iax2_show_peers(), __sip_xmit(), _sip_show_peer(), _sip_show_peers(), acf_channel_read(), action_login(), add_sdp(), ast_append_ha(), ast_apply_ha(), ast_netsock_bindaddr(), ast_parse_arg(), ast_rtcp_read(), ast_rtcp_write_rr(), ast_rtcp_write_sr(), ast_rtp_raw_write(), ast_rtp_read(), ast_rtp_sendcng(), ast_rtp_senddigit_begin(), ast_rtp_senddigit_continuation(), ast_rtp_senddigit_end(), ast_sip_ouraddrfor(), ast_tcptls_client_start(), ast_tcptls_server_start(), ast_udptl_bridge(), ast_udptl_read(), ast_udptl_write(), authenticate(), bridge_native_loop(), bridge_p2p_rtp_write(), build_callid_pvt(), build_callid_registry(), build_contact(), build_peer(), build_reply_digest(), build_rpid(), build_via(), check_access(), check_peer_ok(), check_via(), copy_via_headers(), create_addr_from_peer(), create_client(), dnsmgr_refresh(), dump_addr(), dump_ipaddr(), dundi_rexmit(), dundi_show_peer(), dundi_show_peers(), dundi_show_trans(), dundi_showframe(), dundi_xmit(), external_rtp_create(), find_command(), find_peer(), find_subchannel_and_lock(), find_tpeer(), function_iaxpeer(), function_sipchaninfo_read(), function_sippeer(), get_input(), gtalk_create_candidates(), gtalk_update_stun(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_peer(), handle_cli_iax2_show_registry(), handle_cli_udptl_debug_deprecated(), handle_cli_udptl_set_debug(), handle_command_response(), handle_error(), handle_incoming(), handle_mgcp_show_endpoints(), handle_open_receive_channel_ack_message(), handle_request(), handle_request_bye(), handle_request_do(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_refer(), handle_show_http(), handle_showmanconn(), handle_skinny_show_device(), handle_skinny_show_devices(), handle_skinny_show_settings(), httpstatus_callback(), iax2_ack_registry(), iax2_prov_app(), iax2_trunk_queue(), iax_server(), iax_showframe(), initreqprep(), jingle_create_candidates(), load_module(), manager_iax2_show_peer_list(), mgcpsock_read(), oh323_addrcmp_str(), oh323_call(), oh323_set_rtp_peer(), parse_register_contact(), parsing(), 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(), rtcp_do_debug_ip(), rtp_do_debug_ip(), score_address(), send_dtmf(), send_packet(), send_raw_client(), send_request(), send_response(), send_trunk(), session_do(), set_config(), set_destination(), setup_incoming_call(), show_channels_cb(), show_main_page(), sip_do_debug_ip(), sip_do_debug_peer(), sip_poke_peer(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_show_channel(), sip_show_settings(), sip_show_tcp(), skinny_session(), skinny_set_rtp_peer(), socket_process(), socket_process_meta(), start_rtp(), timing_read(), transmit_notify_with_mwi(), unistim_info(), unistimsock_read(), and update_registry().
00429 { 00430 char *buf; 00431 00432 if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN))) 00433 return ""; 00434 00435 return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN); 00436 }
void ast_join | ( | char * | s, | |
size_t | len, | |||
char *const | w[] | |||
) |
Definition at line 1342 of file utils.c.
Referenced by __ast_cli_generator(), ast_agi_register(), ast_agi_unregister(), cli_console_sendtext(), console_sendtext(), find_best(), handle_cli_agi_show(), handle_help(), help1(), help_workhorse(), set_full_cmd(), and write_htmldump().
01343 { 01344 int x, ofs = 0; 01345 const char *src; 01346 01347 /* Join words into a string */ 01348 if (!s) 01349 return; 01350 for (x = 0; ofs < len && w[x]; x++) { 01351 if (x > 0) 01352 s[ofs++] = ' '; 01353 for (src = w[x]; *src && ofs < len; src++) 01354 s[ofs++] = *src; 01355 } 01356 if (ofs == len) 01357 ofs--; 01358 s[ofs] = '\0'; 01359 }
void ast_md5_hash | ( | char * | output, | |
char * | input | |||
) |
Produces MD5 hash based on input string.
Definition at line 227 of file utils.c.
References md5(), MD5Final(), MD5Init(), and MD5Update().
Referenced by build_reply_digest(), check_auth(), and md5().
00228 { 00229 struct MD5Context md5; 00230 unsigned char digest[16]; 00231 char *ptr; 00232 int x; 00233 00234 MD5Init(&md5); 00235 MD5Update(&md5, (unsigned char *)input, strlen(input)); 00236 MD5Final(digest, &md5); 00237 ptr = output; 00238 for (x = 0; x < 16; x++) 00239 ptr += sprintf(ptr, "%2.2x", digest[x]); 00240 }
int ast_mkdir | ( | const char * | path, | |
int | mode | |||
) |
Recursively create directory path.
path | The directory path to create | |
mode | The permissions with which to try to create the directory |
Definition at line 1708 of file utils.c.
References ast_strdupa, errno, and len().
Referenced by ast_monitor_change_fname(), ast_monitor_start(), conf_run(), create_dirpath(), dictate_exec(), init_logger(), load_module(), mixmonitor_exec(), reload_logger(), remove_from_queue(), setup_privacy_args(), sms_nextoutgoing(), sms_writefile(), testclient_exec(), testserver_exec(), and write_history().
01709 { 01710 char *ptr; 01711 int len = strlen(path), count = 0, x, piececount = 0; 01712 char *tmp = ast_strdupa(path); 01713 char **pieces; 01714 char *fullpath = alloca(len + 1); 01715 int res = 0; 01716 01717 for (ptr = tmp; *ptr; ptr++) { 01718 if (*ptr == '/') 01719 count++; 01720 } 01721 01722 /* Count the components to the directory path */ 01723 pieces = alloca(count * sizeof(*pieces)); 01724 for (ptr = tmp; *ptr; ptr++) { 01725 if (*ptr == '/') { 01726 *ptr = '\0'; 01727 pieces[piececount++] = ptr + 1; 01728 } 01729 } 01730 01731 *fullpath = '\0'; 01732 for (x = 0; x < piececount; x++) { 01733 /* This looks funky, but the buffer is always ideally-sized, so it's fine. */ 01734 strcat(fullpath, "/"); 01735 strcat(fullpath, pieces[x]); 01736 res = mkdir(fullpath, mode); 01737 if (res && errno != EEXIST) 01738 return errno; 01739 } 01740 return 0; 01741 }
char* ast_process_quotes_and_slashes | ( | char * | start, | |
char | find, | |||
char | replace_with | |||
) |
Process a string to find and replace characters.
start | The string to analyze | |
find | The character to find | |
replace_with | The character that will replace the one we are looking for |
Definition at line 1316 of file utils.c.
01317 { 01318 char *dataPut = start; 01319 int inEscape = 0; 01320 int inQuotes = 0; 01321 01322 for (; *start; start++) { 01323 if (inEscape) { 01324 *dataPut++ = *start; /* Always goes verbatim */ 01325 inEscape = 0; 01326 } else { 01327 if (*start == '\\') { 01328 inEscape = 1; /* Do not copy \ into the data */ 01329 } else if (*start == '\'') { 01330 inQuotes = 1 - inQuotes; /* Do not copy ' into the data */ 01331 } else { 01332 /* Replace , with |, unless in quotes */ 01333 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start); 01334 } 01335 } 01336 } 01337 if (start != dataPut) 01338 *dataPut = 0; 01339 return dataPut; 01340 }
int ast_pthread_create_detached_stack | ( | pthread_t * | thread, | |
pthread_attr_t * | attr, | |||
void *(*)(void *) | start_routine, | |||
void * | data, | |||
size_t | stacksize, | |||
const char * | file, | |||
const char * | caller, | |||
int | line, | |||
const char * | start_fn | |||
) |
Definition at line 919 of file utils.c.
References ast_log(), ast_pthread_create_stack(), errno, and LOG_WARNING.
00922 { 00923 unsigned char attr_destroy = 0; 00924 int res; 00925 00926 if (!attr) { 00927 attr = alloca(sizeof(*attr)); 00928 pthread_attr_init(attr); 00929 attr_destroy = 1; 00930 } 00931 00932 if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED))) 00933 ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno)); 00934 00935 res = ast_pthread_create_stack(thread, attr, start_routine, data, 00936 stacksize, file, caller, line, start_fn); 00937 00938 if (attr_destroy) 00939 pthread_attr_destroy(attr); 00940 00941 return res; 00942 }
int ast_pthread_create_stack | ( | pthread_t * | thread, | |
pthread_attr_t * | attr, | |||
void *(*)(void *) | start_routine, | |||
void * | data, | |||
size_t | stacksize, | |||
const char * | file, | |||
const char * | caller, | |||
int | line, | |||
const char * | start_fn | |||
) |
Definition at line 870 of file utils.c.
References asprintf, ast_log(), ast_malloc, AST_STACKSIZE, dummy_start(), errno, LOG_WARNING, and pthread_create.
Referenced by ast_pthread_create_detached_stack().
00873 { 00874 #if !defined(LOW_MEMORY) 00875 struct thr_arg *a; 00876 #endif 00877 00878 if (!attr) { 00879 attr = alloca(sizeof(*attr)); 00880 pthread_attr_init(attr); 00881 } 00882 00883 #ifdef __linux__ 00884 /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED, 00885 which is kind of useless. Change this here to 00886 PTHREAD_INHERIT_SCHED; that way the -p option to set realtime 00887 priority will propagate down to new threads by default. 00888 This does mean that callers cannot set a different priority using 00889 PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set 00890 the priority afterwards with pthread_setschedparam(). */ 00891 if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED))) 00892 ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno)); 00893 #endif 00894 00895 if (!stacksize) 00896 stacksize = AST_STACKSIZE; 00897 00898 if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE))) 00899 ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno)); 00900 00901 #if !defined(LOW_MEMORY) 00902 if ((a = ast_malloc(sizeof(*a)))) { 00903 a->start_routine = start_routine; 00904 a->data = data; 00905 start_routine = dummy_start; 00906 if (asprintf(&a->name, "%-20s started at [%5d] %s %s()", 00907 start_fn, line, file, caller) < 0) { 00908 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00909 a->name = NULL; 00910 } 00911 data = a; 00912 } 00913 #endif /* !LOW_MEMORY */ 00914 00915 return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */ 00916 }
long int ast_random | ( | void | ) |
Definition at line 1292 of file utils.c.
References ast_mutex_lock(), ast_mutex_unlock(), and randomlock.
Referenced by __find_callno(), acf_rand_exec(), action_challenge(), add_sdp(), agent_new(), agi_handle_command(), ast_lock_path_lockfile(), ast_moh_files_next(), ast_rtp_new_init(), ast_rtp_new_with_bindaddr(), ast_udptl_new_with_bindaddr(), authenticate_request(), build_gateway(), build_iv(), build_rand_pad(), build_reply_digest(), calc_metric(), calc_rxstamp(), check_auth(), dahdi_new(), generate_random_string(), get_trans_id(), gtalk_alloc(), gtalk_create_candidates(), gtalk_new(), handle_response_invite(), iax2_start_transfer(), jingle_alloc(), jingle_create_candidates(), jingle_new(), local_new(), make_email_file(), make_our_tag(), moh_files_alloc(), ogg_vorbis_rewrite(), osp_create_uuid(), page_exec(), process_weights(), reg_source_db(), registry_authrequest(), reqprep(), sendmail(), sip_alloc(), socket_read(), start_rtp(), stun_req_id(), transmit_fake_auth_response(), transmit_invite(), transmit_register(), transmit_response_using_temp(), and try_firmware().
01293 { 01294 long int res; 01295 #ifdef HAVE_DEV_URANDOM 01296 if (dev_urandom_fd >= 0) { 01297 int read_res = read(dev_urandom_fd, &res, sizeof(res)); 01298 if (read_res > 0) { 01299 long int rm = RAND_MAX; 01300 res = res < 0 ? ~res : res; 01301 rm++; 01302 return res % rm; 01303 } 01304 } 01305 #endif 01306 #ifdef linux 01307 res = random(); 01308 #else 01309 ast_mutex_lock(&randomlock); 01310 res = random(); 01311 ast_mutex_unlock(&randomlock); 01312 #endif 01313 return res; 01314 }
void ast_sha1_hash | ( | char * | output, | |
char * | input | |||
) |
Produces SHA1 hash based on input string.
Definition at line 243 of file utils.c.
References SHA1Input(), SHA1Reset(), and SHA1Result().
Referenced by aji_act_hook(), jabber_make_auth(), and sha1().
00244 { 00245 struct SHA1Context sha; 00246 char *ptr; 00247 int x; 00248 uint8_t Message_Digest[20]; 00249 00250 SHA1Reset(&sha); 00251 00252 SHA1Input(&sha, (const unsigned char *) input, strlen(input)); 00253 00254 SHA1Result(&sha, Message_Digest); 00255 ptr = output; 00256 for (x = 0; x < 20; x++) 00257 ptr += sprintf(ptr, "%2.2x", Message_Digest[x]); 00258 }
char* ast_strip_quoted | ( | char * | s, | |
const char * | beg_quotes, | |||
const char * | end_quotes | |||
) |
Strip leading/trailing whitespace and quotes from a string.
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. |
It can also remove beginning and ending quote (or quote-like) characters, in matching pairs. If the first character of the string matches any character in beg_quotes, and the last character of the string is the matching character in end_quotes, then they are removed from the string.
Examples:
ast_strip_quoted(buf, "\"", "\""); ast_strip_quoted(buf, "'", "'"); ast_strip_quoted(buf, "[{(", "]})");
Definition at line 1100 of file utils.c.
References ast_strip().
Referenced by ast_register_file_version(), get_rdnis(), iftime(), load_values_config(), parse_cookies(), and parse_dial_string().
01101 { 01102 char *e; 01103 char *q; 01104 01105 s = ast_strip(s); 01106 if ((q = strchr(beg_quotes, *s)) && *q != '\0') { 01107 e = s + strlen(s) - 1; 01108 if (*e == *(end_quotes + (q - beg_quotes))) { 01109 s++; 01110 *e = '\0'; 01111 } 01112 } 01113 01114 return s; 01115 }
int ast_true | ( | const char * | val | ) |
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
0 | if val is a NULL pointer. | |
-1 | if "true". | |
0 | otherwise. |
Definition at line 1202 of file utils.c.
References ast_strlen_zero().
Referenced by __ast_http_load(), __ast_rtp_reload(), __init_manager(), _parse(), action_agent_logoff(), action_bridge(), action_originate(), action_updateconfig(), aji_create_client(), aji_load_config(), apply_general_options(), apply_option(), apply_outgoing(), ast_jb_read_conf(), build_device(), build_gateway(), build_peer(), build_user(), dahdi_set_dnd(), do_reload(), do_timelimit(), festival_exec(), func_channel_write(), func_inheritance_write(), function_ilink(), get_encrypt_methods(), gtalk_load_config(), handle_common_options(), init_logger_chain(), jingle_load_config(), load_config(), load_config_meetme(), load_module(), load_moh_classes(), load_odbc_config(), local_ast_moh_start(), login_exec(), manager_add_queue_member(), manager_pause_queue_member(), message_template_build(), misdn_answer(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), process_dahdi(), process_echocancel(), queue_set_param(), read_agent_config(), reload(), reload_config(), reload_queues(), run_startup_commands(), search_directory(), set_active(), set_config(), sla_load_config(), start_monitor_action(), strings_to_mask(), and update_common_options().
01203 { 01204 if (ast_strlen_zero(s)) 01205 return 0; 01206 01207 /* Determine if this is a true value */ 01208 if (!strcasecmp(s, "yes") || 01209 !strcasecmp(s, "true") || 01210 !strcasecmp(s, "y") || 01211 !strcasecmp(s, "t") || 01212 !strcasecmp(s, "1") || 01213 !strcasecmp(s, "on")) 01214 return -1; 01215 01216 return 0; 01217 }
struct timeval ast_tvadd | ( | struct timeval | a, | |
struct timeval | b | |||
) |
Returns the sum of two timevals a + b.
Definition at line 1256 of file utils.c.
References ONE_MILLION, and tvfix().
Referenced by __get_from_jb(), agent_hangup(), agent_read(), ast_audiohook_trigger_wait(), ast_channel_bridge(), ast_generic_bridge(), ast_rtp_sendcng(), ast_rtp_senddigit_begin(), ast_rtp_senddigit_end(), ast_sched_runq(), ast_smoother_read(), ast_translate(), calc_timestamp(), conf_run(), do_cdr(), iax2_process_thread(), jb_get_and_deliver(), mb_poll_thread(), monmp3thread(), mp3_exec(), mwi_monitor_handler(), NBScat_exec(), sched_settime(), sched_thread(), schedule_delivery(), sla_process_timers(), and smdi_message_wait().
01257 { 01258 /* consistency checks to guarantee usec in 0..999999 */ 01259 a = tvfix(a); 01260 b = tvfix(b); 01261 a.tv_sec += b.tv_sec; 01262 a.tv_usec += b.tv_usec; 01263 if (a.tv_usec >= ONE_MILLION) { 01264 a.tv_sec++; 01265 a.tv_usec -= ONE_MILLION; 01266 } 01267 return a; 01268 }
struct timeval ast_tvsub | ( | struct timeval | a, | |
struct timeval | b | |||
) |
Returns the difference of two timevals a - b.
Definition at line 1270 of file utils.c.
References ONE_MILLION, and tvfix().
Referenced by ast_channel_bridge(), ast_rwlock_timedrdlock(), ast_rwlock_timedwrlock(), ast_sched_dump(), ast_translate(), calc_rxstamp(), calc_timestamp(), conf_run(), handle_showcalls(), handle_showuptime(), and pri_dchannel().
01271 { 01272 /* consistency checks to guarantee usec in 0..999999 */ 01273 a = tvfix(a); 01274 b = tvfix(b); 01275 a.tv_sec -= b.tv_sec; 01276 a.tv_usec -= b.tv_usec; 01277 if (a.tv_usec < 0) { 01278 a.tv_sec-- ; 01279 a.tv_usec += ONE_MILLION; 01280 } 01281 return a; 01282 }
char* ast_unescape_c | ( | char * | s | ) |
Convert some C escape sequences.
(\b\f\n\r\t)
Definition at line 1136 of file utils.c.
01137 { 01138 char c, *ret, *dst; 01139 01140 if (src == NULL) 01141 return NULL; 01142 for (ret = dst = src; (c = *src++); *dst++ = c ) { 01143 if (c != '\\') 01144 continue; /* copy char at the end of the loop */ 01145 switch ((c = *src++)) { 01146 case '\0': /* special, trailing '\' */ 01147 c = '\\'; 01148 break; 01149 case 'b': /* backspace */ 01150 c = '\b'; 01151 break; 01152 case 'f': /* form feed */ 01153 c = '\f'; 01154 break; 01155 case 'n': 01156 c = '\n'; 01157 break; 01158 case 'r': 01159 c = '\r'; 01160 break; 01161 case 't': 01162 c = '\t'; 01163 break; 01164 } 01165 /* default, use the char literally */ 01166 } 01167 *dst = '\0'; 01168 return ret; 01169 }
char* ast_unescape_semicolon | ( | char * | s | ) |
Strip backslash for "escaped" semicolons, the string to be stripped (will be modified).
Definition at line 1117 of file utils.c.
Referenced by sip_notify().
01118 { 01119 char *e; 01120 char *work = s; 01121 01122 while ((e = strchr(work, ';'))) { 01123 if ((e > work) && (*(e-1) == '\\')) { 01124 memmove(e - 1, e, strlen(e) + 1); 01125 work = e; 01126 } else { 01127 work = e + 1; 01128 } 01129 } 01130 01131 return s; 01132 }
void ast_uri_decode | ( | char * | s | ) |
Decode URI, URN, URL (overwrite string).
s | String to be decoded |
Definition at line 411 of file utils.c.
Referenced by check_user_full(), config_curl(), get_also_info(), get_destination(), get_refer_info(), handle_request_invite(), http_decode(), realtime_curl(), realtime_multi_curl(), register_verify(), sip_new(), and uridecode().
00412 { 00413 char *o; 00414 unsigned int tmp; 00415 00416 for (o = s; *s; s++, o++) { 00417 if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) { 00418 /* have '%', two chars and correct parsing */ 00419 *o = tmp; 00420 s += 2; /* Will be incremented once more when we break out */ 00421 } else /* all other cases, just copy */ 00422 *o = *s; 00423 } 00424 *o = '\0'; 00425 }
char* ast_uri_encode | ( | const char * | string, | |
char * | outbuf, | |||
int | buflen, | |||
int | doreserved | |||
) |
Turn text string to URI-encoded XX version.
Definition at line 380 of file utils.c.
References ast_copy_string().
Referenced by config_curl(), destroy_curl(), initreqprep(), launch_asyncagi(), realtime_curl(), realtime_multi_curl(), store_curl(), update_curl(), and uriencode().
00381 { 00382 char *reserved = ";/?:@&=+$,# "; /* Reserved chars */ 00383 00384 const char *ptr = string; /* Start with the string */ 00385 char *out = NULL; 00386 char *buf = NULL; 00387 00388 ast_copy_string(outbuf, string, buflen); 00389 00390 /* If there's no characters to convert, just go through and don't do anything */ 00391 while (*ptr) { 00392 if ((*ptr < 32 || (unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) { 00393 /* Oops, we need to start working here */ 00394 if (!buf) { 00395 buf = outbuf; 00396 out = buf + (ptr - string) ; /* Set output ptr */ 00397 } 00398 out += sprintf(out, "%%%02x", (unsigned char) *ptr); 00399 } else if (buf) { 00400 *out = *ptr; /* Continue copying the string */ 00401 out++; 00402 } 00403 ptr++; 00404 } 00405 if (buf) 00406 *out = '\0'; 00407 return outbuf; 00408 }
int ast_utils_init | ( | void | ) |
Definition at line 1743 of file utils.c.
References ARRAY_LEN, ast_cli_register_multiple(), and base64_init().
Referenced by main().
01744 { 01745 #ifdef HAVE_DEV_URANDOM 01746 dev_urandom_fd = open("/dev/urandom", O_RDONLY); 01747 #endif 01748 base64_init(); 01749 #ifdef DEBUG_THREADS 01750 #if !defined(LOW_MEMORY) 01751 ast_cli_register_multiple(utils_cli, ARRAY_LEN(utils_cli)); 01752 #endif 01753 #endif 01754 return 0; 01755 }
int ast_wait_for_input | ( | int | fd, | |
int | ms | |||
) |
Definition at line 944 of file utils.c.
References ast_poll.
Referenced by _sip_tcp_helper_thread(), action_waitevent(), ast_tcptls_server_root(), get_input(), main(), and moh_class_destructor().
00945 { 00946 struct pollfd pfd[1]; 00947 memset(pfd, 0, sizeof(pfd)); 00948 pfd[0].fd = fd; 00949 pfd[0].events = POLLIN|POLLPRI; 00950 return ast_poll(pfd, 1, ms); 00951 }
static int ast_wait_for_output | ( | int | fd, | |
int | timeoutms | |||
) | [static] |
Definition at line 953 of file utils.c.
References ast_log(), ast_poll, ast_tvdiff_ms(), ast_tvnow(), errno, LOG_ERROR, and LOG_NOTICE.
Referenced by ast_careful_fwrite(), and ast_carefulwrite().
00954 { 00955 struct pollfd pfd = { 00956 .fd = fd, 00957 .events = POLLOUT, 00958 }; 00959 int res; 00960 struct timeval start = ast_tvnow(); 00961 int elapsed = 0; 00962 00963 /* poll() until the fd is writable without blocking */ 00964 while ((res = ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) { 00965 if (res == 0) { 00966 /* timed out. */ 00967 ast_log(LOG_NOTICE, "Timed out trying to write\n"); 00968 return -1; 00969 } else if (res == -1) { 00970 /* poll() returned an error, check to see if it was fatal */ 00971 00972 if (errno == EINTR || errno == EAGAIN) { 00973 elapsed = ast_tvdiff_ms(ast_tvnow(), start); 00974 if (elapsed >= timeoutms) { 00975 return -1; 00976 } 00977 /* This was an acceptable error, go back into poll() */ 00978 continue; 00979 } 00980 00981 /* Fatal error, bail. */ 00982 ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno)); 00983 00984 return -1; 00985 } 00986 elapsed = ast_tvdiff_ms(ast_tvnow(), start); 00987 if (elapsed >= timeoutms) { 00988 return -1; 00989 } 00990 } 00991 00992 return 0; 00993 }
static void base64_init | ( | void | ) | [static] |
Definition at line 344 of file utils.c.
Referenced by ast_utils_init().
00345 { 00346 int x; 00347 memset(b2a, -1, sizeof(b2a)); 00348 /* Initialize base-64 Conversion table */ 00349 for (x = 0; x < 26; x++) { 00350 /* A-Z */ 00351 base64[x] = 'A' + x; 00352 b2a['A' + x] = x; 00353 /* a-z */ 00354 base64[x + 26] = 'a' + x; 00355 b2a['a' + x] = x + 26; 00356 /* 0-9 */ 00357 if (x < 10) { 00358 base64[x + 52] = '0' + x; 00359 b2a['0' + x] = x + 52; 00360 } 00361 } 00362 base64[62] = '+'; 00363 base64[63] = '/'; 00364 b2a[(int)'+'] = 62; 00365 b2a[(int)'/'] = 63; 00366 }
static void* dummy_start | ( | void * | data | ) | [static] |
Definition at line 826 of file utils.c.
References ast_free, AST_LIST_INSERT_TAIL, AST_MUTEX_KIND, ast_register_thread(), ast_threadstorage_get(), ast_unregister_thread(), thr_arg::data, 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().
00827 { 00828 void *ret; 00829 struct thr_arg a = *((struct thr_arg *) data); /* make a local copy */ 00830 #ifdef DEBUG_THREADS 00831 struct thr_lock_info *lock_info; 00832 pthread_mutexattr_t mutex_attr; 00833 #endif 00834 00835 /* note that even though data->name is a pointer to allocated memory, 00836 we are not freeing it here because ast_register_thread is going to 00837 keep a copy of the pointer and then ast_unregister_thread will 00838 free the memory 00839 */ 00840 ast_free(data); 00841 ast_register_thread(a.name); 00842 pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self()); 00843 00844 #ifdef DEBUG_THREADS 00845 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info)))) 00846 return NULL; 00847 00848 lock_info->thread_id = pthread_self(); 00849 lock_info->thread_name = strdup(a.name); 00850 00851 pthread_mutexattr_init(&mutex_attr); 00852 pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND); 00853 pthread_mutex_init(&lock_info->lock, &mutex_attr); 00854 pthread_mutexattr_destroy(&mutex_attr); 00855 00856 pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */ 00857 AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry); 00858 pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */ 00859 #endif /* DEBUG_THREADS */ 00860 00861 ret = a.start_routine(a.data); 00862 00863 pthread_cleanup_pop(1); 00864 00865 return ret; 00866 }
static struct timeval tvfix | ( | struct timeval | a | ) | [static] |
Definition at line 1241 of file utils.c.
References ast_log(), LOG_WARNING, and ONE_MILLION.
Referenced by ast_tvadd(), and ast_tvsub().
01242 { 01243 if (a.tv_usec >= ONE_MILLION) { 01244 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n", 01245 a.tv_sec, (long int) a.tv_usec); 01246 a.tv_sec += a.tv_usec / ONE_MILLION; 01247 a.tv_usec %= ONE_MILLION; 01248 } else if (a.tv_usec < 0) { 01249 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n", 01250 a.tv_sec, (long int) a.tv_usec); 01251 a.tv_usec = 0; 01252 } 01253 return a; 01254 }
const char __ast_string_field_empty[] = "" |
char base64[64] [static] |
int dev_urandom_fd [static] |
ast_mutex_t fetchadd_m = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
struct ast_threadstorage inet_ntoa_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_inet_ntoa_buf , .custom_init = NULL , } [static] |
ast_mutex_t randomlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
glibc puts a lock inside random(3), so that the results are thread-safe. BSD libc (and others) do not.
Definition at line 1289 of file utils.c.
Referenced by ast_random().