Wed Oct 28 15:49:23 2009

Asterisk developer's documentation


utils.c File Reference

Utility functions. More...

#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.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/compat.h"
#include "asterisk/strings.h"
#include "asterisk/time.h"
#include "asterisk/utils.h"

Include dependency graph for utils.c:

Go to the source code of this file.

Defines

#define AST_API_MODULE
#define AST_API_MODULE
#define AST_API_MODULE
#define AST_API_MODULE
#define LONG_MAX   9223372036854775807L
#define LONG_MIN   (-9223372036854775807L-1L)
#define ONE_MILLION   1000000

Functions

int ast_atomic_fetchadd_int_slow (volatile int *p, int v)
int ast_base64decode (unsigned char *dst, const char *src, int max)
int ast_base64encode (char *dst, const unsigned char *src, int srclen, int max)
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.
void ast_enable_packet_fragmentation (int sock)
 Disable PMTU discovery on a socket.
int ast_false (const char *s)
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 (char *buf, int bufsiz, struct in_addr ia)
 ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa
void ast_md5_hash (char *output, char *input)
 ast_md5_hash: Produce 16 char MD5 hash of value. ---
 AST_MUTEX_DEFINE_STATIC (fetchadd_m)
 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)
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)
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.
void ast_uri_decode (char *s)
 ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string) ---
char * ast_uri_encode (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)
int getloadavg (double *list, int nelem)
char * strcasestr (const char *haystack, const char *needle)
char * strndup (const char *s, size_t n)
size_t strnlen (const char *s, size_t n)
uint64_t strtoq (const char *nptr, char **endptr, int base)
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)
static char * upper (const char *orig, char *buf, int bufsize)
int vasprintf (char **strp, const char *fmt, va_list ap)

Variables

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

#define AST_API_MODULE

Definition at line 58 of file utils.c.

#define AST_API_MODULE

Definition at line 58 of file utils.c.

#define AST_API_MODULE

Definition at line 58 of file utils.c.

#define LONG_MAX   9223372036854775807L

Definition at line 764 of file utils.c.

Referenced by strtoq().

#define LONG_MIN   (-9223372036854775807L-1L)

Definition at line 760 of file utils.c.

Referenced by strtoq().

#define ONE_MILLION   1000000

Definition at line 620 of file utils.c.

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


Function Documentation

int ast_atomic_fetchadd_int_slow ( volatile int *  p,
int  v 
)

Definition at line 933 of file utils.c.

References ast_mutex_lock(), and ast_mutex_unlock().

00934 {
00935         int ret;
00936         ast_mutex_lock(&fetchadd_m);
00937         ret = *p;
00938         *p += v;
00939         ast_mutex_unlock(&fetchadd_m);
00940         return ret;
00941 }

int ast_base64decode ( unsigned char *  dst,
const char *  src,
int  max 
)

Definition at line 319 of file utils.c.

Referenced by __ast_check_signature(), and ast_osp_validate().

00320 {
00321    int cnt = 0;
00322    unsigned int byte = 0;
00323    unsigned int bits = 0;
00324    int incnt = 0;
00325 #if 0
00326    unsigned char *odst = dst;
00327 #endif
00328    while(*src && (cnt < max)) {
00329       /* Shift in 6 bits of input */
00330       byte <<= 6;
00331       byte |= (b2a[(int)(*src)]) & 0x3f;
00332       bits += 6;
00333 #if 0
00334       printf("Add: %c %s\n", *src, binary(b2a[(int)(*src)] & 0x3f, 6));
00335 #endif
00336       src++;
00337       incnt++;
00338       /* If we have at least 8 bits left over, take that character 
00339          off the top */
00340       if (bits >= 8)  {
00341          bits -= 8;
00342          *dst = (byte >> bits) & 0xff;
00343 #if 0
00344          printf("Remove: %02x %s\n", *dst, binary(*dst, 8));
00345 #endif
00346          dst++;
00347          cnt++;
00348       }
00349    }
00350 #if 0
00351    dump(odst, cnt);
00352 #endif
00353    /* Dont worry about left over bits, they're extra anyway */
00354    return cnt;
00355 }

int ast_base64encode ( char *  dst,
const unsigned char *  src,
int  srclen,
int  max 
)

Definition at line 357 of file utils.c.

Referenced by __ast_sign(), ast_osp_lookup(), ast_osp_next(), and build_secret().

00358 {
00359    int cnt = 0;
00360    unsigned int byte = 0;
00361    int bits = 0;
00362    int index;
00363    int cntin = 0;
00364 #if 0
00365    char *odst = dst;
00366    dump(src, srclen);
00367 #endif
00368    /* Reserve one bit for end */
00369    max--;
00370    while((cntin < srclen) && (cnt < max)) {
00371       byte <<= 8;
00372 #if 0
00373       printf("Add: %02x %s\n", *src, binary(*src, 8));
00374 #endif
00375       byte |= *(src++);
00376       bits += 8;
00377       cntin++;
00378       while((bits >= 6) && (cnt < max)) {
00379          bits -= 6;
00380          /* We want only the top */
00381          index = (byte >> bits) & 0x3f;
00382          *dst = base64[index];
00383 #if 0
00384          printf("Remove: %c %s\n", *dst, binary(index, 6));
00385 #endif
00386          dst++;
00387          cnt++;
00388       }
00389    }
00390    if (bits && (cnt < max)) {
00391       /* Add one last character for the remaining bits, 
00392          padding the rest with 0 */
00393       byte <<= (6 - bits);
00394       index = (byte) & 0x3f;
00395       *(dst++) = base64[index];
00396       cnt++;
00397    }
00398    *dst = '\0';
00399    return cnt;
00400 }

int ast_build_string ( char **  buffer,
size_t *  space,
const char *  fmt,
  ... 
)

Definition at line 574 of file utils.c.

References ast_build_string_va().

Referenced by __queues_show(), add_codec_to_sdp(), add_noncodec_to_sdp(), add_sdp(), ast_cdr_serialize_variables(), config_odbc(), initreqprep(), manager_event(), pbx_builtin_serialize_variables(), skinny_call(), transmit_notify_with_mwi(), and transmit_state_notify().

00575 {
00576    va_list ap;
00577    int result;
00578 
00579    va_start(ap, fmt);
00580    result = ast_build_string_va(buffer, space, fmt, ap);
00581    va_end(ap);
00582 
00583    return result;
00584 }

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

Referenced by ast_build_string(), and manager_event().

00556 {
00557    int result;
00558 
00559    if (!buffer || !*buffer || !space || !*space)
00560       return -1;
00561 
00562    result = vsnprintf(*buffer, *space, fmt, ap);
00563 
00564    if (result < 0)
00565       return -1;
00566    else if (result > *space)
00567       result = *space;
00568 
00569    *buffer += result;
00570    *space -= result;
00571    return 0;
00572 }

void ast_enable_packet_fragmentation ( int  sock  ) 

Disable PMTU discovery on a socket.

Parameters:
sock The socket to manipulate
Returns:
Nothing
On Linux, UDP sockets default to sending packets with the Dont Fragment (DF) bit set. This is supposedly done to allow the application to do PMTU discovery, but Asterisk does not do this.

Because of this, UDP packets sent by Asterisk that are larger than the MTU of any hop in the path will be lost. This function can be called on a socket to ensure that the DF bit will not be set.

Definition at line 921 of file utils.c.

References ast_log(), and LOG_WARNING.

Referenced by ast_netsock_bindaddr(), and reload_config().

00922 {
00923 #ifdef __linux__
00924    int val = IP_PMTUDISC_DONT;
00925    
00926    if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
00927       ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
00928 #endif
00929 }

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

References ast_strlen_zero().

Referenced by ast_rtp_reload(), ast_strings_to_mask(), build_peer(), build_user(), handle_common_options(), and pbx_load_module().

00604 {
00605    if (ast_strlen_zero(s))
00606       return 0;
00607 
00608    /* Determine if this is a false value */
00609    if (!strcasecmp(s, "no") ||
00610        !strcasecmp(s, "false") ||
00611        !strcasecmp(s, "n") ||
00612        !strcasecmp(s, "f") ||
00613        !strcasecmp(s, "0") ||
00614        !strcasecmp(s, "off"))
00615       return -1;
00616 
00617    return 0;
00618 }

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

References ast_hostent::buf, ast_hostent::hp, and s.

Referenced by ast_dnsmgr_lookup(), ast_find_ourip(), ast_get_ip_or_srv(), ast_sip_ouraddrfor(), build_peer(), check_via(), create_addr(), festival_exec(), iax2_register(), iax_template_parse(), launch_netscript(), parse_ok_contact(), parse_register_contact(), process_sdp(), realtime_peer(), realtime_user(), refresh_list(), reload_config(), rpt_exec(), rtp_do_debug_ip(), set_config(), set_destination(), sip_devicestate(), and sip_do_debug_ip().

00177 {
00178    int res;
00179    int herrno;
00180    int dots=0;
00181    const char *s;
00182    struct hostent *result = NULL;
00183    /* Although it is perfectly legitimate to lookup a pure integer, for
00184       the sake of the sanity of people who like to name their peers as
00185       integers, we break with tradition and refuse to look up a
00186       pure integer */
00187    s = host;
00188    res = 0;
00189    while(s && *s) {
00190       if (*s == '.')
00191          dots++;
00192       else if (!isdigit(*s))
00193          break;
00194       s++;
00195    }
00196    if (!s || !*s) {
00197       /* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
00198       if (dots != 3)
00199          return NULL;
00200       memset(hp, 0, sizeof(struct ast_hostent));
00201       hp->hp.h_addrtype = AF_INET;
00202       hp->hp.h_addr_list = (void *) hp->buf;
00203       hp->hp.h_addr = hp->buf + sizeof(void *);
00204       if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
00205          return &hp->hp;
00206       return NULL;
00207       
00208    }
00209 #ifdef SOLARIS
00210    result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
00211 
00212    if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
00213       return NULL;
00214 #else
00215    res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
00216 
00217    if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
00218       return NULL;
00219 #endif
00220    return &hp->hp;
00221 }

const char* ast_inet_ntoa ( char *  buf,
int  bufsiz,
struct in_addr  ia 
)

ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa

Definition at line 486 of file utils.c.

Referenced by __iax2_show_peers(), __sip_show_channels(), __sip_xmit(), _sip_show_peer(), _sip_show_peers(), add_sdp(), ast_apply_ha(), ast_netsock_bindaddr(), ast_osp_validate(), ast_rtcp_read(), ast_rtp_bridge(), ast_rtp_raw_write(), ast_rtp_read(), ast_rtp_sendcng(), ast_rtp_senddigit(), ast_sip_ouraddrfor(), attempt_transmit(), authenticate(), build_callid(), build_contact(), build_reply_digest(), build_rpid(), build_via(), calltoken_required(), check_access(), check_user_full(), check_via(), copy_via_headers(), create_addr_from_peer(), 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(), find_tpeer(), find_user(), function_iaxpeer(), function_sipchaninfo_read(), function_sippeer(), get_input(), handle_call_token(), handle_command_response(), handle_error(), handle_message(), handle_request(), handle_request_bye(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_showmanconn(), iax2_ack_registry(), iax2_prov_app(), iax2_show_callnumber_usage(), 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_call(), oh323_set_rtp_peer(), parse_register_contact(), peercnt_add(), peercnt_modify(), peercnt_remove(), 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(), rtp_do_debug_ip(), sched_delay_remove(), send_dtmf(), send_packet(), send_request(), send_response(), send_trunk(), session_do(), set_config(), set_destination(), set_peercnt_limit(), setup_incoming_call(), sip_do_debug_ip(), sip_do_debug_peer(), sip_new(), sip_poke_peer(), sip_set_rtp_peer(), sip_show_channel(), sip_show_settings(), sipsock_read(), skinny_session(), skinny_show_devices(), socket_read(), timing_read(), transmit_notify_with_mwi(), and update_registry().

00487 {
00488    return inet_ntop(AF_INET, &ia, buf, bufsiz);
00489 }

void ast_md5_hash ( char *  output,
char *  input 
)

ast_md5_hash: Produce 16 char MD5 hash of value. ---

Definition at line 286 of file utils.c.

References MD5Final(), MD5Init(), and MD5Update().

Referenced by auth_exec(), build_reply_digest(), builtin_function_checkmd5(), builtin_function_md5(), check_auth(), md5_exec(), and md5check_exec().

00287 {
00288    struct MD5Context md5;
00289    unsigned char digest[16];
00290    char *ptr;
00291    int x;
00292 
00293    MD5Init(&md5);
00294    MD5Update(&md5, (unsigned char *)input, strlen(input));
00295    MD5Final(digest, &md5);
00296    ptr = output;
00297    for (x=0; x<16; x++)
00298       ptr += sprintf(ptr, "%2.2x", digest[x]);
00299 }

AST_MUTEX_DEFINE_STATIC ( fetchadd_m   ) 

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.

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

Referenced by __build_step(), handle_context_add_extension(), and pbx_load_module().

00896 {
00897    char *dataPut = start;
00898    int inEscape = 0;
00899    int inQuotes = 0;
00900 
00901    for (; *start; start++) {
00902       if (inEscape) {
00903          *dataPut++ = *start;       /* Always goes verbatim */
00904          inEscape = 0;
00905          } else {
00906          if (*start == '\\') {
00907             inEscape = 1;      /* Do not copy \ into the data */
00908          } else if (*start == '\'') {
00909             inQuotes = 1-inQuotes;   /* Do not copy ' into the data */
00910          } else {
00911             /* Replace , with |, unless in quotes */
00912             *dataPut++ = inQuotes ? *start : ((*start==find) ? replace_with : *start);
00913          }
00914       }
00915    }
00916    if (start != dataPut)
00917       *dataPut = 0;
00918    return dataPut;
00919 }

int ast_pthread_create_stack ( pthread_t *  thread,
pthread_attr_t *  attr,
void *(*)(void *)  start_routine,
void *  data,
size_t  stacksize 
)

Definition at line 501 of file utils.c.

References ast_log(), AST_STACKSIZE, LOG_WARNING, and pthread_create.

00502 {
00503    pthread_attr_t lattr;
00504    if (!attr) {
00505       pthread_attr_init(&lattr);
00506       attr = &lattr;
00507    }
00508 #ifdef __linux__
00509    /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
00510       which is kind of useless. Change this here to
00511       PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
00512       priority will propagate down to new threads by default.
00513       This does mean that callers cannot set a different priority using
00514       PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
00515       the priority afterwards with pthread_setschedparam(). */
00516    errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED);
00517    if (errno)
00518       ast_log(LOG_WARNING, "pthread_attr_setinheritsched returned non-zero: %s\n", strerror(errno));
00519 #endif
00520 
00521    if (!stacksize)
00522       stacksize = AST_STACKSIZE;
00523    errno = pthread_attr_setstacksize(attr, stacksize);
00524    if (errno)
00525       ast_log(LOG_WARNING, "pthread_attr_setstacksize returned non-zero: %s\n", strerror(errno));
00526    return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
00527 }

void ast_sha1_hash ( char *  output,
char *  input 
)

Produce 40 char SHA1 hash of value.

Definition at line 302 of file utils.c.

References SHA1Input(), SHA1Reset(), and SHA1Result().

Referenced by handle_call_token().

00303 {
00304    struct SHA1Context sha;
00305    char *ptr;
00306    int x;
00307    uint8_t Message_Digest[20];
00308 
00309    SHA1Reset(&sha);
00310    
00311    SHA1Input(&sha, (const unsigned char *) input, strlen(input));
00312 
00313    SHA1Result(&sha, Message_Digest);
00314    ptr = output;
00315    for (x = 0; x < 20; x++)
00316       ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
00317 }

char* ast_strip_quoted ( char *  s,
const char *  beg_quotes,
const char *  end_quotes 
)

Definition at line 538 of file utils.c.

Referenced by ast_register_file_version(), builtin_function_if(), builtin_function_iftime(), and parse_dial_string().

00539 {
00540    char *e;
00541    char *q;
00542 
00543    s = ast_strip(s);
00544    if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
00545       e = s + strlen(s) - 1;
00546       if (*e == *(end_quotes + (q - beg_quotes))) {
00547          s++;
00548          *e = '\0';
00549       }
00550    }
00551 
00552    return s;
00553 }

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

References ast_strlen_zero().

Referenced by __load_resource(), __login_exec(), _parse(), action_agent_callback_login(), action_agent_logoff(), action_originate(), action_setcdruserfield(), apply_option(), ast_readconfig(), ast_strings_to_mask(), build_device(), build_gateway(), build_peer(), build_user(), config_load(), dial_exec_full(), do_reload(), festival_exec(), function_ilink(), get_encrypt_methods(), handle_common_options(), init_logger_chain(), init_manager(), load_config(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), loadconfigurationfile(), manager_add_queue_member(), manager_pause_queue_member(), odbc_load_module(), parse_config(), pbx_load_module(), queue_set_param(), read_agent_config(), reload_config(), reload_queues(), rpt_master(), set_config(), setup_zap(), start_monitor_action(), and update_common_options().

00587 {
00588    if (ast_strlen_zero(s))
00589       return 0;
00590 
00591    /* Determine if this is a true value */
00592    if (!strcasecmp(s, "yes") ||
00593        !strcasecmp(s, "true") ||
00594        !strcasecmp(s, "y") ||
00595        !strcasecmp(s, "t") ||
00596        !strcasecmp(s, "1") ||
00597        !strcasecmp(s, "on"))
00598       return -1;
00599 
00600    return 0;
00601 }

struct timeval ast_tvadd ( struct timeval  a,
struct timeval  b 
) [read]

Definition at line 640 of file utils.c.

References ONE_MILLION, and tvfix().

Referenced by agent_hangup(), agent_read(), ast_channel_bridge(), ast_channel_spy_trigger_wait(), ast_rtp_sendcng(), ast_rtp_senddigit(), ast_sched_runq(), ast_smoother_read(), ast_translate(), calc_rxstamp(), calc_timestamp(), do_cdr(), get_from_jb(), monmp3thread(), mp3_exec(), NBScat_exec(), sched_settime(), and schedule_delivery().

00641 {
00642    /* consistency checks to guarantee usec in 0..999999 */
00643    a = tvfix(a);
00644    b = tvfix(b);
00645    a.tv_sec += b.tv_sec;
00646    a.tv_usec += b.tv_usec;
00647    if (a.tv_usec >= ONE_MILLION) {
00648       a.tv_sec++;
00649       a.tv_usec -= ONE_MILLION;
00650    }
00651    return a;
00652 }

struct timeval ast_tvsub ( struct timeval  a,
struct timeval  b 
) [read]

Returns the difference of two timevals a - b.

Definition at line 654 of file utils.c.

References ONE_MILLION, and tvfix().

Referenced by ast_channel_bridge(), ast_sched_dump(), ast_translate(), calc_rxstamp(), and calc_timestamp().

00655 {
00656    /* consistency checks to guarantee usec in 0..999999 */
00657    a = tvfix(a);
00658    b = tvfix(b);
00659    a.tv_sec -= b.tv_sec;
00660    a.tv_usec -= b.tv_usec;
00661    if (a.tv_usec < 0) {
00662       a.tv_sec-- ;
00663       a.tv_usec += ONE_MILLION;
00664    }
00665    return a;
00666 }

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

Referenced by builtin_function_uridecode(), check_user_full(), get_destination(), get_refer_info(), and register_verify().

00470 {
00471    char *o;
00472    unsigned int tmp;
00473 
00474    for (o = s; *s; s++, o++) {
00475       if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
00476          /* have '%', two chars and correct parsing */
00477          *o = tmp;
00478          s += 2;  /* Will be incremented once more when we break out */
00479       } else /* all other cases, just copy */
00480          *o = *s;
00481    }
00482    *o = '\0';
00483 }

char* ast_uri_encode ( 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 438 of file utils.c.

Referenced by builtin_function_uriencode(), and initreqprep().

00439 {
00440    char *reserved = ";/?:@&=+$, ";  /* Reserved chars */
00441 
00442    char *ptr  = string; /* Start with the string */
00443    char *out = NULL;
00444    char *buf = NULL;
00445 
00446    strncpy(outbuf, string, buflen);
00447 
00448    /* If there's no characters to convert, just go through and don't do anything */
00449    while (*ptr) {
00450       if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
00451          /* Oops, we need to start working here */
00452          if (!buf) {
00453             buf = outbuf;
00454             out = buf + (ptr - string) ;  /* Set output ptr */
00455          }
00456          out += sprintf(out, "%%%02x", (unsigned char) *ptr);
00457       } else if (buf) {
00458          *out = *ptr;   /* Continue copying the string */
00459          out++;
00460       } 
00461       ptr++;
00462    }
00463    if (buf)
00464       *out = '\0';
00465    return outbuf;
00466 }

int ast_utils_init ( void   ) 

Definition at line 491 of file utils.c.

References base64_init().

Referenced by main().

00492 {
00493    base64_init();
00494    return 0;
00495 }

int ast_wait_for_input ( int  fd,
int  ms 
)

Definition at line 529 of file utils.c.

References pollfd::events, pollfd::fd, poll(), POLLIN, and POLLPRI.

Referenced by ast_moh_destroy().

00530 {
00531    struct pollfd pfd[1];
00532    memset(pfd, 0, sizeof(pfd));
00533    pfd[0].fd = fd;
00534    pfd[0].events = POLLIN|POLLPRI;
00535    return poll(pfd, 1, ms);
00536 }

static void base64_init ( void   )  [static]

Definition at line 402 of file utils.c.

Referenced by ast_utils_init().

00403 {
00404    int x;
00405    memset(b2a, -1, sizeof(b2a));
00406    /* Initialize base-64 Conversion table */
00407    for (x=0;x<26;x++) {
00408       /* A-Z */
00409       base64[x] = 'A' + x;
00410       b2a['A' + x] = x;
00411       /* a-z */
00412       base64[x + 26] = 'a' + x;
00413       b2a['a' + x] = x + 26;
00414       /* 0-9 */
00415       if (x < 10) {
00416          base64[x + 52] = '0' + x;
00417          b2a['0' + x] = x + 52;
00418       }
00419    }
00420    base64[62] = '+';
00421    base64[63] = '/';
00422    b2a[(int)'+'] = 62;
00423    b2a[(int)'/'] = 63;
00424 }

int getloadavg ( double *  list,
int  nelem 
)

Definition at line 883 of file utils.c.

Referenced by ast_readconfig(), and increase_call_count().

00884 {
00885    int i;
00886 
00887    for (i = 0; i < nelem; i++) {
00888       list[i] = 0.1;
00889    }
00890    return -1;
00891 }

char* strcasestr ( const char *  haystack,
const char *  needle 
)

Definition at line 684 of file utils.c.

References ast_log(), LOG_ERROR, offset, and upper().

Referenced by anti_injection(), do_directory(), find_sdp(), gettag(), handle_response_register(), handle_show_applications(), modlist_modentry(), parse_register_contact(), playback_exec(), realtime_multi_odbc(), realtime_odbc(), reqprep(), respprep(), and sip_sipredirect().

00685 {
00686    char *u1, *u2;
00687    int u1len = strlen(haystack) + 1, u2len = strlen(needle) + 1;
00688 
00689    u1 = alloca(u1len);
00690    u2 = alloca(u2len);
00691    if (u1 && u2) {
00692       char *offset;
00693       if (u2len > u1len) {
00694          /* Needle bigger than haystack */
00695          return NULL;
00696       }
00697       offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
00698       if (offset) {
00699          /* Return the offset into the original string */
00700          return ((char *)((unsigned long)haystack + (unsigned long)(offset - u1)));
00701       } else {
00702          return NULL;
00703       }
00704    } else {
00705       ast_log(LOG_ERROR, "Out of memory\n");
00706       return NULL;
00707    }
00708 }

char* strndup ( const char *  s,
size_t  n 
)

Definition at line 725 of file utils.c.

References malloc, and strnlen().

00726 {
00727    size_t len = strnlen(s, n);
00728    char *new = malloc(len + 1);
00729 
00730    if (!new)
00731       return NULL;
00732 
00733    new[len] = '\0';
00734    return memcpy(new, s, len);
00735 }

size_t strnlen ( const char *  s,
size_t  n 
)

Definition at line 712 of file utils.c.

Referenced by strndup().

00713 {
00714    size_t len;
00715 
00716    for (len=0; len < n; len++)
00717       if (s[len] == '\0')
00718          break;
00719 
00720    return len;
00721 }

uint64_t strtoq ( const char *  nptr,
char **  endptr,
int  base 
)

Definition at line 774 of file utils.c.

References LONG_MAX, LONG_MIN, and s.

00775 {
00776     const char *s;
00777     uint64_t acc;
00778     unsigned char c;
00779     uint64_t qbase, cutoff;
00780     int neg, any, cutlim;
00781 
00782     /*
00783      * Skip white space and pick up leading +/- sign if any.
00784      * If base is 0, allow 0x for hex and 0 for octal, else
00785      * assume decimal; if base is already 16, allow 0x.
00786      */
00787     s = nptr;
00788     do {
00789             c = *s++;
00790     } while (isspace(c));
00791     if (c == '-') {
00792             neg = 1;
00793             c = *s++;
00794     } else {
00795             neg = 0;
00796             if (c == '+')
00797                     c = *s++;
00798     }
00799     if ((base == 0 || base == 16) &&
00800         c == '\0' && (*s == 'x' || *s == 'X')) {
00801             c = s[1];
00802             s += 2;
00803             base = 16;
00804     }
00805     if (base == 0)
00806             base = c == '\0' ? 8 : 10;
00807 
00808     /*
00809      * Compute the cutoff value between legal numbers and illegal
00810      * numbers.  That is the largest legal value, divided by the
00811      * base.  An input number that is greater than this value, if
00812      * followed by a legal input character, is too big.  One that
00813      * is equal to this value may be valid or not; the limit
00814      * between valid and invalid numbers is then based on the last
00815      * digit.  For instance, if the range for quads is
00816      * [-9223372036854775808..9223372036854775807] and the input base
00817      * is 10, cutoff will be set to 922337203685477580 and cutlim to
00818      * either 7 (neg==0) or 8 (neg==1), meaning that if we have
00819      * accumulated a value > 922337203685477580, or equal but the
00820      * next digit is > 7 (or 8), the number is too big, and we will
00821      * return a range error.
00822      *
00823      * Set any if any `digits' consumed; make it negative to indicate
00824      * overflow.
00825      */
00826     qbase = (unsigned)base;
00827     cutoff = neg ? (uint64_t)-(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX;
00828     cutlim = cutoff % qbase;
00829     cutoff /= qbase;
00830     for (acc = 0, any = 0;; c = *s++) {
00831             if (!isascii(c))
00832                     break;
00833             if (isdigit(c))
00834                     c -= '\0';
00835             else if (isalpha(c))
00836                     c -= isupper(c) ? 'A' - 10 : 'a' - 10;
00837             else
00838                     break;
00839             if (c >= base)
00840                     break;
00841             if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
00842                     any = -1;
00843             else {
00844                     any = 1;
00845                     acc *= qbase;
00846                     acc += c;
00847             }
00848     }
00849     if (any < 0) {
00850             acc = neg ? LONG_MIN : LONG_MAX;
00851     } else if (neg)
00852             acc = -acc;
00853     if (endptr != 0)
00854             *((const char **)endptr) = any ? s - 1 : nptr;
00855     return acc;
00856 }

int test_for_thread_safety ( void   ) 

Definition at line 257 of file utils.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, and test_thread_body().

Referenced by main().

00258 { 
00259    ast_mutex_lock(&test_lock2);
00260    ast_mutex_lock(&test_lock);
00261    lock_count += 1;
00262    ast_mutex_lock(&test_lock);
00263    lock_count += 1;
00264    ast_pthread_create(&test_thread, NULL, test_thread_body, NULL); 
00265    usleep(100);
00266    if (lock_count != 2) 
00267       test_errors++;
00268    ast_mutex_unlock(&test_lock);
00269    lock_count -= 1;
00270    usleep(100); 
00271    if (lock_count != 1) 
00272       test_errors++;
00273    ast_mutex_unlock(&test_lock);
00274    lock_count -= 1;
00275    if (lock_count != 0) 
00276       test_errors++;
00277    ast_mutex_unlock(&test_lock2);
00278    usleep(100);
00279    if (lock_count != 0) 
00280       test_errors++;
00281    pthread_join(test_thread, NULL);
00282    return(test_errors);          /* return 0 on success. */
00283 }

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

References ast_mutex_lock(), and ast_mutex_unlock().

Referenced by test_for_thread_safety().

00235 { 
00236    ast_mutex_lock(&test_lock);
00237    lock_count += 10;
00238    if (lock_count != 10) 
00239       test_errors++;
00240    ast_mutex_lock(&test_lock);
00241    lock_count += 10;
00242    if (lock_count != 20) 
00243       test_errors++;
00244    ast_mutex_lock(&test_lock2);
00245    ast_mutex_unlock(&test_lock);
00246    lock_count -= 10;
00247    if (lock_count != 10) 
00248       test_errors++;
00249    ast_mutex_unlock(&test_lock);
00250    lock_count -= 10;
00251    ast_mutex_unlock(&test_lock2);
00252    if (lock_count != 0) 
00253       test_errors++;
00254    return NULL;
00255 } 

static struct timeval tvfix ( struct timeval  a  )  [static, read]

Definition at line 625 of file utils.c.

References ast_log(), LOG_WARNING, and ONE_MILLION.

Referenced by ast_tvadd(), and ast_tvsub().

00626 {
00627    if (a.tv_usec >= ONE_MILLION) {
00628       ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
00629          a.tv_sec, (long int) a.tv_usec);
00630       a.tv_sec += a.tv_usec / ONE_MILLION;
00631       a.tv_usec %= ONE_MILLION;
00632    } else if (a.tv_usec < 0) {
00633       ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
00634          a.tv_sec, (long int) a.tv_usec);
00635       a.tv_usec = 0;
00636    }
00637    return a;
00638 }

static char* upper ( const char *  orig,
char *  buf,
int  bufsize 
) [static]

Definition at line 670 of file utils.c.

Referenced by strcasestr().

00671 {
00672    int i = 0;
00673 
00674    while (i < (bufsize - 1) && orig[i]) {
00675       buf[i] = toupper(orig[i]);
00676       i++;
00677    }
00678 
00679    buf[i] = '\0';
00680 
00681    return buf;
00682 }

int vasprintf ( char **  strp,
const char *  fmt,
va_list  ap 
)

Definition at line 739 of file utils.c.

References malloc, and s.

00740 {
00741    int size;
00742    va_list ap2;
00743    char s;
00744 
00745    *strp = NULL;
00746    va_copy(ap2, ap);
00747    size = vsnprintf(&s, 1, fmt, ap2);
00748    va_end(ap2);
00749    *strp = malloc(size + 1);
00750    if (!*strp)
00751       return -1;
00752    vsnprintf(*strp, size + 1, fmt, ap);
00753 
00754    return size;
00755 }


Variable Documentation

char b2a[256] [static]

Definition at line 62 of file utils.c.

char base64[64] [static]

Definition at line 61 of file utils.c.

int lock_count = 0 [static]

Definition at line 228 of file utils.c.

int test_errors = 0 [static]

Definition at line 229 of file utils.c.

pthread_t test_thread [static]

Definition at line 227 of file utils.c.


Generated on Wed Oct 28 15:49:23 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6