Sat Nov 1 06:29:22 2008

Asterisk developer's documentation


utils.c File Reference

Utility functions. More...

#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"

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 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.
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)
 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)
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.
char * ast_unescape_semicolon (char *s)
 Strip backslash for "escaped" semicolons. s 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 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)
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


Detailed Description

Utility functions.

Note:
These are important for portability and security, so please use them in favour of other routines. Please consult the CODING GUIDELINES for more information.

Definition in file utils.c.


Define Documentation

#define AST_API_MODULE

Definition at line 64 of file utils.c.

#define AST_API_MODULE

Definition at line 64 of file utils.c.

#define AST_API_MODULE

Definition at line 64 of file utils.c.

#define AST_API_MODULE

Definition at line 64 of file utils.c.

#define AST_API_MODULE

Definition at line 64 of file utils.c.

#define AST_API_MODULE

Definition at line 64 of 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

Definition at line 1102 of file utils.c.

Referenced by ast_tvadd(), ast_tvsub(), and tvfix().


Function Documentation

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 1244 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.

01246 {
01247    char *result = NULL;
01248 
01249    if (__builtin_expect(needed > mgr->space, 0)) {
01250       size_t new_size = mgr->size * 2;
01251 
01252       while (new_size < needed)
01253          new_size *= 2;
01254 
01255       if (add_string_pool(mgr, new_size))
01256          return NULL;
01257    }
01258 
01259    result = mgr->pool->base + mgr->used;
01260    mgr->used += needed;
01261    mgr->space -= needed;
01262    return result;
01263 }

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 1292 of file utils.c.

References __ast_string_field_index_build_va().

01295 {
01296    va_list ap1, ap2;
01297 
01298    va_start(ap1, format);
01299    va_start(ap2, format);     /* va_copy does not exist on FreeBSD */
01300 
01301    __ast_string_field_index_build_va(mgr, fields, num_fields, index, format, ap1, ap2);
01302 
01303    va_end(ap1);
01304    va_end(ap2);
01305 }

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 1265 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().

01268 {
01269    size_t needed;
01270 
01271    needed = vsnprintf(mgr->pool->base + mgr->used, mgr->space, format, ap1) + 1;
01272 
01273    va_end(ap1);
01274 
01275    if (needed > mgr->space) {
01276       size_t new_size = mgr->size * 2;
01277 
01278       while (new_size < needed)
01279          new_size *= 2;
01280 
01281       if (add_string_pool(mgr, new_size))
01282          return;
01283 
01284       vsprintf(mgr->pool->base + mgr->used, format, ap2);
01285    }
01286 
01287    fields[index] = mgr->pool->base + mgr->used;
01288    mgr->used += needed;
01289    mgr->space -= needed;
01290 }

int __ast_string_field_init ( struct ast_string_field_mgr mgr,
size_t  size,
ast_string_field fields,
int  num_fields 
)

Definition at line 1230 of file utils.c.

References add_string_pool().

01232 {
01233    int index;
01234 
01235    if (add_string_pool(mgr, size))
01236       return -1;
01237 
01238    for (index = 0; index < num_fields; index++)
01239       fields[index] = __ast_string_field_empty;
01240 
01241    return 0;
01242 }

int _ast_asprintf ( char **  ret,
const char *  file,
int  lineno,
const char *  func,
const char *  fmt,
  ... 
)

Definition at line 1412 of file utils.c.

References MALLOC_FAILURE_MSG, and vasprintf.

01413 {
01414    int res;
01415    va_list ap;
01416 
01417    va_start(ap, fmt);
01418    if ((res = vasprintf(ret, fmt, ap)) == -1) {
01419       MALLOC_FAILURE_MSG;
01420    }
01421    va_end(ap);
01422 
01423    return res;
01424 }

static int add_string_pool ( struct ast_string_field_mgr mgr,
size_t  size 
) [static]

Definition at line 1214 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().

01215 {
01216    struct ast_string_field_pool *pool;
01217 
01218    if (!(pool = ast_calloc(1, sizeof(*pool) + size)))
01219       return -1;
01220    
01221    pool->prev = mgr->pool;
01222    mgr->pool = pool;
01223    mgr->size = size;
01224    mgr->space = size;
01225    mgr->used = 0;
01226 
01227    return 0;
01228 }

int ast_atomic_fetchadd_int_slow ( volatile int *  p,
int  v 
)

Definition at line 1309 of file utils.c.

References ast_mutex_lock(), and ast_mutex_unlock().

01310 {
01311         int ret;
01312         ast_mutex_lock(&fetchadd_m);
01313         ret = *p;
01314         *p += v;
01315         ast_mutex_unlock(&fetchadd_m);
01316         return ret;
01317 }

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 1056 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().

01057 {
01058    va_list ap;
01059    int result;
01060 
01061    va_start(ap, fmt);
01062    result = ast_build_string_va(buffer, space, fmt, ap);
01063    va_end(ap);
01064 
01065    return result;
01066 }

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.

Returns:
0 on success, non-zero on failure.
Parameters:
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 1037 of file utils.c.

Referenced by ast_build_string().

01038 {
01039    int result;
01040 
01041    if (!buffer || !*buffer || !space || !*space)
01042       return -1;
01043 
01044    result = vsnprintf(*buffer, *space, fmt, ap);
01045 
01046    if (result < 0)
01047       return -1;
01048    else if (result > *space)
01049       result = *space;
01050 
01051    *buffer += result;
01052    *space -= result;
01053    return 0;
01054 }

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

Note:
If you are calling ast_carefulwrite, it is assumed that you are calling it on a file descriptor that _DOES_ have NONBLOCK set. This way, there is only one system call made to do a write, unless we actually have a need to wait. This way, we get better performance.

Definition at line 975 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().

00976 {
00977    /* Try to write string, but wait no more than ms milliseconds
00978       before timing out */
00979    int res = 0;
00980    struct pollfd fds[1];
00981    while (len) {
00982       res = write(fd, s, len);
00983       if ((res < 0) && (errno != EAGAIN)) {
00984          return -1;
00985       }
00986       if (res < 0)
00987          res = 0;
00988       len -= res;
00989       s += res;
00990       res = 0;
00991       if (len) {
00992          fds[0].fd = fd;
00993          fds[0].events = POLLOUT;
00994          /* Wait until writable again */
00995          res = poll(fds, 1, timeoutms);
00996          if (res < 1)
00997             return -1;
00998       }
00999    }
01000    return res;
01001 }

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 1345 of file utils.c.

References ast_realloc, ast_threadstorage::key, and offset.

01347 {
01348    int res;
01349    int offset = (append && (*buf)->len) ? strlen((*buf)->str) : 0;
01350 #if defined(DEBUG_THREADLOCALS)
01351    struct ast_dynamic_str *old_buf = *buf;
01352 #endif /* defined(DEBUG_THREADLOCALS) */
01353 
01354    res = vsnprintf((*buf)->str + offset, (*buf)->len - offset, fmt, ap);
01355 
01356    /* Check to see if there was not enough space in the string buffer to prepare
01357     * the string.  Also, if a maximum length is present, make sure the current
01358     * length is less than the maximum before increasing the size. */
01359    if ((res + offset + 1) > (*buf)->len && (max_len ? ((*buf)->len < max_len) : 1)) {
01360       /* Set the new size of the string buffer to be the size needed
01361        * to hold the resulting string (res) plus one byte for the
01362        * terminating '\0'.  If this size is greater than the max, set
01363        * the new length to be the maximum allowed. */
01364       if (max_len)
01365          (*buf)->len = ((res + offset + 1) < max_len) ? (res + offset + 1) : max_len;
01366       else
01367          (*buf)->len = res + offset + 1;
01368 
01369       if (!(*buf = ast_realloc(*buf, (*buf)->len + sizeof(*(*buf)))))
01370          return AST_DYNSTR_BUILD_FAILED;
01371 
01372       if (append)
01373          (*buf)->str[offset] = '\0';
01374 
01375       if (ts) {
01376          pthread_setspecific(ts->key, *buf);
01377 #if defined(DEBUG_THREADLOCALS)
01378          __ast_threadstorage_object_replace(old_buf, *buf, (*buf)->len + sizeof(*(*buf)));
01379 #endif /* defined(DEBUG_THREADLOCALS) */
01380       }
01381 
01382       /* va_end() and va_start() must be done before calling
01383        * vsnprintf() again. */
01384       return AST_DYNSTR_BUILD_RETRY;
01385    }
01386 
01387    return res;
01388 }

void ast_enable_packet_fragmentation ( int  sock  ) 

Definition at line 1390 of file utils.c.

References ast_log(), and LOG_WARNING.

Referenced by ast_netsock_bindaddr().

01391 {
01392 #if defined(HAVE_IP_MTU_DISCOVER)
01393    int val = IP_PMTUDISC_DONT;
01394    
01395    if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
01396       ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
01397 #endif /* HAVE_IP_MTU_DISCOVER */
01398 }

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 1085 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(), and strings_to_mask().

01086 {
01087    if (ast_strlen_zero(s))
01088       return 0;
01089 
01090    /* Determine if this is a false value */
01091    if (!strcasecmp(s, "no") ||
01092        !strcasecmp(s, "false") ||
01093        !strcasecmp(s, "n") ||
01094        !strcasecmp(s, "f") ||
01095        !strcasecmp(s, "0") ||
01096        !strcasecmp(s, "off"))
01097       return -1;
01098 
01099    return 0;
01100 }

int ast_get_time_t ( const char *  src,
time_t *  dst,
time_t  _default,
int *  consumed 
)

get values from config variables.

Definition at line 1322 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().

01323 {
01324    long t;
01325    int scanned;
01326 
01327    if (dst == NULL)
01328       return -1;
01329 
01330    *dst = _default;
01331 
01332    if (ast_strlen_zero(src))
01333       return -1;
01334 
01335    /* only integer at the moment, but one day we could accept more formats */
01336    if (sscanf(src, "%ld%n", &t, &scanned) == 1) {
01337       *dst = t;
01338       if (consumed)
01339          *consumed = scanned;
01340       return 0;
01341    } else
01342       return -1;
01343 }

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 184 of file utils.c.

References gethostbyname_r(), hp, and s.

Referenced by __ast_http_load(), __set_address_from_contact(), 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(), realtime_peer(), realtime_user(), reload_config(), rtcp_do_debug_ip(), rtcp_do_debug_ip_deprecated(), rtp_do_debug_ip(), 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  ) 

thread-safe replacement for inet_ntoa().

Note:
It is very important to note that even though this is a thread-safe replacement for inet_ntoa(), it is *not* reentrant. In a single thread, the result from a previous call to this function is no longer valid once it is called again. If the result from multiple calls to this function need to be kept or used at once, then the result must be copied to a local buffer before calling this function again.

Definition at line 495 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_peer(), 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_command(), find_peer(), find_subchannel_and_lock(), function_iaxpeer(), function_sipchaninfo_read(), function_sippeer(), 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(), 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().

00496 {
00497    char *buf;
00498 
00499    if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
00500       return "";
00501 
00502    return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
00503 }

void ast_join ( char *  s,
size_t  len,
char *const   w[] 
)

Definition at line 1193 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().

01194 {
01195    int x, ofs = 0;
01196    const char *src;
01197 
01198    /* Join words into a string */
01199    if (!s)
01200       return;
01201    for (x = 0; ofs < len && w[x]; x++) {
01202       if (x > 0)
01203          s[ofs++] = ' ';
01204       for (src = w[x]; *src && ofs < len; src++)
01205          s[ofs++] = *src;
01206    }
01207    if (ofs == len)
01208       ofs--;
01209    s[ofs] = '\0';
01210 }

void ast_md5_hash ( char *  output,
char *  input 
)

Produce 32 char MD5 hash of value.

Definition at line 294 of file utils.c.

References md5(), 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.

Parameters:
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 1167 of file utils.c.

Referenced by handle_context_add_extension(), handle_context_add_extension_deprecated(), and pbx_load_config().

01168 {
01169    char *dataPut = start;
01170    int inEscape = 0;
01171    int inQuotes = 0;
01172 
01173    for (; *start; start++) {
01174       if (inEscape) {
01175          *dataPut++ = *start;       /* Always goes verbatim */
01176          inEscape = 0;
01177       } else {
01178          if (*start == '\\') {
01179             inEscape = 1;      /* Do not copy \ into the data */
01180          } else if (*start == '\'') {
01181             inQuotes = 1 - inQuotes;   /* Do not copy ' into the data */
01182          } else {
01183             /* Replace , with |, unless in quotes */
01184             *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
01185          }
01186       }
01187    }
01188    if (start != dataPut)
01189       *dataPut = 0;
01190    return dataPut;
01191 }

<