#include "asterisk.h"
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "asterisk/lock.h"
#include "asterisk/io.h"
#include "asterisk/logger.h"
#include "asterisk/md5.h"
#include "asterisk/sha1.h"
#include "asterisk/options.h"
#include "asterisk/strings.h"
#include "asterisk/time.h"
#include "asterisk/stringfields.h"
#include "asterisk/utils.h"
#include "asterisk/threadstorage.h"
Include dependency graph for utils.c:
Go to the source code of this file.
Data Structures | |
struct | thr_arg |
Defines | |
#define | AST_API_MODULE |
#define | AST_API_MODULE |
#define | AST_API_MODULE |
#define | AST_API_MODULE |
#define | AST_API_MODULE |
#define | AST_API_MODULE |
#define | ONE_MILLION 1000000 |
Functions | |
ast_string_field | __ast_string_field_alloc_space (struct ast_string_field_mgr *mgr, size_t needed, ast_string_field *fields, int num_fields) |
void | __ast_string_field_index_build (struct ast_string_field_mgr *mgr, ast_string_field *fields, int num_fields, int index, const char *format,...) |
void | __ast_string_field_index_build_va (struct ast_string_field_mgr *mgr, ast_string_field *fields, int num_fields, int index, const char *format, va_list ap1, va_list ap2) |
int | __ast_string_field_init (struct ast_string_field_mgr *mgr, size_t size, ast_string_field *fields, int num_fields) |
static int | add_string_pool (struct ast_string_field_mgr *mgr, size_t size) |
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) |
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,...) |
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_carefulwrite (int fd, char *s, int len, int timeoutms) |
Try to write string, but wait no more than ms milliseconds before timing out. | |
int | ast_dynamic_str_thread_build_va (struct ast_dynamic_str **buf, size_t max_len, struct ast_threadstorage *ts, int append, const char *fmt, va_list ap) |
Core functionality of ast_dynamic_str_thread_(set|append)_va. | |
void | ast_enable_packet_fragmentation (int sock) |
int | ast_false (const char *s) |
int | ast_get_time_t (const char *src, time_t *dst, time_t _default, int *consumed) |
get values from config variables. | |
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) |
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) |
Produce 32 char MD5 hash of value. | |
AST_MUTEX_DEFINE_STATIC (fetchadd_m) | |
AST_MUTEX_DEFINE_STATIC (randomlock) | |
glibc puts a lock inside random(3), so that the results are thread-safe. BSD libc (and others) do not. | |
AST_MUTEX_DEFINE_STATIC (test_lock2) | |
AST_MUTEX_DEFINE_STATIC (test_lock) | |
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_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) |
AST_THREADSTORAGE (inet_ntoa_buf, inet_ntoa_buf_init) | |
int | ast_true (const char *s) |
timeval | ast_tvadd (struct timeval a, struct timeval b) |
timeval | ast_tvsub (struct timeval a, struct timeval b) |
Returns the difference of two timevals a - b. | |
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 At this point, we're converting from ISO-8859-x (8-bit), not UTF8 as in the SIP protocol spec If doreserved == 1 we will convert reserved characters also. RFC 2396, section 2.4 outbuf needs to have more memory allocated than the instring to have room for the expansion. Every char that is converted is replaced by three ASCII characters. | |
int | ast_utils_init (void) |
int | ast_wait_for_input (int fd, int ms) |
static void | base64_init (void) |
static void * | dummy_start (void *data) |
int | test_for_thread_safety (void) |
static void * | test_thread_body (void *data) |
This is a regression test for recursive mutexes. test_for_thread_safety() will return 0 if recursive mutex locks are working properly, and non-zero if they are not working properly. | |
static struct timeval | tvfix (struct timeval a) |
Variables | |
const char | __ast_string_field_empty [] = "" |
static char | b2a [256] |
static char | base64 [64] |
static int | lock_count = 0 |
static int | test_errors = 0 |
static pthread_t | test_thread |
Definition in file utils.c.
#define ONE_MILLION 1000000 |
ast_string_field __ast_string_field_alloc_space | ( | struct ast_string_field_mgr * | mgr, | |
size_t | needed, | |||
ast_string_field * | fields, | |||
int | num_fields | |||
) |
Definition at line 874 of file utils.c.
References add_string_pool(), ast_string_field_pool::base, ast_string_field_mgr::pool, ast_string_field_mgr::size, ast_string_field_mgr::space, and ast_string_field_mgr::used.
00876 { 00877 char *result = NULL; 00878 00879 if (__builtin_expect(needed > mgr->space, 0)) { 00880 size_t new_size = mgr->size * 2; 00881 00882 while (new_size < needed) 00883 new_size *= 2; 00884 00885 if (add_string_pool(mgr, new_size)) 00886 return NULL; 00887 } 00888 00889 result = mgr->pool->base + mgr->used; 00890 mgr->used += needed; 00891 mgr->space -= needed; 00892 return result; 00893 }
void __ast_string_field_index_build | ( | struct ast_string_field_mgr * | mgr, | |
ast_string_field * | fields, | |||
int | num_fields, | |||
int | index, | |||
const char * | format, | |||
... | ||||
) |
Definition at line 922 of file utils.c.
References __ast_string_field_index_build_va().
00925 { 00926 va_list ap1, ap2; 00927 00928 va_start(ap1, format); 00929 va_start(ap2, format); /* va_copy does not exist on FreeBSD */ 00930 00931 __ast_string_field_index_build_va(mgr, fields, num_fields, index, format, ap1, ap2); 00932 00933 va_end(ap1); 00934 va_end(ap2); 00935 }
void __ast_string_field_index_build_va | ( | struct ast_string_field_mgr * | mgr, | |
ast_string_field * | fields, | |||
int | num_fields, | |||
int | index, | |||
const char * | format, | |||
va_list | ap1, | |||
va_list | ap2 | |||
) |
Definition at line 895 of file utils.c.
References add_string_pool(), ast_string_field_pool::base, ast_string_field_mgr::pool, ast_string_field_mgr::size, ast_string_field_mgr::space, and ast_string_field_mgr::used.
Referenced by __ast_string_field_index_build().
00898 { 00899 size_t needed; 00900 00901 needed = vsnprintf(mgr->pool->base + mgr->used, mgr->space, format, ap1) + 1; 00902 00903 va_end(ap1); 00904 00905 if (needed > mgr->space) { 00906 size_t new_size = mgr->size * 2; 00907 00908 while (new_size < needed) 00909 new_size *= 2; 00910 00911 if (add_string_pool(mgr, new_size)) 00912 return; 00913 00914 vsprintf(mgr->pool->base + mgr->used, format, ap2); 00915 } 00916 00917 fields[index] = mgr->pool->base + mgr->used; 00918 mgr->used += needed; 00919 mgr->space -= needed; 00920 }
int __ast_string_field_init | ( | struct ast_string_field_mgr * | mgr, | |
size_t | size, | |||
ast_string_field * | fields, | |||
int | num_fields | |||
) |
Definition at line 860 of file utils.c.
References add_string_pool().
00862 { 00863 int index; 00864 00865 if (add_string_pool(mgr, size)) 00866 return -1; 00867 00868 for (index = 0; index < num_fields; index++) 00869 fields[index] = __ast_string_field_empty; 00870 00871 return 0; 00872 }
static int add_string_pool | ( | struct ast_string_field_mgr * | mgr, | |
size_t | size | |||
) | [static] |
Definition at line 844 of file utils.c.
References ast_calloc, ast_string_field_mgr::pool, ast_string_field_mgr::size, ast_string_field_mgr::space, and ast_string_field_mgr::used.
Referenced by __ast_string_field_alloc_space(), __ast_string_field_index_build_va(), and __ast_string_field_init().
00845 { 00846 struct ast_string_field_pool *pool; 00847 00848 if (!(pool = ast_calloc(1, sizeof(*pool) + size))) 00849 return -1; 00850 00851 pool->prev = mgr->pool; 00852 mgr->pool = pool; 00853 mgr->size = size; 00854 mgr->space = size; 00855 mgr->used = 0; 00856 00857 return 0; 00858 }
int ast_atomic_fetchadd_int_slow | ( | volatile int * | p, | |
int | v | |||
) |
Definition at line 939 of file utils.c.
References ast_mutex_lock(), and ast_mutex_unlock().
00940 { 00941 int ret; 00942 ast_mutex_lock(&fetchadd_m); 00943 ret = *p; 00944 *p += v; 00945 ast_mutex_unlock(&fetchadd_m); 00946 return ret; 00947 }
int ast_base64decode | ( | unsigned char * | dst, | |
const char * | src, | |||
int | max | |||
) |
decode BASE64 encoded text
Definition at line 326 of file utils.c.
Referenced by __ast_check_signature(), base64_decode(), and osp_validate_token().
00327 { 00328 int cnt = 0; 00329 unsigned int byte = 0; 00330 unsigned int bits = 0; 00331 int incnt = 0; 00332 while(*src && (cnt < max)) { 00333 /* Shift in 6 bits of input */ 00334 byte <<= 6; 00335 byte |= (b2a[(int)(*src)]) & 0x3f; 00336 bits += 6; 00337 src++; 00338 incnt++; 00339 /* If we have at least 8 bits left over, take that character 00340 off the top */ 00341 if (bits >= 8) { 00342 bits -= 8; 00343 *dst = (byte >> bits) & 0xff; 00344 dst++; 00345 cnt++; 00346 } 00347 } 00348 /* Dont worry about left over bits, they're extra anyway */ 00349 return cnt; 00350 }
int ast_base64encode | ( | char * | dst, | |
const unsigned char * | src, | |||
int | srclen, | |||
int | max | |||
) |
Definition at line 404 of file utils.c.
References ast_base64encode_full().
Referenced by __ast_sign(), aji_act_hook(), base64_encode(), build_secret(), and osp_check_destination().
00405 { 00406 return ast_base64encode_full(dst, src, srclen, max, 0); 00407 }
int ast_base64encode_full | ( | char * | dst, | |
const unsigned char * | src, | |||
int | srclen, | |||
int | max, | |||
int | linebreaks | |||
) |
encode text to BASE64 coding
Definition at line 353 of file utils.c.
Referenced by ast_base64encode().
00354 { 00355 int cnt = 0; 00356 int col = 0; 00357 unsigned int byte = 0; 00358 int bits = 0; 00359 int cntin = 0; 00360 /* Reserve space for null byte at end of string */ 00361 max--; 00362 while ((cntin < srclen) && (cnt < max)) { 00363 byte <<= 8; 00364 byte |= *(src++); 00365 bits += 8; 00366 cntin++; 00367 if ((bits == 24) && (cnt + 4 <= max)) { 00368 *dst++ = base64[(byte >> 18) & 0x3f]; 00369 *dst++ = base64[(byte >> 12) & 0x3f]; 00370 *dst++ = base64[(byte >> 6) & 0x3f]; 00371 *dst++ = base64[byte & 0x3f]; 00372 cnt += 4; 00373 col += 4; 00374 bits = 0; 00375 byte = 0; 00376 } 00377 if (linebreaks && (cnt < max) && (col == 64)) { 00378 *dst++ = '\n'; 00379 cnt++; 00380 col = 0; 00381 } 00382 } 00383 if (bits && (cnt + 4 <= max)) { 00384 /* Add one last character for the remaining bits, 00385 padding the rest with 0 */ 00386 byte <<= 24 - bits; 00387 *dst++ = base64[(byte >> 18) & 0x3f]; 00388 *dst++ = base64[(byte >> 12) & 0x3f]; 00389 if (bits == 16) 00390 *dst++ = base64[(byte >> 6) & 0x3f]; 00391 else 00392 *dst++ = '='; 00393 *dst++ = '='; 00394 cnt += 4; 00395 } 00396 if (linebreaks && (cnt < max)) { 00397 *dst++ = '\n'; 00398 cnt++; 00399 } 00400 *dst = '\0'; 00401 return cnt; 00402 }
int ast_build_string | ( | char ** | buffer, | |
size_t * | space, | |||
const char * | fmt, | |||
... | ||||
) |
Definition at line 686 of file utils.c.
References ast_build_string_va().
Referenced by __queues_show(), add_codec_to_sdp(), add_noncodec_to_sdp(), add_sdp(), add_t38_sdp(), ast_cdr_serialize_variables(), ast_http_setcookie(), config_odbc(), config_pgsql(), function_realtime_read(), html_translate(), httpstatus_callback(), initreqprep(), pbx_builtin_serialize_variables(), print_uptimestr(), show_translation(), show_translation_deprecated(), transmit_notify_with_mwi(), transmit_state_notify(), and xml_translate().
00687 { 00688 va_list ap; 00689 int result; 00690 00691 va_start(ap, fmt); 00692 result = ast_build_string_va(buffer, space, fmt, ap); 00693 va_end(ap); 00694 00695 return result; 00696 }
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 667 of file utils.c.
Referenced by ast_build_string().
00668 { 00669 int result; 00670 00671 if (!buffer || !*buffer || !space || !*space) 00672 return -1; 00673 00674 result = vsnprintf(*buffer, *space, fmt, ap); 00675 00676 if (result < 0) 00677 return -1; 00678 else if (result > *space) 00679 result = *space; 00680 00681 *buffer += result; 00682 *space -= result; 00683 return 0; 00684 }
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 622 of file utils.c.
References pollfd::events, pollfd::fd, poll(), and POLLOUT.
Referenced by agi_debug_cli(), ast_cli(), astman_append(), and process_events().
00623 { 00624 /* Try to write string, but wait no more than ms milliseconds 00625 before timing out */ 00626 int res = 0; 00627 struct pollfd fds[1]; 00628 while (len) { 00629 res = write(fd, s, len); 00630 if ((res < 0) && (errno != EAGAIN)) { 00631 return -1; 00632 } 00633 if (res < 0) 00634 res = 0; 00635 len -= res; 00636 s += res; 00637 res = 0; 00638 if (len) { 00639 fds[0].fd = fd; 00640 fds[0].events = POLLOUT; 00641 /* Wait until writable again */ 00642 res = poll(fds, 1, timeoutms); 00643 if (res < 1) 00644 return -1; 00645 } 00646 } 00647 return res; 00648 }
int ast_dynamic_str_thread_build_va | ( | struct ast_dynamic_str ** | buf, | |
size_t | max_len, | |||
struct ast_threadstorage * | ts, | |||
int | append, | |||
const char * | fmt, | |||
va_list | ap | |||
) |
Core functionality of ast_dynamic_str_thread_(set|append)_va.
The arguments to this function are the same as those described for ast_dynamic_str_thread_set_va except for an addition argument, append. If append is non-zero, this will append to the current string instead of writing over it.
In the case that this function is called and the buffer was not large enough to hold the result, the partial write will be truncated, and the result AST_DYNSTR_BUILD_RETRY will be returned to indicate that the buffer size was increased, and the function should be called a second time.
A return of AST_DYNSTR_BUILD_FAILED indicates a memory allocation error.
A return value greater than or equal to zero indicates the number of characters that have been written, not including the terminating ''. In the append case, this only includes the number of characters appended.
Definition at line 975 of file utils.c.
References ast_realloc, ast_threadstorage::key, and offset.
00977 { 00978 int res; 00979 int offset = (append && (*buf)->len) ? strlen((*buf)->str) : 0; 00980 #if defined(DEBUG_THREADLOCALS) 00981 struct ast_dynamic_str *old_buf = *buf; 00982 #endif /* defined(DEBUG_THREADLOCALS) */ 00983 00984 res = vsnprintf((*buf)->str + offset, (*buf)->len - offset, fmt, ap); 00985 00986 /* Check to see if there was not enough space in the string buffer to prepare 00987 * the string. Also, if a maximum length is present, make sure the current 00988 * length is less than the maximum before increasing the size. */ 00989 if ((res + offset + 1) > (*buf)->len && (max_len ? ((*buf)->len < max_len) : 1)) { 00990 /* Set the new size of the string buffer to be the size needed 00991 * to hold the resulting string (res) plus one byte for the 00992 * terminating '\0'. If this size is greater than the max, set 00993 * the new length to be the maximum allowed. */ 00994 if (max_len) 00995 (*buf)->len = ((res + offset + 1) < max_len) ? (res + offset + 1) : max_len; 00996 else 00997 (*buf)->len = res + offset + 1; 00998 00999 if (!(*buf = ast_realloc(*buf, (*buf)->len + sizeof(*(*buf))))) 01000 return AST_DYNSTR_BUILD_FAILED; 01001 01002 if (append) 01003 (*buf)->str[offset] = '\0'; 01004 01005 if (ts) { 01006 pthread_setspecific(ts->key, *buf); 01007 #if defined(DEBUG_THREADLOCALS) 01008 __ast_threadstorage_object_replace(old_buf, *buf, (*buf)->len + sizeof(*(*buf))); 01009 #endif /* defined(DEBUG_THREADLOCALS) */ 01010 } 01011 01012 /* va_end() and va_start() must be done before calling 01013 * vsnprintf() again. */ 01014 return AST_DYNSTR_BUILD_RETRY; 01015 } 01016 01017 return res; 01018 }
void ast_enable_packet_fragmentation | ( | int | sock | ) |
Definition at line 1020 of file utils.c.
References ast_log(), and LOG_WARNING.
Referenced by ast_netsock_bindaddr().
01021 { 01022 #if defined(HAVE_IP_MTU_DISCOVER) 01023 int val = IP_PMTUDISC_DONT; 01024 01025 if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val))) 01026 ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n"); 01027 #endif /* HAVE_IP_MTU_DISCOVER */ 01028 }
int ast_false | ( | const char * | val | ) |
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".
Returns 0 if val is a NULL pointer, -1 if "false", and 0 otherwise.
Definition at line 715 of file utils.c.
References ast_strlen_zero().
Referenced by aji_create_client(), aji_load_config(), ast_rtp_reload(), ast_udptl_reload(), handle_common_options(), init_acf_query(), load_config(), load_odbc_config(), reload(), run_agi(), and strings_to_mask().
00716 { 00717 if (ast_strlen_zero(s)) 00718 return 0; 00719 00720 /* Determine if this is a false value */ 00721 if (!strcasecmp(s, "no") || 00722 !strcasecmp(s, "false") || 00723 !strcasecmp(s, "n") || 00724 !strcasecmp(s, "f") || 00725 !strcasecmp(s, "0") || 00726 !strcasecmp(s, "off")) 00727 return -1; 00728 00729 return 0; 00730 }
int ast_get_time_t | ( | const char * | src, | |
time_t * | dst, | |||
time_t | _default, | |||
int * | consumed | |||
) |
get values from config variables.
Definition at line 952 of file utils.c.
References ast_strlen_zero(), and t.
Referenced by acf_strftime(), build_peer(), cache_lookup_internal(), handle_saydatetime(), load_password(), play_message_datetime(), and sayunixtime_exec().
00953 { 00954 long t; 00955 int scanned; 00956 00957 if (dst == NULL) 00958 return -1; 00959 00960 *dst = _default; 00961 00962 if (ast_strlen_zero(src)) 00963 return -1; 00964 00965 /* only integer at the moment, but one day we could accept more formats */ 00966 if (sscanf(src, "%ld%n", &t, &scanned) == 1) { 00967 *dst = t; 00968 if (consumed) 00969 *consumed = scanned; 00970 return 0; 00971 } else 00972 return -1; 00973 }
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).
Definition at line 182 of file utils.c.
Referenced by __ast_http_load(), ast_dnsmgr_lookup(), ast_find_ourip(), ast_get_ip_or_srv(), ast_sip_ouraddrfor(), check_via(), create_addr(), dnsmgr_refresh(), festival_exec(), gtalk_load_config(), gtalk_update_stun(), iax_template_parse(), launch_netscript(), parse_register_contact(), process_sdp(), reload_config(), rpt_exec(), rtcp_do_debug_ip(), rtcp_do_debug_ip_deprecated(), rtp_do_debug_ip(), set_address_from_contact(), set_config(), set_destination(), sip_devicestate(), sip_do_debug_ip(), and udptl_do_debug_ip().
00183 { 00184 int res; 00185 int herrno; 00186 int dots=0; 00187 const char *s; 00188 struct hostent *result = NULL; 00189 /* Although it is perfectly legitimate to lookup a pure integer, for 00190 the sake of the sanity of people who like to name their peers as 00191 integers, we break with tradition and refuse to look up a 00192 pure integer */ 00193 s = host; 00194 res = 0; 00195 while(s && *s) { 00196 if (*s == '.') 00197 dots++; 00198 else if (!isdigit(*s)) 00199 break; 00200 s++; 00201 } 00202 if (!s || !*s) { 00203 /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */ 00204 if (dots != 3) 00205 return NULL; 00206 memset(hp, 0, sizeof(struct ast_hostent)); 00207 hp->hp.h_addrtype = AF_INET; 00208 hp->hp.h_addr_list = (void *) hp->buf; 00209 hp->hp.h_addr = hp->buf + sizeof(void *); 00210 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0) 00211 return &hp->hp; 00212 return NULL; 00213 00214 } 00215 #ifdef SOLARIS 00216 result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno); 00217 00218 if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0]) 00219 return NULL; 00220 #else 00221 res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno); 00222 00223 if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0]) 00224 return NULL; 00225 #endif 00226 return &hp->hp; 00227 }
const char* ast_inet_ntoa | ( | struct in_addr | ia | ) |
thread-safe replacement for inet_ntoa().
Definition at line 493 of file utils.c.
Referenced by __attempt_transmit(), __iax2_show_peers(), __sip_show_channels(), __sip_xmit(), _sip_show_peer(), _sip_show_peers(), accept_thread(), add_sdp(), add_t38_sdp(), ast_apply_ha(), ast_netsock_bindaddr(), 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_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_reply_digest(), build_rpid(), build_via(), check_access(), check_user_full(), check_via(), copy_via_headers(), create_addr_from_peer(), 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_callno(), find_command(), find_peer(), find_subchannel_and_lock(), function_iaxpeer(), function_sipchaninfo_read(), function_sippeer(), gtalk_create_candidates(), handle_command_response(), handle_error(), handle_open_receive_channel_ack_message(), handle_request(), handle_request_bye(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_refer(), handle_show_http(), handle_showmanconn(), http_server_start(), httpstatus_callback(), iax2_ack_registry(), iax2_prov_app(), iax2_show_channels(), iax2_show_peer(), iax2_show_registry(), iax2_trunk_queue(), iax_server(), iax_showframe(), initreqprep(), load_module(), mgcp_show_endpoints(), mgcpsock_read(), oh323_addrcmp_str(), oh323_call(), oh323_set_rtp_peer(), parse_register_contact(), process_message(), process_rfc3389(), process_sdp(), raw_hangup(), realtime_peer(), realtime_update_peer(), reg_source_db(), register_verify(), registry_rerequest(), reload_config(), resend_response(), retrans_pkt(), rpt_exec(), rtcp_do_debug_ip(), rtcp_do_debug_ip_deprecated(), rtp_do_debug_ip(), send_dtmf(), send_packet(), send_request(), send_response(), send_trunk(), session_do(), set_config(), set_destination(), setup_incoming_call(), sip_do_debug_ip(), sip_do_debug_peer(), sip_handle_t38_reinvite(), sip_poke_peer(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_show_channel(), sip_show_settings(), sipsock_read(), skinny_session(), skinny_show_devices(), socket_process(), timing_read(), transmit_notify_with_mwi(), udptl_do_debug_ip(), and update_registry().
00494 { 00495 char *buf; 00496 00497 if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN))) 00498 return ""; 00499 00500 return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN); 00501 }
void ast_join | ( | char * | s, | |
size_t | len, | |||
char *const | w[] | |||
) |
Definition at line 823 of file utils.c.
Referenced by __ast_cli_generator(), __ast_cli_register(), ast_builtins_init(), console_sendtext(), console_sendtext_deprecated(), find_best(), handle_agidumphtml(), handle_help(), handle_showagi(), help1(), and help_workhorse().
00824 { 00825 int x, ofs = 0; 00826 const char *src; 00827 00828 /* Join words into a string */ 00829 if (!s) 00830 return; 00831 for (x = 0; ofs < len && w[x]; x++) { 00832 if (x > 0) 00833 s[ofs++] = ' '; 00834 for (src = w[x]; *src && ofs < len; src++) 00835 s[ofs++] = *src; 00836 } 00837 if (ofs == len) 00838 ofs--; 00839 s[ofs] = '\0'; 00840 }
void ast_md5_hash | ( | char * | output, | |
char * | input | |||
) |
Produce 32 char MD5 hash of value.
Definition at line 292 of file utils.c.
References md5(), MD5Final(), MD5Init(), and MD5Update().
Referenced by auth_exec(), build_reply_digest(), check_auth(), checkmd5(), and md5().
00293 { 00294 struct MD5Context md5; 00295 unsigned char digest[16]; 00296 char *ptr; 00297 int x; 00298 00299 MD5Init(&md5); 00300 MD5Update(&md5, (unsigned char *)input, strlen(input)); 00301 MD5Final(digest, &md5); 00302 ptr = output; 00303 for (x = 0; x < 16; x++) 00304 ptr += sprintf(ptr, "%2.2x", digest[x]); 00305 }
AST_MUTEX_DEFINE_STATIC | ( | fetchadd_m | ) |
AST_MUTEX_DEFINE_STATIC | ( | randomlock | ) |
glibc puts a lock inside random(3), so that the results are thread-safe. BSD libc (and others) do not.
AST_MUTEX_DEFINE_STATIC | ( | test_lock2 | ) |
AST_MUTEX_DEFINE_STATIC | ( | test_lock | ) |
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 797 of file utils.c.
Referenced by handle_context_add_extension(), handle_context_add_extension_deprecated(), and pbx_load_config().
00798 { 00799 char *dataPut = start; 00800 int inEscape = 0; 00801 int inQuotes = 0; 00802 00803 for (; *start; start++) { 00804 if (inEscape) { 00805 *dataPut++ = *start; /* Always goes verbatim */ 00806 inEscape = 0; 00807 } else { 00808 if (*start == '\\') { 00809 inEscape = 1; /* Do not copy \ into the data */ 00810 } else if (*start == '\'') { 00811 inQuotes = 1 - inQuotes; /* Do not copy ' into the data */ 00812 } else { 00813 /* Replace , with |, unless in quotes */ 00814 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start); 00815 } 00816 } 00817 } 00818 if (start != dataPut) 00819 *dataPut = 0; 00820 return dataPut; 00821 }
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 553 of file utils.c.
References asprintf, ast_log(), ast_malloc, AST_STACKSIZE, dummy_start(), LOG_WARNING, and pthread_create.
00556 { 00557 #if !defined(LOW_MEMORY) 00558 struct thr_arg *a; 00559 #endif 00560 00561 if (!attr) { 00562 attr = alloca(sizeof(*attr)); 00563 pthread_attr_init(attr); 00564 } 00565 00566 #ifdef __linux__ 00567 /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED, 00568 which is kind of useless. Change this here to 00569 PTHREAD_INHERIT_SCHED; that way the -p option to set realtime 00570 priority will propagate down to new threads by default. 00571 This does mean that callers cannot set a different priority using 00572 PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set 00573 the priority afterwards with pthread_setschedparam(). */ 00574 if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED))) 00575 ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno)); 00576 #endif 00577 00578 if (!stacksize) 00579 stacksize = AST_STACKSIZE; 00580 00581 if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE))) 00582 ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno)); 00583 00584 #if !defined(LOW_MEMORY) 00585 if ((a = ast_malloc(sizeof(*a)))) { 00586 a->start_routine = start_routine; 00587 a->data = data; 00588 start_routine = dummy_start; 00589 asprintf(&a->name, "%-20s started at [%5d] %s %s()", 00590 start_fn, line, file, caller); 00591 data = a; 00592 } 00593 #endif /* !LOW_MEMORY */ 00594 00595 return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */ 00596 }
long int ast_random | ( | void | ) |
Definition at line 787 of file utils.c.
References ast_mutex_lock(), and ast_mutex_unlock().
Referenced by acf_rand_exec(), agent_new(), ast_lock_path(), ast_rtp_new_init(), ast_rtp_new_with_bindaddr(), ast_udptl_new_with_bindaddr(), authenticate_request(), build_gateway(), build_iv(), build_reply_digest(), calc_metric(), calc_rxstamp(), check_auth(), generate_random_string(), get_trans_id(), gtalk_alloc(), gtalk_create_candidates(), gtalk_new(), iax2_start_transfer(), local_new(), make_email_file(), make_our_tag(), moh_files_alloc(), ogg_vorbis_rewrite(), page_exec(), process_message(), random_exec(), reg_source_db(), registry_authrequest(), reqprep(), sip_alloc(), socket_read(), start_rtp(), stun_req_id(), transmit_fake_auth_response(), transmit_invite(), transmit_register(), transmit_response_using_temp(), try_calling(), try_firmware(), and zt_new().
00788 { 00789 long int res; 00790 ast_mutex_lock(&randomlock); 00791 res = random(); 00792 ast_mutex_unlock(&randomlock); 00793 return res; 00794 }
void ast_sha1_hash | ( | char * | output, | |
char * | input | |||
) |
Produce 40 char SHA1 hash of value.
Definition at line 308 of file utils.c.
References SHA1Input(), SHA1Reset(), and SHA1Result().
Referenced by aji_act_hook(), jabber_make_auth(), and sha1().
00309 { 00310 struct SHA1Context sha; 00311 char *ptr; 00312 int x; 00313 uint8_t Message_Digest[20]; 00314 00315 SHA1Reset(&sha); 00316 00317 SHA1Input(&sha, (const unsigned char *) input, strlen(input)); 00318 00319 SHA1Result(&sha, Message_Digest); 00320 ptr = output; 00321 for (x = 0; x < 20; x++) 00322 ptr += sprintf(ptr, "%2.2x", Message_Digest[x]); 00323 }
char* ast_strip_quoted | ( | char * | s, | |
const char * | beg_quotes, | |||
const char * | end_quotes | |||
) |
Definition at line 650 of file utils.c.
Referenced by acf_if(), ast_register_file_version(), iftime(), and parse_dial_string().
00651 { 00652 char *e; 00653 char *q; 00654 00655 s = ast_strip(s); 00656 if ((q = strchr(beg_quotes, *s)) && *q != '\0') { 00657 e = s + strlen(s) - 1; 00658 if (*e == *(end_quotes + (q - beg_quotes))) { 00659 s++; 00660 *e = '\0'; 00661 } 00662 } 00663 00664 return s; 00665 }
AST_THREADSTORAGE | ( | inet_ntoa_buf | , | |
inet_ntoa_buf_init | ||||
) |
int ast_true | ( | const char * | val | ) |
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".
Returns 0 if val is a NULL pointer, -1 if "true", and 0 otherwise.
Definition at line 698 of file utils.c.
References ast_strlen_zero().
Referenced by __ast_http_load(), __login_exec(), _parse(), action_agent_callback_login(), action_agent_logoff(), action_originate(), action_setcdruserfield(), action_updateconfig(), aji_create_client(), aji_load_config(), apply_option(), apply_outgoing(), ast_jb_read_conf(), authenticate(), build_device(), build_gateway(), build_peer(), build_user(), do_directory(), do_reload(), festival_exec(), function_ilink(), get_encrypt_methods(), gtalk_load_config(), handle_common_options(), handle_save_dialplan(), init_logger_chain(), init_manager(), load_config(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_rpt_vars(), loadconfigurationfile(), manager_add_queue_member(), manager_pause_queue_member(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), process_zap(), queue_set_param(), read_agent_config(), reload(), reload_config(), reload_queues(), set_config(), sla_load_config(), start_monitor_action(), strings_to_mask(), and update_common_options().
00699 { 00700 if (ast_strlen_zero(s)) 00701 return 0; 00702 00703 /* Determine if this is a true value */ 00704 if (!strcasecmp(s, "yes") || 00705 !strcasecmp(s, "true") || 00706 !strcasecmp(s, "y") || 00707 !strcasecmp(s, "t") || 00708 !strcasecmp(s, "1") || 00709 !strcasecmp(s, "on")) 00710 return -1; 00711 00712 return 0; 00713 }
struct timeval ast_tvadd | ( | struct timeval | a, | |
struct timeval | b | |||
) |
Definition at line 752 of file utils.c.
References ONE_MILLION, and tvfix().
Referenced by __get_from_jb(), agent_hangup(), agent_read(), ast_channel_bridge(), ast_channel_spy_trigger_wait(), ast_rtp_sendcng(), ast_rtp_senddigit_begin(), ast_rtp_senddigit_end(), ast_sched_runq(), ast_smoother_read(), ast_translate(), calc_timestamp(), do_cdr(), iax2_process_thread(), jb_get_and_deliver(), monmp3thread(), mp3_exec(), NBScat_exec(), sched_settime(), sched_thread(), schedule_delivery(), and sla_process_timers().
00753 { 00754 /* consistency checks to guarantee usec in 0..999999 */ 00755 a = tvfix(a); 00756 b = tvfix(b); 00757 a.tv_sec += b.tv_sec; 00758 a.tv_usec += b.tv_usec; 00759 if (a.tv_usec >= ONE_MILLION) { 00760 a.tv_sec++; 00761 a.tv_usec -= ONE_MILLION; 00762 } 00763 return a; 00764 }
struct timeval ast_tvsub | ( | struct timeval | a, | |
struct timeval | b | |||
) |
Returns the difference of two timevals a - b.
Definition at line 766 of file utils.c.
References ONE_MILLION, and tvfix().
Referenced by ast_channel_bridge(), ast_sched_dump(), ast_translate(), calc_rxstamp(), and calc_timestamp().
00767 { 00768 /* consistency checks to guarantee usec in 0..999999 */ 00769 a = tvfix(a); 00770 b = tvfix(b); 00771 a.tv_sec -= b.tv_sec; 00772 a.tv_usec -= b.tv_usec; 00773 if (a.tv_usec < 0) { 00774 a.tv_sec-- ; 00775 a.tv_usec += ONE_MILLION; 00776 } 00777 return a; 00778 }
void ast_uri_decode | ( | char * | s | ) |
Decode URI, URN, URL (overwrite string).
s | String to be decoded |
Definition at line 476 of file utils.c.
Referenced by check_user_full(), get_also_info(), get_destination(), get_refer_info(), handle_request_invite(), handle_uri(), register_verify(), and uridecode().
00477 { 00478 char *o; 00479 unsigned int tmp; 00480 00481 for (o = s; *s; s++, o++) { 00482 if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) { 00483 /* have '%', two chars and correct parsing */ 00484 *o = tmp; 00485 s += 2; /* Will be incremented once more when we break out */ 00486 } else /* all other cases, just copy */ 00487 *o = *s; 00488 } 00489 *o = '\0'; 00490 }
char* ast_uri_encode | ( | const char * | string, | |
char * | outbuf, | |||
int | buflen, | |||
int | doreserved | |||
) |
Turn text string to URI-encoded XX version At this point, we're converting from ISO-8859-x (8-bit), not UTF8 as in the SIP protocol spec If doreserved == 1 we will convert reserved characters also. RFC 2396, section 2.4 outbuf needs to have more memory allocated than the instring to have room for the expansion. Every char that is converted is replaced by three ASCII characters.
Definition at line 445 of file utils.c.
Referenced by initreqprep(), and uriencode().
00446 { 00447 char *reserved = ";/?:@&=+$, "; /* Reserved chars */ 00448 00449 const char *ptr = string; /* Start with the string */ 00450 char *out = NULL; 00451 char *buf = NULL; 00452 00453 ast_copy_string(outbuf, string, buflen); 00454 00455 /* If there's no characters to convert, just go through and don't do anything */ 00456 while (*ptr) { 00457 if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) { 00458 /* Oops, we need to start working here */ 00459 if (!buf) { 00460 buf = outbuf; 00461 out = buf + (ptr - string) ; /* Set output ptr */ 00462 } 00463 out += sprintf(out, "%%%02x", (unsigned char) *ptr); 00464 } else if (buf) { 00465 *out = *ptr; /* Continue copying the string */ 00466 out++; 00467 } 00468 ptr++; 00469 } 00470 if (buf) 00471 *out = '\0'; 00472 return outbuf; 00473 }
int ast_utils_init | ( | void | ) |
Definition at line 503 of file utils.c.
References base64_init().
Referenced by main().
00504 { 00505 base64_init(); 00506 return 0; 00507 }
int ast_wait_for_input | ( | int | fd, | |
int | ms | |||
) |
Definition at line 598 of file utils.c.
References poll(), POLLIN, and POLLPRI.
Referenced by action_waitevent(), ast_moh_destroy(), and http_root().
00599 { 00600 struct pollfd pfd[1]; 00601 memset(pfd, 0, sizeof(pfd)); 00602 pfd[0].fd = fd; 00603 pfd[0].events = POLLIN|POLLPRI; 00604 return poll(pfd, 1, ms); 00605 }
static void base64_init | ( | void | ) | [static] |
Definition at line 409 of file utils.c.
Referenced by ast_utils_init().
00410 { 00411 int x; 00412 memset(b2a, -1, sizeof(b2a)); 00413 /* Initialize base-64 Conversion table */ 00414 for (x = 0; x < 26; x++) { 00415 /* A-Z */ 00416 base64[x] = 'A' + x; 00417 b2a['A' + x] = x; 00418 /* a-z */ 00419 base64[x + 26] = 'a' + x; 00420 b2a['a' + x] = x + 26; 00421 /* 0-9 */ 00422 if (x < 10) { 00423 base64[x + 52] = '0' + x; 00424 b2a['0' + x] = x + 52; 00425 } 00426 } 00427 base64[62] = '+'; 00428 base64[63] = '/'; 00429 b2a[(int)'+'] = 62; 00430 b2a[(int)'/'] = 63; 00431 }
static void* dummy_start | ( | void * | data | ) | [static] |
Definition at line 532 of file utils.c.
References ast_register_thread(), ast_unregister_thread(), thr_arg::data, free, thr_arg::name, and thr_arg::start_routine.
Referenced by ast_pthread_create_stack().
00533 { 00534 void *ret; 00535 struct thr_arg a = *((struct thr_arg *) data); /* make a local copy */ 00536 00537 /* note that even though data->name is a pointer to allocated memory, 00538 we are not freeing it here because ast_register_thread is going to 00539 keep a copy of the pointer and then ast_unregister_thread will 00540 free the memory 00541 */ 00542 free(data); 00543 ast_register_thread(a.name); 00544 pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self()); 00545 ret = a.start_routine(a.data); 00546 pthread_cleanup_pop(1); 00547 00548 return ret; 00549 }
int test_for_thread_safety | ( | void | ) |
Definition at line 263 of file utils.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, and test_thread_body().
Referenced by main().
00264 { 00265 ast_mutex_lock(&test_lock2); 00266 ast_mutex_lock(&test_lock); 00267 lock_count += 1; 00268 ast_mutex_lock(&test_lock); 00269 lock_count += 1; 00270 ast_pthread_create(&test_thread, NULL, test_thread_body, NULL); 00271 usleep(100); 00272 if (lock_count != 2) 00273 test_errors++; 00274 ast_mutex_unlock(&test_lock); 00275 lock_count -= 1; 00276 usleep(100); 00277 if (lock_count != 1) 00278 test_errors++; 00279 ast_mutex_unlock(&test_lock); 00280 lock_count -= 1; 00281 if (lock_count != 0) 00282 test_errors++; 00283 ast_mutex_unlock(&test_lock2); 00284 usleep(100); 00285 if (lock_count != 0) 00286 test_errors++; 00287 pthread_join(test_thread, NULL); 00288 return(test_errors); /* return 0 on success. */ 00289 }
static void* test_thread_body | ( | void * | data | ) | [static] |
This is a regression test for recursive mutexes. test_for_thread_safety() will return 0 if recursive mutex locks are working properly, and non-zero if they are not working properly.
Definition at line 240 of file utils.c.
References ast_mutex_lock(), and ast_mutex_unlock().
Referenced by test_for_thread_safety().
00241 { 00242 ast_mutex_lock(&test_lock); 00243 lock_count += 10; 00244 if (lock_count != 10) 00245 test_errors++; 00246 ast_mutex_lock(&test_lock); 00247 lock_count += 10; 00248 if (lock_count != 20) 00249 test_errors++; 00250 ast_mutex_lock(&test_lock2); 00251 ast_mutex_unlock(&test_lock); 00252 lock_count -= 10; 00253 if (lock_count != 10) 00254 test_errors++; 00255 ast_mutex_unlock(&test_lock); 00256 lock_count -= 10; 00257 ast_mutex_unlock(&test_lock2); 00258 if (lock_count != 0) 00259 test_errors++; 00260 return NULL; 00261 }
static struct timeval tvfix | ( | struct timeval | a | ) | [static] |
Definition at line 737 of file utils.c.
References ast_log(), LOG_WARNING, and ONE_MILLION.
Referenced by ast_tvadd(), and ast_tvsub().
00738 { 00739 if (a.tv_usec >= ONE_MILLION) { 00740 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n", 00741 a.tv_sec, (long int) a.tv_usec); 00742 a.tv_sec += a.tv_usec / ONE_MILLION; 00743 a.tv_usec %= ONE_MILLION; 00744 } else if (a.tv_usec < 0) { 00745 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n", 00746 a.tv_sec, (long int) a.tv_usec); 00747 a.tv_usec = 0; 00748 } 00749 return a; 00750 }
const char __ast_string_field_empty[] = "" |
char base64[64] [static] |
int lock_count = 0 [static] |
int test_errors = 0 [static] |
pthread_t test_thread [static] |