Sat Nov 1 06:31:15 2008

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

#define AST_API_MODULE

Definition at line 57 of file utils.c.

#define AST_API_MODULE

Definition at line 57 of file utils.c.

#define AST_API_MODULE

Definition at line 57 of file utils.c.

#define LONG_MAX   9223372036854775807L

Definition at line 745 of file utils.c.

Referenced by strtoq().

#define LONG_MIN   (-9223372036854775807L-1L)

Definition at line 741 of file utils.c.

Referenced by strtoq().

#define ONE_MILLION   1000000

Definition at line 601 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 914 of file utils.c.

References ast_mutex_lock(), and ast_mutex_unlock().

00915 {
00916         int ret;
00917         ast_mutex_lock(&fetchadd_m);
00918         ret = *p;
00919         *p += v;
00920         ast_mutex_unlock(&fetchadd_m);
00921         return ret;
00922 }

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

Definition at line 300 of file utils.c.

References MD5Context::bits.

Referenced by __ast_check_signature(), and ast_osp_validate().

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

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

Definition at line 338 of file utils.c.

References MD5Context::bits.

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

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

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

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

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

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

Referenced by ast_build_string(), and manager_event().

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

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

References ast_log(), and LOG_WARNING.

Referenced by ast_netsock_bindaddr(), and reload_config().

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

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

References ast_strlen_zero().

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

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

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

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

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 467 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_callid(), 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_callno(), 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_message(), 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(), initreqprep(), 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(), realtime_user(), reg_source_db(), register_verify(), registry_rerequest(), reload_config(), resend_response(), retrans_pkt(), rpt_exec(), 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().

00468 {
00469    return inet_ntop(AF_INET, &ia, buf, bufsiz);
00470 }

void ast_md5_hash ( char *  output,
char *  input 
)

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

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

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

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

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

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

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

Definition at line 482 of file utils.c.

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

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

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

Definition at line 519 of file utils.c.

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

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

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

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

struct timeval ast_tvadd ( struct timeval  a,
struct timeval  b 
)

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

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

struct timeval ast_tvsub ( struct timeval  a,
struct timeval  b 
)

Returns the difference of two timevals a - b.

Definition at line 635 of file utils.c.

References ONE_MILLION, and tvfix().

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

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

void ast_uri_decode ( char *  s  ) 

Decode URI, URN, URL (overwrite string).

Parameters:
s String to be decoded

Definition at line 450 of file utils.c.

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

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

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

Referenced by builtin_function_uriencode(), and initreqprep().

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

int ast_utils_init ( void   ) 

Definition at line 472 of file utils.c.

References base64_init().

Referenced by main().

00473 {
00474    base64_init();
00475    return 0;
00476 }

int ast_wait_for_input ( int  fd,
int  ms 
)

Definition at line 510 of file utils.c.

References poll(), POLLIN, and POLLPRI.

Referenced by ast_moh_destroy().

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

static void base64_init ( void   )  [static]

Definition at line 383 of file utils.c.

Referenced by ast_utils_init().

00384 {
00385    int x;
00386    memset(b2a, -1, sizeof(b2a));
00387    /* Initialize base-64 Conversion table */
00388    for (x=0;x<26;x++) {
00389       /* A-Z */
00390       base64[x] = 'A' + x;
00391       b2a['A' + x] = x;
00392       /* a-z */
00393       base64[x + 26] = 'a' + x;
00394       b2a['a' + x] = x + 26;
00395       /* 0-9 */
00396       if (x < 10) {
00397          base64[x + 52] = '0' + x;
00398          b2a['0' + x] = x + 52;
00399       }
00400    }
00401    base64[62] = '+';
00402    base64[63] = '/';
00403    b2a[(int)'+'] = 62;
00404    b2a[(int)'/'] = 63;
00405 }

int getloadavg ( double *  list,
int  nelem 
)

Definition at line 864 of file utils.c.

Referenced by ast_readconfig(), and increase_call_count().

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

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

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

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

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

Definition at line 706 of file utils.c.

References malloc, and strnlen().

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

size_t strnlen ( const char *  s,
size_t  n 
)

Definition at line 693 of file utils.c.

Referenced by strndup().

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

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

Definition at line 755 of file utils.c.

References LONG_MAX, LONG_MIN, and s.

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

int test_for_thread_safety ( void   ) 

Definition at line 256 of file utils.c.

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

Referenced by