#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/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 | ERANGE 34 |
#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) |
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, 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. | |
struct hostent * | ast_gethostbyname (const char *host, struct ast_hostent *hp) |
Re-entrant (thread safe) version of gethostbyname that replaces the standard gethostbyname (which is not thread safe). | |
const char * | ast_inet_ntoa (struct in_addr ia) |
ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa | |
void | ast_join (char *s, size_t len, char *const w[]) |
void | ast_md5_hash (char *output, char *input) |
Produce 32 char MD5 hash of value. | |
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) | |
AST_MUTEX_DEFINE_STATIC (__mutex) | |
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) |
struct timeval | ast_tvadd (struct timeval a, struct timeval b) |
struct timeval | ast_tvsub (struct timeval a, struct timeval b) |
Returns the difference of two timevals a - b. | |
char * | ast_unescape_semicolon (char *s) |
Strip backslash for "escaped" semicolons. | |
void | ast_uri_decode (char *s) |
ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string) | |
char * | ast_uri_encode (const char *string, char *outbuf, int buflen, int doreserved) |
ast_uri_encode: Turn text string to URI-encoded XX version | |
int | ast_utils_init (void) |
int | ast_wait_for_input (int fd, int ms) |
static void | base64_init (void) |
static void * | dummy_start (void *data) |
static int | gethostbyname_r (const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) |
Reentrant replacement for gethostbyname for BSD-based systems. | |
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 ERANGE 34 |
duh? ERANGE value copied from web...
Definition at line 74 of file utils.c.
Referenced by gethostbyname_r(), and reload_queue_members().
#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 1226 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.
01228 { 01229 char *result = NULL; 01230 01231 if (__builtin_expect(needed > mgr->space, 0)) { 01232 size_t new_size = mgr->size * 2; 01233 01234 while (new_size < needed) 01235 new_size *= 2; 01236 01237 if (add_string_pool(mgr, new_size)) 01238 return NULL; 01239 } 01240 01241 result = mgr->pool->base + mgr->used; 01242 mgr->used += needed; 01243 mgr->space -= needed; 01244 return result; 01245 }
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 1274 of file utils.c.
References __ast_string_field_index_build_va().
01277 { 01278 va_list ap1, ap2; 01279 01280 va_start(ap1, format); 01281 va_start(ap2, format); /* va_copy does not exist on FreeBSD */ 01282 01283 __ast_string_field_index_build_va(mgr, fields, num_fields, index, format, ap1, ap2); 01284 01285 va_end(ap1); 01286 va_end(ap2); 01287 }
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 1247 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().
01250 { 01251 size_t needed; 01252 01253 needed = vsnprintf(mgr->pool->base + mgr->used, mgr->space, format, ap1) + 1; 01254 01255 va_end(ap1); 01256 01257 if (needed > mgr->space) { 01258 size_t new_size = mgr->size * 2; 01259 01260 while (new_size < needed) 01261 new_size *= 2; 01262 01263 if (add_string_pool(mgr, new_size)) 01264 return; 01265 01266 vsprintf(mgr->pool->base + mgr->used, format, ap2); 01267 } 01268 01269 fields[index] = mgr->pool->base + mgr->used; 01270 mgr->used += needed; 01271 mgr->space -= needed; 01272 }
int __ast_string_field_init | ( | struct ast_string_field_mgr * | mgr, | |
size_t | size, | |||
ast_string_field * | fields, | |||
int | num_fields | |||
) |
Definition at line 1212 of file utils.c.
References __ast_string_field_empty, and add_string_pool().
01214 { 01215 int index; 01216 01217 if (add_string_pool(mgr, size)) 01218 return -1; 01219 01220 for (index = 0; index < num_fields; index++) 01221 fields[index] = __ast_string_field_empty; 01222 01223 return 0; 01224 }
int _ast_asprintf | ( | char ** | ret, | |
const char * | file, | |||
int | lineno, | |||
const char * | func, | |||
const char * | fmt, | |||
... | ||||
) |
Definition at line 1394 of file utils.c.
References MALLOC_FAILURE_MSG, and vasprintf.
01395 { 01396 int res; 01397 va_list ap; 01398 01399 va_start(ap, fmt); 01400 if ((res = vasprintf(ret, fmt, ap)) == -1) { 01401 MALLOC_FAILURE_MSG; 01402 } 01403 va_end(ap); 01404 01405 return res; 01406 }
static int add_string_pool | ( | struct ast_string_field_mgr * | mgr, | |
size_t | size | |||
) | [static] |
Definition at line 1196 of file utils.c.
References ast_calloc, ast_string_field_mgr::pool, ast_string_field_pool::prev, 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().
01197 { 01198 struct ast_string_field_pool *pool; 01199 01200 if (!(pool = ast_calloc(1, sizeof(*pool) + size))) 01201 return -1; 01202 01203 pool->prev = mgr->pool; 01204 mgr->pool = pool; 01205 mgr->size = size; 01206 mgr->space = size; 01207 mgr->used = 0; 01208 01209 return 0; 01210 }
int ast_atomic_fetchadd_int_slow | ( | volatile int * | p, | |
int | v | |||
) |
Definition at line 1291 of file utils.c.
References ast_mutex_lock(), and ast_mutex_unlock().
01292 { 01293 int ret; 01294 ast_mutex_lock(&fetchadd_m); 01295 ret = *p; 01296 *p += v; 01297 ast_mutex_unlock(&fetchadd_m); 01298 return ret; 01299 }
int ast_base64decode | ( | unsigned char * | dst, | |
const char * | src, | |||
int | max | |||
) |
decode BASE64 encoded text
Definition at line 328 of file utils.c.
Referenced by __ast_check_signature(), base64_decode(), and osp_validate_token().
00329 { 00330 int cnt = 0; 00331 unsigned int byte = 0; 00332 unsigned int bits = 0; 00333 int incnt = 0; 00334 while(*src && (cnt < max)) { 00335 /* Shift in 6 bits of input */ 00336 byte <<= 6; 00337 byte |= (b2a[(int)(*src)]) & 0x3f; 00338 bits += 6; 00339 src++; 00340 incnt++; 00341 /* If we have at least 8 bits left over, take that character 00342 off the top */ 00343 if (bits >= 8) { 00344 bits -= 8; 00345 *dst = (byte >> bits) & 0xff; 00346 dst++; 00347 cnt++; 00348 } 00349 } 00350 /* Dont worry about left over bits, they're extra anyway */ 00351 return cnt; 00352 }
int ast_base64encode | ( | char * | dst, | |
const unsigned char * | src, | |||
int | srclen, | |||
int | max | |||
) |
Definition at line 406 of file utils.c.
References ast_base64encode_full().
Referenced by __ast_sign(), aji_act_hook(), base64_encode(), build_secret(), and osp_check_destination().
00407 { 00408 return ast_base64encode_full(dst, src, srclen, max, 0); 00409 }
int ast_base64encode_full | ( | char * | dst, | |
const unsigned char * | src, | |||
int | srclen, | |||
int | max, | |||
int | linebreaks | |||
) |
encode text to BASE64 coding
Definition at line 355 of file utils.c.
Referenced by ast_base64encode().
00356 { 00357 int cnt = 0; 00358 int col = 0; 00359 unsigned int byte = 0; 00360 int bits = 0; 00361 int cntin = 0; 00362 /* Reserve space for null byte at end of string */ 00363 max--; 00364 while ((cntin < srclen) && (cnt < max)) { 00365 byte <<= 8; 00366 byte |= *(src++); 00367 bits += 8; 00368 cntin++; 00369 if ((bits == 24) && (cnt + 4 <= max)) { 00370 *dst++ = base64[(byte >> 18) & 0x3f]; 00371 *dst++ = base64[(byte >> 12) & 0x3f]; 00372 *dst++ = base64[(byte >> 6) & 0x3f]; 00373 *dst++ = base64[byte & 0x3f]; 00374 cnt += 4; 00375 col += 4; 00376 bits = 0; 00377 byte = 0; 00378 } 00379 if (linebreaks && (cnt < max) && (col == 64)) { 00380 *dst++ = '\n'; 00381 cnt++; 00382 col = 0; 00383 } 00384 } 00385 if (bits && (cnt + 4 <= max)) { 00386 /* Add one last character for the remaining bits, 00387 padding the rest with 0 */ 00388 byte <<= 24 - bits; 00389 *dst++ = base64[(byte >> 18) & 0x3f]; 00390 *dst++ = base64[(byte >> 12) & 0x3f]; 00391 if (bits == 16) 00392 *dst++ = base64[(byte >> 6) & 0x3f]; 00393 else 00394 *dst++ = '='; 00395 *dst++ = '='; 00396 cnt += 4; 00397 } 00398 if (linebreaks && (cnt < max)) { 00399 *dst++ = '\n'; 00400 cnt++; 00401 } 00402 *dst = '\0'; 00403 return cnt; 00404 }
int ast_build_string | ( | char ** | buffer, | |
size_t * | space, | |||
const char * | fmt, | |||
... | ||||
) |
Definition at line 1038 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(), generic_http_callback(), 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().
01039 { 01040 va_list ap; 01041 int result; 01042 01043 va_start(ap, fmt); 01044 result = ast_build_string_va(buffer, space, fmt, ap); 01045 va_end(ap); 01046 01047 return result; 01048 }
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 1019 of file utils.c.
Referenced by ast_build_string().
01020 { 01021 int result; 01022 01023 if (!buffer || !*buffer || !space || !*space) 01024 return -1; 01025 01026 result = vsnprintf(*buffer, *space, fmt, ap); 01027 01028 if (result < 0) 01029 return -1; 01030 else if (result > *space) 01031 result = *space; 01032 01033 *buffer += result; 01034 *space -= result; 01035 return 0; 01036 }
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.
ast_carefulwrite
Definition at line 957 of file utils.c.
References errno, pollfd::events, pollfd::fd, poll(), and POLLOUT.
Referenced by agi_debug_cli(), ast_cli(), astman_append(), and process_events().
00958 { 00959 /* Try to write string, but wait no more than ms milliseconds 00960 before timing out */ 00961 int res = 0; 00962 struct pollfd fds[1]; 00963 while (len) { 00964 res = write(fd, s, len); 00965 if ((res < 0) && (errno != EAGAIN)) { 00966 return -1; 00967 } 00968 if (res < 0) 00969 res = 0; 00970 len -= res; 00971 s += res; 00972 res = 0; 00973 if (len) { 00974 fds[0].fd = fd; 00975 fds[0].events = POLLOUT; 00976 /* Wait until writable again */ 00977 res = poll(fds, 1, timeoutms); 00978 if (res < 1) 00979 return -1; 00980 } 00981 } 00982 return res; 00983 }
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.
Definition at line 1327 of file utils.c.
References ast_realloc, ast_threadstorage::key, and offset.
01329 { 01330 int res; 01331 int offset = (append && (*buf)->len) ? strlen((*buf)->str) : 0; 01332 #if defined(DEBUG_THREADLOCALS) 01333 struct ast_dynamic_str *old_buf = *buf; 01334 #endif /* defined(DEBUG_THREADLOCALS) */ 01335 01336 res = vsnprintf((*buf)->str + offset, (*buf)->len - offset, fmt, ap); 01337 01338 /* Check to see if there was not enough space in the string buffer to prepare 01339 * the string. Also, if a maximum length is present, make sure the current 01340 * length is less than the maximum before increasing the size. */ 01341 if ((res + offset + 1) > (*buf)->len && (max_len ? ((*buf)->len < max_len) : 1)) { 01342 /* Set the new size of the string buffer to be the size needed 01343 * to hold the resulting string (res) plus one byte for the 01344 * terminating '\0'. If this size is greater than the max, set 01345 * the new length to be the maximum allowed. */ 01346 if (max_len) 01347 (*buf)->len = ((res + offset + 1) < max_len) ? (res + offset + 1) : max_len; 01348 else 01349 (*buf)->len = res + offset + 1; 01350 01351 if (!(*buf = ast_realloc(*buf, (*buf)->len + sizeof(*(*buf))))) 01352 return AST_DYNSTR_BUILD_FAILED; 01353 01354 if (append) 01355 (*buf)->str[offset] = '\0'; 01356 01357 if (ts) { 01358 pthread_setspecific(ts->key, *buf); 01359 #if defined(DEBUG_THREADLOCALS) 01360 __ast_threadstorage_object_replace(old_buf, *buf, (*buf)->len + sizeof(*(*buf))); 01361 #endif /* defined(DEBUG_THREADLOCALS) */ 01362 } 01363 01364 /* va_end() and va_start() must be done before calling 01365 * vsnprintf() again. */ 01366 return AST_DYNSTR_BUILD_RETRY; 01367 } 01368 01369 return res; 01370 }
void ast_enable_packet_fragmentation | ( | int | sock | ) |
Definition at line 1372 of file utils.c.
References ast_log(), and LOG_WARNING.
Referenced by ast_netsock_bindaddr(), and reload_config().
01373 { 01374 #if defined(HAVE_IP_MTU_DISCOVER) 01375 int val = IP_PMTUDISC_DONT; 01376 01377 if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val))) 01378 ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n"); 01379 #endif /* HAVE_IP_MTU_DISCOVER */ 01380 }
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".
Returns 0 if val is a NULL pointer, -1 if "false", and 0 otherwise.
Definition at line 1067 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(), set_insecure_flags(), sla_build_trunk(), and strings_to_mask().
01068 { 01069 if (ast_strlen_zero(s)) 01070 return 0; 01071 01072 /* Determine if this is a false value */ 01073 if (!strcasecmp(s, "no") || 01074 !strcasecmp(s, "false") || 01075 !strcasecmp(s, "n") || 01076 !strcasecmp(s, "f") || 01077 !strcasecmp(s, "0") || 01078 !strcasecmp(s, "off")) 01079 return -1; 01080 01081 return 0; 01082 }
int ast_get_time_t | ( | const char * | src, | |
time_t * | dst, | |||
time_t | _default, | |||
int * | consumed | |||
) |
get values from config variables.
Definition at line 1304 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(), realtime_peer(), and sayunixtime_exec().
01305 { 01306 long t; 01307 int scanned; 01308 01309 if (dst == NULL) 01310 return -1; 01311 01312 *dst = _default; 01313 01314 if (ast_strlen_zero(src)) 01315 return -1; 01316 01317 /* only integer at the moment, but one day we could accept more formats */ 01318 if (sscanf(src, "%ld%n", &t, &scanned) == 1) { 01319 *dst = t; 01320 if (consumed) 01321 *consumed = scanned; 01322 return 0; 01323 } else 01324 return -1; 01325 }
struct hostent* ast_gethostbyname | ( | const char * | host, | |
struct ast_hostent * | hp | |||
) | [read] |
Re-entrant (thread safe) version of gethostbyname that replaces the standard gethostbyname (which is not thread safe).
Definition at line 184 of file utils.c.
References ast_hostent::buf, gethostbyname_r(), ast_hostent::hp, and s.
Referenced by __ast_http_load(), ast_dnsmgr_lookup(), ast_find_ourip(), ast_get_ip_or_srv(), ast_sip_ouraddrfor(), build_peer(), check_via(), create_addr(), dnsmgr_refresh(), festival_exec(), gtalk_load_config(), gtalk_update_stun(), iax_template_parse(), launch_netscript(), load_module(), parse_register_contact(), process_sdp(), realtime_peer(), realtime_user(), 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().
00185 { 00186 int res; 00187 int herrno; 00188 int dots=0; 00189 const char *s; 00190 struct hostent *result = NULL; 00191 /* Although it is perfectly legitimate to lookup a pure integer, for 00192 the sake of the sanity of people who like to name their peers as 00193 integers, we break with tradition and refuse to look up a 00194 pure integer */ 00195 s = host; 00196 res = 0; 00197 while(s && *s) { 00198 if (*s == '.') 00199 dots++; 00200 else if (!isdigit(*s)) 00201 break; 00202 s++; 00203 } 00204 if (!s || !*s) { 00205 /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */ 00206 if (dots != 3) 00207 return NULL; 00208 memset(hp, 0, sizeof(struct ast_hostent)); 00209 hp->hp.h_addrtype = AF_INET; 00210 hp->hp.h_addr_list = (void *) hp->buf; 00211 hp->hp.h_addr = hp->buf + sizeof(void *); 00212 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0) 00213 return &hp->hp; 00214 return NULL; 00215 00216 } 00217 #ifdef HAVE_GETHOSTBYNAME_R_5 00218 result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno); 00219 00220 if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0]) 00221 return NULL; 00222 #else 00223 res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno); 00224 00225 if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0]) 00226 return NULL; 00227 #endif 00228 return &hp->hp; 00229 }
const char* ast_inet_ntoa | ( | struct in_addr | ia | ) |
ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa
thread-safe replacement for inet_ntoa().
Definition at line 494 of file utils.c.
Referenced by __attempt_transmit(), __find_callno(), __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(), do_message(), dump_addr(), dump_ipaddr(), dundi_rexmit(), dundi_show_peer(), dundi_show_peers(), dundi_show_trans(), dundi_showframe(), dundi_xmit(), external_rtp_create(), find_command(), find_peer(), find_subchannel_and_lock(), find_tpeer(), function_iaxpeer(), function_sipchaninfo_read(), function_sippeer(), generic_http_callback(), get_input(), gtalk_create_candidates(), gtalk_update_stun(), handle_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(), realtime_user(), 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().
00495 { 00496 char *buf; 00497 00498 if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN))) 00499 return ""; 00500 00501 return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN); 00502 }
void ast_join | ( | char * | s, | |
size_t | len, | |||
char *const | w[] | |||
) |
Definition at line 1175 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().
01176 { 01177 int x, ofs = 0; 01178 const char *src; 01179 01180 /* Join words into a string */ 01181 if (!s) 01182 return; 01183 for (x = 0; ofs < len && w[x]; x++) { 01184 if (x > 0) 01185 s[ofs++] = ' '; 01186 for (src = w[x]; *src && ofs < len; src++) 01187 s[ofs++] = *src; 01188 } 01189 if (ofs == len) 01190 ofs--; 01191 s[ofs] = '\0'; 01192 }
void ast_md5_hash | ( | char * | output, | |
char * | input | |||
) |
Produce 32 char MD5 hash of value.
Definition at line 294 of file utils.c.
References MD5Final(), MD5Init(), and MD5Update().
Referenced by auth_exec(), build_reply_digest(), check_auth(), checkmd5(), and md5().
00295 { 00296 struct MD5Context md5; 00297 unsigned char digest[16]; 00298 char *ptr; 00299 int x; 00300 00301 MD5Init(&md5); 00302 MD5Update(&md5, (unsigned char *)input, strlen(input)); 00303 MD5Final(digest, &md5); 00304 ptr = output; 00305 for (x = 0; x < 16; x++) 00306 ptr += sprintf(ptr, "%2.2x", digest[x]); 00307 }
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 | ) |
AST_MUTEX_DEFINE_STATIC | ( | __mutex | ) |
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 1149 of file utils.c.
Referenced by handle_context_add_extension(), handle_context_add_extension_deprecated(), and pbx_load_config().
01150 { 01151 char *dataPut = start; 01152 int inEscape = 0; 01153 int inQuotes = 0; 01154 01155 for (; *start; start++) { 01156 if (inEscape) { 01157 *dataPut++ = *start; /* Always goes verbatim */ 01158 inEscape = 0; 01159 } else { 01160 if (*start == '\\') { 01161 inEscape = 1; /* Do not copy \ into the data */ 01162 } else if (*start == '\'') { 01163 inQuotes = 1 - inQuotes; /* Do not copy ' into the data */ 01164 } else { 01165 /* Replace , with |, unless in quotes */ 01166 *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start); 01167 } 01168 } 01169 } 01170 if (start != dataPut) 01171 *dataPut = 0; 01172 return dataPut; 01173 }
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 903 of file utils.c.
References asprintf, ast_log(), ast_malloc, AST_STACKSIZE, thr_arg::data, dummy_start(), errno, LOG_WARNING, thr_arg::name, pthread_create, and thr_arg::start_routine.
00906 { 00907 #if !defined(LOW_MEMORY) 00908 struct thr_arg *a; 00909 #endif 00910 00911 if (!attr) { 00912 attr = alloca(sizeof(*attr)); 00913 pthread_attr_init(attr); 00914 } 00915 00916 #ifdef __linux__ 00917 /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED, 00918 which is kind of useless. Change this here to 00919 PTHREAD_INHERIT_SCHED; that way the -p option to set realtime 00920 priority will propagate down to new threads by default. 00921 This does mean that callers cannot set a different priority using 00922 PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set 00923 the priority afterwards with pthread_setschedparam(). */ 00924 if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED))) 00925 ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno)); 00926 #endif 00927 00928 if (!stacksize) 00929 stacksize = AST_STACKSIZE; 00930 00931 if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE))) 00932 ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno)); 00933 00934 #if !defined(LOW_MEMORY) 00935 if ((a = ast_malloc(sizeof(*a)))) { 00936 a->start_routine = start_routine; 00937 a->data = data; 00938 start_routine = dummy_start; 00939 asprintf(&a->name, "%-20s started at [%5d] %s %s()", 00940 start_fn, line, file, caller); 00941 data = a; 00942 } 00943 #endif /* !LOW_MEMORY */ 00944 00945 return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */ 00946 }
long int ast_random | ( | void | ) |
Definition at line 1139 of file utils.c.
References ast_mutex_lock(), and ast_mutex_unlock().
Referenced by __find_callno(), acf_rand_exec(), agent_new(), ast_lock_path(), 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_reply_digest(), calc_metric(), calc_rxstamp(), check_auth(), generate_random_string(), get_trans_id(), gtalk_alloc(), gtalk_create_candidates(), gtalk_new(), handle_response_invite(), iax2_start_transfer(), local_new(), make_email_file(), make_our_tag(), moh_files_alloc(), ogg_vorbis_rewrite(), page_exec(), process_message(), process_weights(), 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().
01140 { 01141 long int res; 01142 ast_mutex_lock(&randomlock); 01143 res = random(); 01144 ast_mutex_unlock(&randomlock); 01145 return res; 01146 }
void ast_sha1_hash | ( | char * | output, | |
char * | input | |||
) |
Produce 40 char SHA1 hash of value.
Definition at line 310 of file utils.c.
References SHA1Input(), SHA1Reset(), and SHA1Result().
Referenced by aji_act_hook(), jabber_make_auth(), and sha1().
00311 { 00312 struct SHA1Context sha; 00313 char *ptr; 00314 int x; 00315 uint8_t Message_Digest[20]; 00316 00317 SHA1Reset(&sha); 00318 00319 SHA1Input(&sha, (const unsigned char *) input, strlen(input)); 00320 00321 SHA1Result(&sha, Message_Digest); 00322 ptr = output; 00323 for (x = 0; x < 20; x++) 00324 ptr += sprintf(ptr, "%2.2x", Message_Digest[x]); 00325 }
char* ast_strip_quoted | ( | char * | s, | |
const char * | beg_quotes, | |||
const char * | end_quotes | |||
) |
Definition at line 985 of file utils.c.
Referenced by ast_register_file_version(), iftime(), parse_cookies(), and parse_dial_string().
00986 { 00987 char *e; 00988 char *q; 00989 00990 s = ast_strip(s); 00991 if ((q = strchr(beg_quotes, *s)) && *q != '\0') { 00992 e = s + strlen(s) - 1; 00993 if (*e == *(end_quotes + (q - beg_quotes))) { 00994 s++; 00995 *e = '\0'; 00996 } 00997 } 00998 00999 return s; 01000 }
AST_THREADSTORAGE | ( | inet_ntoa_buf | , | |
inet_ntoa_buf_init | ||||
) |
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".
Returns 0 if val is a NULL pointer, -1 if "true", and 0 otherwise.
Definition at line 1050 of file utils.c.
References ast_strlen_zero().
Referenced by __ast_http_load(), __login_exec(), _parse(), action_agent_callback_login(), action_agent_logoff(), action_bridge(), action_originate(), action_setcdruserfield(), action_updateconfig(), aji_create_client(), aji_load_config(), apply_option(), apply_outgoing(), ast_jb_read_conf(), ast_readconfig(), authenticate(), build_device(), build_gateway(), build_peer(), build_user(), connect_link(), do_directory(), do_reload(), festival_exec(), 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(), set_insecure_flags(), sla_load_config(), smdi_load(), start_monitor_action(), strings_to_mask(), and update_common_options().
01051 { 01052 if (ast_strlen_zero(s)) 01053 return 0; 01054 01055 /* Determine if this is a true value */ 01056 if (!strcasecmp(s, "yes") || 01057 !strcasecmp(s, "true") || 01058 !strcasecmp(s, "y") || 01059 !strcasecmp(s, "t") || 01060 !strcasecmp(s, "1") || 01061 !strcasecmp(s, "on")) 01062 return -1; 01063 01064 return 0; 01065 }
struct timeval ast_tvadd | ( | struct timeval | a, | |
struct timeval | b | |||
) | [read] |
Definition at line 1104 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_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(), mwi_monitor_handler(), NBScat_exec(), sched_settime(), sched_thread(), schedule_delivery(), sla_process_timers(), and smdi_message_wait().
01105 { 01106 /* consistency checks to guarantee usec in 0..999999 */ 01107 a = tvfix(a); 01108 b = tvfix(b); 01109 a.tv_sec += b.tv_sec; 01110 a.tv_usec += b.tv_usec; 01111 if (a.tv_usec >= ONE_MILLION) { 01112 a.tv_sec++; 01113 a.tv_usec -= ONE_MILLION; 01114 } 01115 return a; 01116 }
struct timeval ast_tvsub | ( | struct timeval | a, | |
struct timeval | b | |||
) | [read] |
Returns the difference of two timevals a - b.
Definition at line 1118 of file utils.c.
References ONE_MILLION, and tvfix().
Referenced by ast_channel_bridge(), ast_sched_dump(), ast_translate(), calc_rxstamp(), and calc_timestamp().
01119 { 01120 /* consistency checks to guarantee usec in 0..999999 */ 01121 a = tvfix(a); 01122 b = tvfix(b); 01123 a.tv_sec -= b.tv_sec; 01124 a.tv_usec -= b.tv_usec; 01125 if (a.tv_usec < 0) { 01126 a.tv_sec-- ; 01127 a.tv_usec += ONE_MILLION; 01128 } 01129 return a; 01130 }
char* ast_unescape_semicolon | ( | char * | s | ) |
Strip backslash for "escaped" semicolons.
s The string to be stripped (will be modified).
Definition at line 1002 of file utils.c.
Referenced by sip_notify().
01003 { 01004 char *e; 01005 char *work = s; 01006 01007 while ((e = strchr(work, ';'))) { 01008 if ((e > work) && (*(e-1) == '\\')) { 01009 memmove(e - 1, e, strlen(e) + 1); 01010 work = e; 01011 } else { 01012 work = e + 1; 01013 } 01014 } 01015 01016 return s; 01017 }
void ast_uri_decode | ( | char * | s | ) |
ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string)
Decode URI, URN, URL (overwrite string).
Definition at line 477 of file utils.c.
Referenced by check_user_full(), get_also_info(), get_destination(), get_refer_info(), handle_request_invite(), handle_uri(), register_verify(), sip_new(), and uridecode().
00478 { 00479 char *o; 00480 unsigned int tmp; 00481 00482 for (o = s; *s; s++, o++) { 00483 if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) { 00484 /* have '%', two chars and correct parsing */ 00485 *o = tmp; 00486 s += 2; /* Will be incremented once more when we break out */ 00487 } else /* all other cases, just copy */ 00488 *o = *s; 00489 } 00490 *o = '\0'; 00491 }
char* ast_uri_encode | ( | const char * | string, | |
char * | outbuf, | |||
int | buflen, | |||
int | doreserved | |||
) |
ast_uri_encode: Turn text string to URI-encoded XX version
Turn text string to URI-encoded XX version 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 447 of file utils.c.
Referenced by initreqprep(), and uriencode().
00448 { 00449 char *reserved = ";/?:@&=+$,# "; /* Reserved chars */ 00450 00451 const char *ptr = string; /* Start with the string */ 00452 char *out = outbuf; 00453 00454 /* If there's no characters to convert, just go through and copy the string */ 00455 while (*ptr && out - outbuf < buflen - 1) { 00456 if ((*ptr < 32) || (doreserved && strchr(reserved, *ptr))) { 00457 if (out - outbuf >= buflen - 3) { 00458 break; 00459 } 00460 00461 out += sprintf(out, "%%%02x", (unsigned char) *ptr); 00462 } else { 00463 *out = *ptr; /* copy the character */ 00464 out++; 00465 } 00466 ptr++; 00467 } 00468 00469 if (buflen) { 00470 *out = '\0'; 00471 } 00472 00473 return outbuf; 00474 }
int ast_utils_init | ( | void | ) |
Definition at line 1382 of file utils.c.
References ast_cli_register_multiple(), and base64_init().
Referenced by main().
01383 { 01384 base64_init(); 01385 #ifdef DEBUG_THREADS 01386 #if !defined(LOW_MEMORY) 01387 ast_cli_register_multiple(utils_cli, sizeof(utils_cli) / sizeof(utils_cli[0])); 01388 #endif 01389 #endif 01390 return 0; 01391 }
int ast_wait_for_input | ( | int | fd, | |
int | ms | |||
) |
Definition at line 948 of file utils.c.
References pollfd::events, pollfd::fd, poll(), POLLIN, and POLLPRI.
Referenced by action_waitevent(), ast_moh_destroy_one(), http_root(), and main().
00949 { 00950 struct pollfd pfd[1]; 00951 memset(pfd, 0, sizeof(pfd)); 00952 pfd[0].fd = fd; 00953 pfd[0].events = POLLIN|POLLPRI; 00954 return poll(pfd, 1, ms); 00955 }
static void base64_init | ( | void | ) | [static] |
Definition at line 411 of file utils.c.
Referenced by ast_utils_init().
00412 { 00413 int x; 00414 memset(b2a, -1, sizeof(b2a)); 00415 /* Initialize base-64 Conversion table */ 00416 for (x = 0; x < 26; x++) { 00417 /* A-Z */ 00418 base64[x] = 'A' + x; 00419 b2a['A' + x] = x; 00420 /* a-z */ 00421 base64[x + 26] = 'a' + x; 00422 b2a['a' + x] = x + 26; 00423 /* 0-9 */ 00424 if (x < 10) { 00425 base64[x + 52] = '0' + x; 00426 b2a['0' + x] = x + 52; 00427 } 00428 } 00429 base64[62] = '+'; 00430 base64[63] = '/'; 00431 b2a[(int)'+'] = 62; 00432 b2a[(int)'/'] = 63; 00433 }
static void* dummy_start | ( | void * | data | ) | [static] |
Definition at line 859 of file utils.c.
References AST_LIST_INSERT_TAIL, AST_MUTEX_KIND, ast_register_thread(), ast_unregister_thread(), thr_arg::data, free, thr_arg::name, pthread_mutex_init, pthread_mutex_lock, pthread_mutex_unlock, thr_arg::start_routine, and strdup.
Referenced by ast_pthread_create_stack().
00860 { 00861 void *ret; 00862 struct thr_arg a = *((struct thr_arg *) data); /* make a local copy */ 00863 #ifdef DEBUG_THREADS 00864 struct thr_lock_info *lock_info; 00865 pthread_mutexattr_t mutex_attr; 00866 #endif 00867 00868 /* note that even though data->name is a pointer to allocated memory, 00869 we are not freeing it here because ast_register_thread is going to 00870 keep a copy of the pointer and then ast_unregister_thread will 00871 free the memory 00872 */ 00873 free(data); 00874 ast_register_thread(a.name); 00875 pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self()); 00876 00877 #ifdef DEBUG_THREADS 00878 if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info)))) 00879 return NULL; 00880 00881 lock_info->thread_id = pthread_self(); 00882 lock_info->thread_name = strdup(a.name); 00883 00884 pthread_mutexattr_init(&mutex_attr); 00885 pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND); 00886 pthread_mutex_init(&lock_info->lock, &mutex_attr); 00887 pthread_mutexattr_destroy(&mutex_attr); 00888 00889 pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */ 00890 AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry); 00891 pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */ 00892 #endif /* DEBUG_THREADS */ 00893 00894 ret = a.start_routine(a.data); 00895 00896 pthread_cleanup_pop(1); 00897 00898 return ret; 00899 }
static int gethostbyname_r | ( | const char * | name, | |
struct hostent * | ret, | |||
char * | buf, | |||
size_t | buflen, | |||
struct hostent ** | result, | |||
int * | h_errnop | |||
) | [static] |
Reentrant replacement for gethostbyname for BSD-based systems.
Definition at line 84 of file utils.c.
References ast_mutex_lock(), ast_mutex_unlock(), ERANGE, and gethostbyname.
Referenced by ast_gethostbyname().
00087 { 00088 int hsave; 00089 struct hostent *ph; 00090 ast_mutex_lock(&__mutex); /* begin critical area */ 00091 hsave = h_errno; 00092 00093 ph = gethostbyname(name); 00094 *h_errnop = h_errno; /* copy h_errno to *h_herrnop */ 00095 if (ph == NULL) { 00096 *result = NULL; 00097 } else { 00098 char **p, **q; 00099 char *pbuf; 00100 int nbytes=0; 00101 int naddr=0, naliases=0; 00102 /* determine if we have enough space in buf */ 00103 00104 /* count how many addresses */ 00105 for (p = ph->h_addr_list; *p != 0; p++) { 00106 nbytes += ph->h_length; /* addresses */ 00107 nbytes += sizeof(*p); /* pointers */ 00108 naddr++; 00109 } 00110 nbytes += sizeof(*p); /* one more for the terminating NULL */ 00111 00112 /* count how many aliases, and total length of strings */ 00113 for (p = ph->h_aliases; *p != 0; p++) { 00114 nbytes += (strlen(*p)+1); /* aliases */ 00115 nbytes += sizeof(*p); /* pointers */ 00116 naliases++; 00117 } 00118 nbytes += sizeof(*p); /* one more for the terminating NULL */ 00119 00120 /* here nbytes is the number of bytes required in buffer */ 00121 /* as a terminator must be there, the minimum value is ph->h_length */ 00122 if (nbytes > buflen) { 00123 *result = NULL; 00124 ast_mutex_unlock(&__mutex); /* end critical area */ 00125 return ERANGE; /* not enough space in buf!! */ 00126 } 00127 00128 /* There is enough space. Now we need to do a deep copy! */ 00129 /* Allocation in buffer: 00130 from [0] to [(naddr-1) * sizeof(*p)]: 00131 pointers to addresses 00132 at [naddr * sizeof(*p)]: 00133 NULL 00134 from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] : 00135 pointers to aliases 00136 at [(naddr+naliases+1) * sizeof(*p)]: 00137 NULL 00138 then naddr addresses (fixed length), and naliases aliases (asciiz). 00139 */ 00140 00141 *ret = *ph; /* copy whole structure (not its address!) */ 00142 00143 /* copy addresses */ 00144 q = (char **)buf; /* pointer to pointers area (type: char **) */ 00145 ret->h_addr_list = q; /* update pointer to address list */ 00146 pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */ 00147 for (p = ph->h_addr_list; *p != 0; p++) { 00148 memcpy(pbuf, *p, ph->h_length); /* copy address bytes */ 00149 *q++ = pbuf; /* the pointer is the one inside buf... */ 00150 pbuf += ph->h_length; /* advance pbuf */ 00151 } 00152 *q++ = NULL; /* address list terminator */ 00153 00154 /* copy aliases */ 00155 ret->h_aliases = q; /* update pointer to aliases list */ 00156 for (p = ph->h_aliases; *p != 0; p++) { 00157 strcpy(pbuf, *p); /* copy alias strings */ 00158 *q++ = pbuf; /* the pointer is the one inside buf... */ 00159 pbuf += strlen(*p); /* advance pbuf */ 00160 *pbuf++ = 0; /* string terminator */ 00161 } 00162 *q++ = NULL; /* terminator */ 00163 00164 strcpy(pbuf, ph->h_name); /* copy alias strings */ 00165 ret->h_name = pbuf; 00166 pbuf += strlen(ph->h_name); /* advance pbuf */ 00167 *pbuf++ = 0; /* string terminator */ 00168 00169 *result = ret; /* and let *result point to structure */ 00170 00171 } 00172 h_errno = hsave; /* restore h_errno */ 00173 ast_mutex_unlock(&__mutex); /* end critical area */ 00174 00175 return (*result == NULL); /* return 0 on success, non-zero on error */ 00176 }
int test_for_thread_safety | ( | void | ) |
Definition at line 265 of file utils.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, and test_thread_body().
Referenced by main().
00266 { 00267 ast_mutex_lock(&test_lock2); 00268 ast_mutex_lock(&test_lock); 00269 lock_count += 1; 00270 ast_mutex_lock(&test_lock); 00271 lock_count += 1; 00272 ast_pthread_create(&test_thread, NULL, test_thread_body, NULL); 00273 usleep(100); 00274 if (lock_count != 2) 00275 test_errors++; 00276 ast_mutex_unlock(&test_lock); 00277 lock_count -= 1; 00278 usleep(100); 00279 if (lock_count != 1) 00280 test_errors++; 00281 ast_mutex_unlock(&test_lock); 00282 lock_count -= 1; 00283 if (lock_count != 0) 00284 test_errors++; 00285 ast_mutex_unlock(&test_lock2); 00286 usleep(100); 00287 if (lock_count != 0) 00288 test_errors++; 00289 pthread_join(test_thread, NULL); 00290 return(test_errors); /* return 0 on success. */ 00291 }
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 242 of file utils.c.
References ast_mutex_lock(), and ast_mutex_unlock().
Referenced by test_for_thread_safety().
00243 { 00244 ast_mutex_lock(&test_lock); 00245 lock_count += 10; 00246 if (lock_count != 10) 00247 test_errors++; 00248 ast_mutex_lock(&test_lock); 00249 lock_count += 10; 00250 if (lock_count != 20) 00251 test_errors++; 00252 ast_mutex_lock(&test_lock2); 00253 ast_mutex_unlock(&test_lock); 00254 lock_count -= 10; 00255 if (lock_count != 10) 00256 test_errors++; 00257 ast_mutex_unlock(&test_lock); 00258 lock_count -= 10; 00259 ast_mutex_unlock(&test_lock2); 00260 if (lock_count != 0) 00261 test_errors++; 00262 return NULL; 00263 }
static struct timeval tvfix | ( | struct timeval | a | ) | [static, read] |
Definition at line 1089 of file utils.c.
References ast_log(), LOG_WARNING, and ONE_MILLION.
Referenced by ast_tvadd(), and ast_tvsub().
01090 { 01091 if (a.tv_usec >= ONE_MILLION) { 01092 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n", 01093 a.tv_sec, (long int) a.tv_usec); 01094 a.tv_sec += a.tv_usec / ONE_MILLION; 01095 a.tv_usec %= ONE_MILLION; 01096 } else if (a.tv_usec < 0) { 01097 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n", 01098 a.tv_sec, (long int) a.tv_usec); 01099 a.tv_usec = 0; 01100 } 01101 return a; 01102 }
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] |