Sat Mar 24 23:30:36 2007

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/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 LONG_MAX   9223372036854775807L
#define LONG_MIN   (-9223372036854775807L-1L)
#define ONE_MILLION   1000000

Functions

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.
int ast_false (const char *s)
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 (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)
char * ast_strip_quoted (char *s, const char *beg_quotes, const char *end_quotes)
int ast_true (const char *s)
timeval ast_tvadd (struct timeval a, struct timeval b)
timeval ast_tvsub (struct timeval a, struct timeval b)
 Returns the difference of two timevals a - b.
void ast_uri_decode (char *s)
 Decode URI, URN, URL (overwrite string).
char * ast_uri_encode (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)
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 55 of file utils.c.

#define AST_API_MODULE
 

Definition at line 55 of file utils.c.

#define AST_API_MODULE
 

Definition at line 55 of file utils.c.

#define LONG_MAX   9223372036854775807L
 

Definition at line 750 of file utils.c.

Referenced by strtoq().

#define LONG_MIN   (-9223372036854775807L-1L)
 

Definition at line 746 of file utils.c.

Referenced by strtoq().

#define ONE_MILLION   1000000
 

Definition at line 606 of file utils.c.

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


Function Documentation

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

Definition at line 297 of file utils.c.

References MD5Context::bits.

Referenced by __ast_check_signature(), and ast_osp_validate().

00298 {
00299    int cnt = 0;
00300    unsigned int byte = 0;
00301    unsigned int bits = 0;
00302    int incnt = 0;
00303 #if 0
00304    unsigned char *odst = dst;
00305 #endif
00306    while(*src && (cnt < max)) {
00307       /* Shift in 6 bits of input */
00308       byte <<= 6;
00309       byte |= (b2a[(int)(*src)]) & 0x3f;
00310       bits += 6;
00311 #if 0
00312       printf("Add: %c %s\n", *src, binary(b2a[(int)(*src)] & 0x3f, 6));
00313 #endif
00314       src++;
00315       incnt++;
00316       /* If we have at least 8 bits left over, take that character 
00317          off the top */
00318       if (bits >= 8)  {
00319          bits -= 8;
00320          *dst = (byte >> bits) & 0xff;
00321 #if 0
00322          printf("Remove: %02x %s\n", *dst, binary(*dst, 8));
00323 #endif
00324          dst++;
00325          cnt++;
00326       }
00327    }
00328 #if 0
00329    dump(odst, cnt);
00330 #endif
00331    /* Dont worry about left over bits, they're extra anyway */
00332    return cnt;
00333 }

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

Definition at line 335 of file utils.c.

References MD5Context::bits.

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

00336 {
00337    int cnt = 0;
00338    unsigned int byte = 0;
00339    int bits = 0;
00340    int index;
00341    int cntin = 0;
00342 #if 0
00343    char *odst = dst;
00344    dump(src, srclen);
00345 #endif
00346    /* Reserve one bit for end */
00347    max--;
00348    while((cntin < srclen) && (cnt < max)) {
00349       byte <<= 8;
00350 #if 0
00351       printf("Add: %02x %s\n", *src, binary(*src, 8));
00352 #endif
00353       byte |= *(src++);
00354       bits += 8;
00355       cntin++;
00356       while((bits >= 6) && (cnt < max)) {
00357          bits -= 6;
00358          /* We want only the top */
00359          index = (byte >> bits) & 0x3f;
00360          *dst = base64[index];
00361 #if 0
00362          printf("Remove: %c %s\n", *dst, binary(index, 6));
00363 #endif
00364          dst++;
00365          cnt++;
00366       }
00367    }
00368    if (bits && (cnt < max)) {
00369       /* Add one last character for the remaining bits, 
00370          padding the rest with 0 */
00371       byte <<= (6 - bits);
00372       index = (byte) & 0x3f;
00373       *(dst++) = base64[index];
00374       cnt++;
00375    }
00376    *dst = '\0';
00377    return cnt;
00378 }

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

Definition at line 560 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(), manager_event(), pbx_builtin_serialize_variables(), skinny_call(), transmit_notify_with_mwi(), and transmit_state_notify().

00561 {
00562    va_list ap;
00563    int result;
00564 
00565    va_start(ap, fmt);
00566    result = ast_build_string_va(buffer, space, fmt, ap);
00567    va_end(ap);
00568 
00569    return result;
00570 }

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

Referenced by ast_build_string(), and manager_event().

00542 {
00543    int result;
00544 
00545    if (!buffer || !*buffer || !space || !*space)
00546       return -1;
00547 
00548    result = vsnprintf(*buffer, *space, fmt, ap);
00549 
00550    if (result < 0)
00551       return -1;
00552    else if (result > *space)
00553       result = *space;
00554 
00555    *buffer += result;
00556    *space -= result;
00557    return 0;
00558 }

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

References ast_strlen_zero().

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

00590 {
00591    if (ast_strlen_zero(s))
00592       return 0;
00593 
00594    /* Determine if this is a false value */
00595    if (!strcasecmp(s, "no") ||
00596        !strcasecmp(s, "false") ||
00597        !strcasecmp(s, "n") ||
00598        !strcasecmp(s, "f") ||
00599        !strcasecmp(s, "0") ||
00600        !strcasecmp(s, "off"))
00601       return -1;
00602 
00603    return 0;
00604 }

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

References 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(), refresh_list(), reload_config(), rtp_do_debug_ip(), set_config(), set_destination(), sip_devicestate(), and sip_do_debug_ip().

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

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 472 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_raw_write(), ast_rtp_read(), ast_rtp_sendcng(), ast_rtp_senddigit(), ast_sip_ouraddrfor(), attempt_transmit(), authenticate(), build_contact(), build_reply_digest(), build_rpid(), build_via(), 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_trans(), dundi_showframe(), dundi_xmit(), external_rtp_create(), find_command(), find_peer(), find_subchannel_and_lock(), find_tpeer(), find_user(), function_iaxpeer(), function_sipchaninfo_read(), function_sippeer(), handle_command_response(), handle_error(), handle_request(), handle_request_bye(), handle_request_register(), handle_response(), handle_showmanconn(), iax2_ack_registry(), iax2_prov_app(), iax2_show_channels(), iax2_show_peer(), iax2_show_registry(), iax2_trunk_queue(), iax_server(), iax_showframe(), load_module(), mgcp_show_endpoints(), mgcpsock_read(), oh323_call(), oh323_set_rtp_peer(), parse_register_contact(), process_message(), process_rfc3389(), process_sdp(), raw_hangup(), realtime_peer(), realtime_update_peer(), reg_source_db(), register_verify(), registry_rerequest(), reload_config(), resend_response(), retrans_pkt(), rtp_do_debug_ip(), send_dtmf(), send_packet(), send_request(), send_response(), send_trunk(), set_config(), set_destination(), 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().

00473 {
00474    return inet_ntop(AF_INET, &ia, buf, bufsiz);
00475 }

void ast_md5_hash char *  output,
char *  input
 

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

Definition at line 282 of file utils.c.

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

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

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

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

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

00882 {
00883    char *dataPut = start;
00884    int inEscape = 0;
00885    int inQuotes = 0;
00886 
00887    for (; *start; start++) {
00888       if (inEscape) {
00889          *dataPut++ = *start;       /* Always goes verbatim */
00890          inEscape = 0;
00891          } else {
00892          if (*start == '\\') {
00893             inEscape = 1;      /* Do not copy \ into the data */
00894          } else if (*start == '\'') {
00895             inQuotes = 1-inQuotes;   /* Do not copy ' into the data */
00896          } else {
00897             /* Replace , with |, unless in quotes */
00898             *dataPut++ = inQuotes ? *start : ((*start==find) ? replace_with : *start);
00899          }
00900       }
00901    }
00902    if (start != dataPut)
00903       *dataPut = 0;
00904    return dataPut;
00905 }

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

Definition at line 487 of file utils.c.

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

00488 {
00489    pthread_attr_t lattr;
00490    if (!attr) {
00491       pthread_attr_init(&lattr);
00492       attr = &lattr;
00493    }
00494 #ifdef __linux__
00495    /* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
00496       which is kind of useless. Change this here to
00497       PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
00498       priority will propagate down to new threads by default.
00499       This does mean that callers cannot set a different priority using
00500       PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
00501       the priority afterwards with pthread_setschedparam(). */
00502    errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED);
00503    if (errno)
00504       ast_log(LOG_WARNING, "pthread_attr_setinheritsched returned non-zero: %s\n", strerror(errno));
00505 #endif
00506 
00507    if (!stacksize)
00508       stacksize = AST_STACKSIZE;
00509    errno = pthread_attr_setstacksize(attr, stacksize);
00510    if (errno)
00511       ast_log(LOG_WARNING, "pthread_attr_setstacksize returned non-zero: %s\n", strerror(errno));
00512    return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
00513 }

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

Definition at line 524 of file utils.c.

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

00525 {
00526    char *e;
00527    char *q;
00528 
00529    s = ast_strip(s);
00530    if ((q = strchr(beg_quotes, *s))) {
00531       e = s + strlen(s) - 1;
00532       if (*e == *(end_quotes + (q - beg_quotes))) {
00533          s++;
00534          *e = '\0';
00535       }
00536    }
00537 
00538    return s;
00539 }

int ast_true const char *  val  ) 
 

Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".

Returns 0 if val is a NULL pointer, -1 if "true", and 0 otherwise.

Definition at line 572 of file utils.c.

References ast_strlen_zero().

Referenced by __load_resource(), __login_exec(), 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(), builtin_function_if(), config_load(), dial_exec_full(), do_reload(), execif_exec(), festival_exec(), function_ilink(), get_encrypt_methods(), handle_common_options(), init_logger_chain(), init_manager(), load_config(), load_module(), load_moh_classes(), loadconfigurationfile(), macroif_exec(), 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(), start_monitor_action(), and update_common_options().

00573 {
00574    if (ast_strlen_zero(s))
00575       return 0;
00576 
00577    /* Determine if this is a true value */
00578    if (!strcasecmp(s, "yes") ||
00579        !strcasecmp(s, "true") ||
00580        !strcasecmp(s, "y") ||
00581        !strcasecmp(s, "t") ||
00582        !strcasecmp(s, "1") ||
00583        !strcasecmp(s, "on"))
00584       return -1;
00585 
00586    return 0;
00587 }

struct timeval ast_tvadd struct timeval  a,
struct timeval  b
 

Definition at line 626 of file utils.c.

References ONE_MILLION, and tvfix().

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

00627 {
00628    /* consistency checks to guarantee usec in 0..999999 */
00629    a = tvfix(a);
00630    b = tvfix(b);
00631    a.tv_sec += b.tv_sec;
00632    a.tv_usec += b.tv_usec;
00633    if (a.tv_usec >= ONE_MILLION) {
00634       a.tv_sec++;
00635       a.tv_usec -= ONE_MILLION;
00636    }
00637    return a;
00638 }

struct timeval ast_tvsub struct timeval  a,
struct timeval  b
 

Returns the difference of two timevals a - b.

Definition at line 640 of file utils.c.

References ONE_MILLION, and tvfix().

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

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 < 0) {
00648       a.tv_sec-- ;
00649       a.tv_usec += ONE_MILLION;
00650    }
00651    return a;
00652 }

void ast_uri_decode char *  s  ) 
 

Decode URI, URN, URL (overwrite string).

Parameters:
s String to be decoded

Definition at line 455 of file utils.c.

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

00456 {
00457    char *o;
00458    unsigned int tmp;
00459 
00460    for (o = s; *s; s++, o++) {
00461       if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
00462          /* have '%', two chars and correct parsing */
00463          *o = tmp;
00464          s += 2;  /* Will be incremented once more when we break out */
00465       } else /* all other cases, just copy */
00466          *o = *s;
00467    }
00468    *o = '\0';
00469 }

char* ast_uri_encode 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.

ast_uri_encode

Parameters:
string String to be converted
outbuf Resulting encoded string
buflen Size of output buffer
doreserved Convert reserved characters

Definition at line 424 of file utils.c.

Referenced by builtin_function_uriencode().

00425 {
00426    char *reserved = ";/?:@&=+$, ";  /* Reserved chars */
00427 
00428    char *ptr  = string; /* Start with the string */
00429    char *out = NULL;
00430    char *buf = NULL;
00431 
00432    strncpy(outbuf, string, buflen);
00433 
00434    /* If there's no characters to convert, just go through and don't do anything */
00435    while (*ptr) {
00436       if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
00437          /* Oops, we need to start working here */
00438          if (!buf) {
00439             buf = outbuf;
00440             out = buf + (ptr - string) ;  /* Set output ptr */
00441          }
00442          out += sprintf(out, "%%%02x", (unsigned char) *ptr);
00443       } else if (buf) {
00444          *out = *ptr;   /* Continue copying the string */
00445          out++;
00446       } 
00447       ptr++;
00448    }
00449    if (buf)
00450       *out = '\0';
00451    return outbuf;
00452 }

int ast_utils_init void   ) 
 

Definition at line 477 of file utils.c.

References base64_init().

00478 {
00479    base64_init();
00480    return 0;
00481 }

int ast_wait_for_input int  fd,
int  ms
 

Definition at line 515 of file utils.c.

References poll(), POLLIN, and POLLPRI.

Referenced by ast_moh_destroy().

00516 {
00517    struct pollfd pfd[1];
00518    memset(pfd, 0, sizeof(pfd));
00519    pfd[0].fd = fd;
00520    pfd[0].events = POLLIN|POLLPRI;
00521    return poll(pfd, 1, ms);
00522 }

static void base64_init void   )  [static]
 

Definition at line 380 of file utils.c.

Referenced by ast_utils_init().

00381 {
00382    int x;
00383    memset(b2a, -1, sizeof(b2a));
00384    /* Initialize base-64 Conversion table */
00385    for (x=0;x<26;x++) {
00386       /* A-Z */
00387       base64[x] = 'A' + x;
00388       b2a['A' + x] = x;
00389       /* a-z */
00390       base64[x + 26] = 'a' + x;
00391       b2a['a' + x] = x + 26;
00392       /* 0-9 */
00393       if (x < 10) {
00394          base64[x + 52] = '0' + x;
00395          b2a['0' + x] = x + 52;
00396       }
00397    }
00398    base64[62] = '+';
00399    base64[63] = '/';
00400    b2a[(int)'+'] = 62;
00401    b2a[(int)'/'] = 63;
00402 #if 0
00403    for (x=0;x<64;x++) {
00404       if (b2a[(int)base64[x]] != x) {
00405          fprintf(stderr, "!!! %d failed\n", x);
00406       } else
00407          fprintf(stderr, "--- %d passed\n", x);
00408    }
00409 #endif
00410 }

int getloadavg double *  list,
int  nelem
 

Definition at line 869 of file utils.c.

Referenced by ast_readconfig(), and increase_call_count().

00870 {
00871    int i;
00872 
00873    for (i = 0; i < nelem; i++) {
00874       list[i] = 0.1;
00875    }
00876    return -1;
00877 }

char* strcasestr const char *  haystack,
const char *  needle
 

Definition at line 670 of file utils.c.

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

Referenced by do_directory(), gettag(), handle_show_applications(), modlist_modentry(), parse_register_contact(), playback_exec(), reqprep(), and respprep().

00671 {
00672    char *u1, *u2;
00673    int u1len = strlen(haystack) + 1, u2len = strlen(needle) + 1;
00674 
00675    u1 = alloca(u1len);
00676    u2 = alloca(u2len);
00677    if (u1 && u2) {
00678       char *offset;
00679       if (u2len > u1len) {
00680          /* Needle bigger than haystack */
00681          return NULL;
00682       }
00683       offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
00684       if (offset) {
00685          /* Return the offset into the original string */
00686          return ((char *)((unsigned long)haystack + (unsigned long)(offset - u1)));
00687       } else {
00688          return NULL;
00689       }
00690    } else {
00691       ast_log(LOG_ERROR, "Out of memory\n");
00692       return NULL;
00693    }
00694 }

char* strndup const char *  s,
size_t  n
 

Definition at line 711 of file utils.c.

References malloc, and strnlen().

00712 {
00713    size_t len = strnlen(s, n);
00714    char *new = malloc(len + 1);
00715 
00716    if (!new)
00717       return NULL;
00718 
00719    new[len] = '\0';
00720    return memcpy(new, s, len);
00721 }

size_t strnlen const char *  s,
size_t  n
 

Definition at line 698 of file utils.c.

Referenced by strndup().

00699 {
00700    size_t len;
00701 
00702    for (len=0; len < n; len++)
00703       if (s[len] == '\0')
00704          break;
00705 
00706    return len;
00707 }

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

Definition at line 760 of file utils.c.

References LONG_MAX, LONG_MIN, and s.

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

int test_for_thread_safety void   ) 
 

Definition at line 253 of file utils.c.

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

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

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

References ast_mutex_lock(), and ast_mutex_unlock().

Referenced by test_for_thread_safety().

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

static struct timeval tvfix struct timeval  a  )  [static]
 

Definition at line 611 of file utils.c.

References ast_log(), LOG_WARNING, and ONE_MILLION.

Referenced by ast_tvadd(), and ast_tvsub().

00612 {
00613    if (a.tv_usec >= ONE_MILLION) {
00614       ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
00615          a.tv_sec, (long int) a.tv_usec);
00616       a.tv_sec += a.tv_usec / ONE_MILLION;
00617       a.tv_usec %= ONE_MILLION;
00618    } else if (a.tv_usec < 0) {
00619       ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
00620          a.tv_sec, (long int) a.tv_usec);
00621       a.tv_usec = 0;
00622    }
00623    return a;
00624 }

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

Definition at line 656 of file utils.c.

Referenced by strcasestr().

00657 {
00658    int i = 0;
00659 
00660    while (i < (bufsize - 1) && orig[i]) {
00661       buf[i] = toupper(orig[i]);
00662       i++;
00663    }
00664 
00665    buf[i] = '\0';
00666 
00667    return buf;
00668 }

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

Definition at line 725 of file utils.c.

References malloc, and s.

00726 {
00727    int size;
00728    va_list ap2;
00729    char s;
00730 
00731    *strp = NULL;
00732    va_copy(ap2, ap);
00733    size = vsnprintf(&s, 1, fmt, ap2);
00734    va_end(ap2);
00735    *strp = malloc(size + 1);
00736    if (!*strp)
00737       return -1;
00738    vsnprintf(*strp, size + 1, fmt, ap);
00739 
00740    return size;
00741 }


Variable Documentation

char b2a[256] [static]
 

Definition at line 59 of file utils.c.

char base64[64] [static]
 

Definition at line 58 of file utils.c.

int lock_count = 0 [static]
 

Definition at line 224 of file utils.c.

int test_errors = 0 [static]
 

Definition at line 225 of file utils.c.

pthread_t test_thread [static]
 

Definition at line 223 of file utils.c.


Generated on Sat Mar 24 23:30:36 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.6