Sat Nov 25 00:46:14 2006

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"

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.
void ast_enable_packet_fragmentation (int sock)
 Disable PMTU discovery on a socket.
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 742 of file utils.c.

Referenced by strtoq().

#define LONG_MIN   (-9223372036854775807L-1L)
 

Definition at line 738 of file utils.c.

Referenced by strtoq().

#define ONE_MILLION   1000000
 

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

00553 {
00554    va_list ap;
00555    int result;
00556 
00557    va_start(ap, fmt);
00558    result = ast_build_string_va(buffer, space, fmt, ap);
00559    va_end(ap);
00560 
00561    return result;
00562 }

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

Referenced by ast_build_string(), and manager_event().

00534 {
00535    int result;
00536 
00537    if (!buffer || !*buffer || !space || !*space)
00538       return -1;
00539 
00540    result = vsnprintf(*buffer, *space, fmt, ap);
00541 
00542    if (result < 0)
00543       return -1;
00544    else if (result > *space)
00545       result = *space;
00546 
00547    *buffer += result;
00548    *space -= result;
00549    return 0;
00550 }

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

References ast_log(), and LOG_WARNING.

Referenced by ast_netsock_bindaddr(), and reload_config().

00900 {
00901 #ifdef __linux__
00902    int val = IP_PMTUDISC_DONT;
00903    
00904    if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
00905       ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
00906 #endif
00907 }

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

References ast_strlen_zero().

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

00582 {
00583    if (ast_strlen_zero(s))
00584       return 0;
00585 
00586    /* Determine if this is a false value */
00587    if (!strcasecmp(s, "no") ||
00588        !strcasecmp(s, "false") ||
00589        !strcasecmp(s, "n") ||
00590        !strcasecmp(s, "f") ||
00591        !strcasecmp(s, "0") ||
00592        !strcasecmp(s, "off"))
00593       return -1;
00594 
00595    return 0;
00596 }

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 464 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_request_subscribe(), 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().

00465 {
00466    return inet_ntop(AF_INET, &ia, buf, bufsiz);
00467 }

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

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

00874 {
00875    char *dataPut = start;
00876    int inEscape = 0;
00877    int inQuotes = 0;
00878 
00879    for (; *start; start++) {
00880       if (inEscape) {
00881          *dataPut++ = *start;       /* Always goes verbatim */
00882          inEscape = 0;
00883          } else {
00884          if (*start == '\\') {
00885             inEscape = 1;      /* Do not copy \ into the data */
00886          } else if (*start == '\'') {
00887             inQuotes = 1-inQuotes;   /* Do not copy ' into the data */
00888          } else {
00889             /* Replace , with |, unless in quotes */
00890             *dataPut++ = inQuotes ? *start : ((*start==find) ? replace_with : *start);
00891          }
00892       }
00893    }
00894    if (start != dataPut)
00895       *dataPut = 0;
00896    return dataPut;
00897 }

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

Definition at line 479 of file utils.c.

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

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

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

Definition at line 516 of file utils.c.

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

00517 {
00518    char *e;
00519    char *q;
00520 
00521    s = ast_strip(s);
00522    if ((q = strchr(beg_quotes, *s))) {
00523       e = s + strlen(s) - 1;
00524       if (*e == *(end_quotes + (q - beg_quotes))) {
00525          s++;
00526          *e = '\0';
00527       }
00528    }
00529 
00530    return s;
00531 }

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 564 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_moh_classes(), 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(), start_monitor_action(), and update_common_options().

00565 {
00566    if (ast_strlen_zero(s))
00567       return 0;
00568 
00569    /* Determine if this is a true value */
00570    if (!strcasecmp(s, "yes") ||
00571        !strcasecmp(s, "true") ||
00572        !strcasecmp(s, "y") ||
00573        !strcasecmp(s, "t") ||
00574        !strcasecmp(s, "1") ||
00575        !strcasecmp(s, "on"))
00576       return -1;
00577 
00578    return 0;
00579 }

struct timeval ast_tvadd struct timeval  a,
struct timeval  b
 

Definition at line 618 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(), sched_settime(), and schedule_delivery().

00619 {
00620    /* consistency checks to guarantee usec in 0..999999 */
00621    a = tvfix(a);
00622    b = tvfix(b);
00623    a.tv_sec += b.tv_sec;
00624    a.tv_usec += b.tv_usec;
00625    if (a.tv_usec >= ONE_MILLION) {
00626       a.tv_sec++;
00627       a.tv_usec -= ONE_MILLION;
00628    }
00629    return a;
00630 }

struct timeval ast_tvsub struct timeval  a,
struct timeval  b
 

Returns the difference of two timevals a - b.

Definition at line 632 of file utils.c.

References ONE_MILLION, and tvfix().

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

00633 {
00634    /* consistency checks to guarantee usec in 0..999999 */
00635    a = tvfix(a);
00636    b = tvfix(b);
00637    a.tv_sec -= b.tv_sec;
00638    a.tv_usec -= b.tv_usec;
00639    if (a.tv_usec < 0) {
00640       a.tv_sec-- ;
00641       a.tv_usec += ONE_MILLION;
00642    }
00643    return a;
00644 }

void ast_uri_decode char *  s  ) 
 

Decode URI, URN, URL (overwrite string).

Parameters:
s String to be decoded

Definition at line 447 of file utils.c.

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

00448 {
00449    char *o;
00450    unsigned int tmp;
00451 
00452    for (o = s; *s; s++, o++) {
00453       if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
00454          /* have '%', two chars and correct parsing */
00455          *o = tmp;
00456          s += 2;  /* Will be incremented once more when we break out */
00457       } else /* all other cases, just copy */
00458          *o = *s;
00459    }
00460    *o = '\0';
00461 }

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

Referenced by builtin_function_uriencode().

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

int ast_utils_init void   ) 
 

Definition at line 469 of file utils.c.

References base64_init().

00470 {
00471    base64_init();
00472    return 0;
00473 }

int ast_wait_for_input int  fd,
int  ms
 

Definition at line 507 of file utils.c.

References poll(), POLLIN, and POLLPRI.

Referenced by ast_moh_destroy().

00508 {
00509    struct pollfd pfd[1];
00510    memset(pfd, 0, sizeof(pfd));
00511    pfd[0].fd = fd;
00512    pfd[0].events = POLLIN|POLLPRI;
00513    return poll(pfd, 1, ms);
00514 }

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 }

int getloadavg double *  list,
int  nelem
 

Definition at line 861 of file utils.c.

Referenced by ast_readconfig(), and increase_call_count().

00862 {
00863    int i;
00864 
00865    for (i = 0; i < nelem; i++) {
00866       list[i] = 0.1;
00867    }
00868    return -1;
00869 }

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

Definition at line 662 of file utils.c.

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

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

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

char* strndup const char *  s,
size_t  n
 

Definition at line 703 of file utils.c.

References malloc, and strnlen().

00704 {
00705    size_t len = strnlen(s, n);
00706    char *new = malloc(len + 1);
00707 
00708    if (!new)
00709       return NULL;
00710 
00711    new[len] = '\0';
00712    return memcpy(new, s, len);
00713 }

size_t strnlen const char *  s,
size_t  n
 

Definition at line 690 of file utils.c.

Referenced by strndup().

00691 {
00692    size_t len;
00693 
00694    for (len=0; len < n; len++)
00695       if (s[len] == '\0')
00696          break;
00697 
00698    return len;
00699 }

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

Definition at line 752 of file utils.c.

References LONG_MAX, LONG_MIN, and s.

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

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

References ast_log(), LOG_WARNING, and ONE_MILLION.

Referenced by ast_tvadd(), and ast_tvsub().

00604 {
00605    if (a.tv_usec >= ONE_MILLION) {
00606       ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
00607          a.tv_sec, (long int) a.tv_usec);
00608       a.tv_sec += a.tv_usec / ONE_MILLION;
00609       a.tv_usec %= ONE_MILLION;
00610    } else if (a.tv_usec < 0) {
00611       ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
00612          a.tv_sec, (long int) a.tv_usec);
00613       a.tv_usec = 0;
00614    }
00615    return a;
00616 }

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

Definition at line 648 of file utils.c.

Referenced by strcasestr().

00649 {
00650    int i = 0;
00651 
00652    while (i < (bufsize - 1) && orig[i]) {
00653       buf[i] = toupper(orig[i]);
00654       i++;
00655    }
00656 
00657    buf[i] = '\0';
00658 
00659    return buf;
00660 }

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

Definition at line 717 of file utils.c.

References malloc, and s.

00718 {
00719    int size;
00720    va_list ap2;
00721    char s;
00722 
00723    *strp = NULL;
00724    va_copy(ap2, ap);
00725    size = vsnprintf(&s, 1, fmt, ap2);
00726    va_end(ap2);
00727    *strp = malloc(size + 1);
00728    if (!*strp)
00729       return -1;
00730    vsnprintf(*strp, size + 1, fmt, ap);
00731 
00732    return size;
00733 }


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 Nov 25 00:46:14 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.6