2004-05-03 04:31:11 +00:00
/*
2005-08-30 18:32:10 +00:00
* Asterisk - - An open source telephony toolkit .
2004-05-03 04:31:11 +00:00
*
2006-01-04 21:54:09 +00:00
* Copyright ( C ) 1999 - 2006 , Digium , Inc .
2005-08-30 18:32:10 +00:00
*
* Mark Spencer < markster @ digium . com >
2004-05-03 04:31:11 +00:00
*
2005-08-30 18:32:10 +00:00
* See http : //www.asterisk.org for more information about
* the Asterisk project . Please do not directly contact
* any of the maintainers of this project for assistance ;
* the project provides a web site , mailing lists and IRC
* channels for your use .
2004-05-03 04:31:11 +00:00
*
* This program is free software , distributed under the terms of
2005-08-30 18:32:10 +00:00
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree .
*/
2005-10-24 20:12:06 +00:00
/*! \file
* \ brief Utility functions
2004-05-03 04:31:11 +00:00
*/
2005-05-02 00:27:54 +00:00
# ifndef _ASTERISK_UTILS_H
# define _ASTERISK_UTILS_H
2004-05-03 04:31:11 +00:00
2005-09-08 02:19:02 +00:00
# include "asterisk/compat.h"
2005-05-02 00:27:54 +00:00
2006-01-10 23:51:42 +00:00
# include <stdlib.h>
2004-08-08 17:15:02 +00:00
# include <netinet/in.h>
2005-06-07 17:06:33 +00:00
# include <arpa/inet.h> /* we want to override inet_ntoa */
2004-05-09 08:22:15 +00:00
# include <netdb.h>
2004-12-23 11:32:22 +00:00
# include <limits.h>
2004-05-09 08:22:15 +00:00
2005-05-02 00:27:54 +00:00
# include "asterisk/lock.h"
2005-06-24 22:45:15 +00:00
# include "asterisk/time.h"
# include "asterisk/strings.h"
2006-01-10 23:51:42 +00:00
# include "asterisk/logger.h"
2005-05-02 00:27:54 +00:00
2005-10-24 20:12:06 +00:00
/*! \note
\ verbatim
Note :
2005-01-08 19:00:46 +00:00
It is very important to use only unsigned variables to hold
bit flags , as otherwise you can fall prey to the compiler ' s
sign - extension antics if you try to use the top two bits in
your variable .
2004-12-16 03:15:20 +00:00
2005-01-08 19:00:46 +00:00
The flag macros below use a set of compiler tricks to verify
that the caller is using an " unsigned int " variable to hold
the flags , and nothing else . If the caller uses any other
type of variable , a warning message similar to this :
2004-12-16 03:15:20 +00:00
2005-01-08 19:00:46 +00:00
warning : comparison of distinct pointer types lacks cast
will be generated .
2004-12-16 03:15:20 +00:00
2005-01-08 19:00:46 +00:00
The " dummy " variable below is used to make these comparisons .
Also note that at - O2 or above , this type - safety checking
does _not_ produce any additional object code at all .
2005-10-24 20:12:06 +00:00
\ endverbatim
2005-01-08 19:00:46 +00:00
*/
extern unsigned int __unsigned_int_flags_dummy ;
# define ast_test_flag(p,flag) ({ \
typeof ( ( p ) - > flags ) __p = ( p ) - > flags ; \
typeof ( __unsigned_int_flags_dummy ) __x = 0 ; \
( void ) ( & __p = = & __x ) ; \
( ( p ) - > flags & ( flag ) ) ; \
} )
# define ast_set_flag(p,flag) do { \
typeof ( ( p ) - > flags ) __p = ( p ) - > flags ; \
typeof ( __unsigned_int_flags_dummy ) __x = 0 ; \
( void ) ( & __p = = & __x ) ; \
( ( p ) - > flags | = ( flag ) ) ; \
} while ( 0 )
# define ast_clear_flag(p,flag) do { \
typeof ( ( p ) - > flags ) __p = ( p ) - > flags ; \
typeof ( __unsigned_int_flags_dummy ) __x = 0 ; \
( void ) ( & __p = = & __x ) ; \
( ( p ) - > flags & = ~ ( flag ) ) ; \
} while ( 0 )
# define ast_copy_flags(dest,src,flagz) do { \
typeof ( ( dest ) - > flags ) __d = ( dest ) - > flags ; \
typeof ( ( src ) - > flags ) __s = ( src ) - > flags ; \
typeof ( __unsigned_int_flags_dummy ) __x = 0 ; \
( void ) ( & __d = = & __x ) ; \
( void ) ( & __s = = & __x ) ; \
( dest ) - > flags & = ~ ( flagz ) ; \
( dest ) - > flags | = ( ( src ) - > flags & ( flagz ) ) ; \
} while ( 0 )
# define ast_set2_flag(p,value,flag) do { \
typeof ( ( p ) - > flags ) __p = ( p ) - > flags ; \
typeof ( __unsigned_int_flags_dummy ) __x = 0 ; \
( void ) ( & __p = = & __x ) ; \
if ( value ) \
( p ) - > flags | = ( flag ) ; \
else \
( p ) - > flags & = ~ ( flag ) ; \
} while ( 0 )
2004-12-16 03:15:20 +00:00
2006-05-10 09:09:16 +00:00
# define ast_set_flags_to(p,flag,value) do { \
typeof ( ( p ) - > flags ) __p = ( p ) - > flags ; \
typeof ( __unsigned_int_flags_dummy ) __x = 0 ; \
( void ) ( & __p = = & __x ) ; \
( p ) - > flags & = ~ ( flag ) ; \
( p ) - > flags | = ( value ) ; \
} while ( 0 )
2005-01-10 14:46:59 +00:00
/* Non-type checking variations for non-unsigned int flags. You
should only use non - unsigned int flags where required by
protocol etc and if you know what you ' re doing : ) */
# define ast_test_flag_nonstd(p,flag) ({ \
( ( p ) - > flags & ( flag ) ) ; \
} )
# define ast_set_flag_nonstd(p,flag) do { \
( ( p ) - > flags | = ( flag ) ) ; \
} while ( 0 )
# define ast_clear_flag_nonstd(p,flag) do { \
( ( p ) - > flags & = ~ ( flag ) ) ; \
} while ( 0 )
# define ast_copy_flags_nonstd(dest,src,flagz) do { \
( dest ) - > flags & = ~ ( flagz ) ; \
( dest ) - > flags | = ( ( src ) - > flags & ( flagz ) ) ; \
} while ( 0 )
# define ast_set2_flag_nonstd(p,value,flag) do { \
if ( value ) \
( p ) - > flags | = ( flag ) ; \
else \
( p ) - > flags & = ~ ( flag ) ; \
} while ( 0 )
2004-12-23 11:32:22 +00:00
# define AST_FLAGS_ALL UINT_MAX
2005-01-08 19:00:46 +00:00
struct ast_flags {
unsigned int flags ;
} ;
2004-05-09 08:22:15 +00:00
struct ast_hostent {
struct hostent hp ;
char buf [ 1024 ] ;
} ;
2005-11-01 20:09:09 +00:00
struct hostent * ast_gethostbyname ( const char * host , struct ast_hostent * hp ) ;
2005-08-29 22:39:39 +00:00
2006-02-24 10:50:43 +00:00
/* ast_md5_hash
\ brief Produces MD5 hash based on input string */
2005-11-01 20:09:09 +00:00
void ast_md5_hash ( char * output , char * input ) ;
2006-02-03 22:37:29 +00:00
/* ast_sha1_hash
\ brief Produces SHA1 hash based on input string */
void ast_sha1_hash ( char * output , char * input ) ;
2005-08-29 22:39:39 +00:00
2005-11-01 20:09:09 +00:00
int ast_base64encode ( char * dst , const unsigned char * src , int srclen , int max ) ;
int ast_base64decode ( unsigned char * dst , const char * src , int max ) ;
2004-05-09 08:22:15 +00:00
2005-08-29 22:39:39 +00:00
/*! ast_uri_encode
\ brief 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 .
\ param string String to be converted
\ param outbuf Resulting encoded string
\ param buflen Size of output buffer
\ param doreserved Convert reserved characters
*/
2006-02-24 10:50:43 +00:00
2006-01-04 21:54:09 +00:00
char * ast_uri_encode ( const char * string , char * outbuf , int buflen , int doreserved ) ;
2005-08-29 22:39:39 +00:00
/*! \brief Decode URI, URN, URL (overwrite string)
\ param s String to be decoded
*/
void ast_uri_decode ( char * s ) ;
2005-10-28 21:35:55 +00:00
2005-11-01 20:09:09 +00:00
static force_inline void ast_slinear_saturated_add ( short * input , short * value )
2005-10-28 21:35:55 +00:00
{
int res ;
2005-10-31 18:15:02 +00:00
res = ( int ) * input + * value ;
2005-10-28 21:35:55 +00:00
if ( res > 32767 )
* input = 32767 ;
else if ( res < - 32767 )
* input = - 32767 ;
else
* input = ( short ) res ;
}
2005-08-29 22:39:39 +00:00
2005-11-01 20:09:09 +00:00
static force_inline void ast_slinear_saturated_multiply ( short * input , short * value )
2005-10-28 21:35:55 +00:00
{
int res ;
2005-10-31 18:15:02 +00:00
res = ( int ) * input * * value ;
2005-10-28 21:35:55 +00:00
if ( res > 32767 )
* input = 32767 ;
else if ( res < - 32767 )
* input = - 32767 ;
else
* input = ( short ) res ;
}
2005-11-01 20:09:09 +00:00
static force_inline void ast_slinear_saturated_divide ( short * input , short * value )
2005-10-28 21:35:55 +00:00
{
2005-10-31 18:15:02 +00:00
* input / = * value ;
2005-10-28 21:35:55 +00:00
}
2005-08-29 22:39:39 +00:00
2005-11-01 20:09:09 +00:00
int test_for_thread_safety ( void ) ;
2005-02-18 05:29:31 +00:00
2005-11-01 20:09:09 +00:00
const char * ast_inet_ntoa ( char * buf , int bufsiz , struct in_addr ia ) ;
2004-06-22 17:42:14 +00:00
2004-06-29 17:54:25 +00:00
# ifdef inet_ntoa
# undef inet_ntoa
# endif
2004-06-29 12:56:46 +00:00
# define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
2005-11-01 20:09:09 +00:00
int ast_utils_init ( void ) ;
int ast_wait_for_input ( int fd , int ms ) ;
2005-07-19 23:17:02 +00:00
2006-05-05 21:01:39 +00:00
/*! ast_carefulwrite
\ brief Try to write string , but wait no more than ms milliseconds
before timing out .
\ note If you are calling ast_carefulwrite , it is assumed that you are calling
it on a file descriptor that _DOES_ have NONBLOCK set . This way ,
there is only one system call made to do a write , unless we actually
have a need to wait . This way , we get better performance .
*/
int ast_carefulwrite ( int fd , char * s , int len , int timeoutms ) ;
2006-02-24 10:50:43 +00:00
/*! Compares the source address and port of two sockaddr_in */
2005-11-01 20:09:09 +00:00
static force_inline int inaddrcmp ( const struct sockaddr_in * sin1 , const struct sockaddr_in * sin2 )
2005-07-19 23:17:02 +00:00
{
return ( ( sin1 - > sin_addr . s_addr ! = sin2 - > sin_addr . s_addr )
| | ( sin1 - > sin_port ! = sin2 - > sin_port ) ) ;
}
2006-02-24 10:50:43 +00:00
# define AST_STACKSIZE 256 * 1024
2006-04-12 20:40:46 +00:00
void ast_register_thread ( char * name ) ;
void ast_unregister_thread ( void * id ) ;
# define ast_pthread_create(a,b,c,d) ast_pthread_create_stack(a,b,c,d,0, \
__FILE__ , __FUNCTION__ , __LINE__ , # c )
int ast_pthread_create_stack ( pthread_t * thread , pthread_attr_t * attr , void * ( * start_routine ) ( void * ) , void * data , size_t stacksize ,
const char * file , const char * caller , int line , const char * start_fn ) ;
2005-05-02 00:27:54 +00:00
2005-09-23 02:57:14 +00:00
/*!
\ brief Process a string to find and replace characters
\ param start The string to analyze
\ param find The character to find
\ param replace_with The character that will replace the one we are looking for
*/
char * ast_process_quotes_and_slashes ( char * start , char find , char replace_with ) ;
2005-11-08 04:13:19 +00:00
# ifndef HAVE_GETLOADAVG
int getloadavg ( double * list , int nelem ) ;
# endif
2006-01-10 00:55:45 +00:00
# ifdef linux
# define ast_random random
# else
long int ast_random ( void ) ;
# endif
2006-03-19 01:39:14 +00:00
# ifndef __AST_DEBUG_MALLOC
2006-01-10 23:51:42 +00:00
/*!
\ brief A wrapper for malloc ( )
ast_malloc ( ) is a wrapper for malloc ( ) that will generate an Asterisk log
message in the case that the allocation fails .
The argument and return value are the same as malloc ( )
*/
# define ast_malloc(len) \
2006-01-13 18:38:55 +00:00
_ast_malloc ( ( len ) , __FILE__ , __LINE__ , __PRETTY_FUNCTION__ )
2006-01-10 23:51:42 +00:00
AST_INLINE_API (
2006-04-19 22:32:07 +00:00
void * __attribute__ ( ( malloc ) ) _ast_malloc ( size_t len , const char * file , int lineno , const char * func ) ,
2006-01-10 23:51:42 +00:00
{
void * p ;
p = malloc ( len ) ;
2006-01-21 03:09:01 +00:00
if ( ! p )
2006-01-10 23:51:42 +00:00
ast_log ( LOG_ERROR , " Memory Allocation Failure - '%d' bytes in function %s at line %d of %s \n " , ( int ) len , func , lineno , file ) ;
return p ;
}
)
/*!
\ brief A wrapper for calloc ( )
ast_calloc ( ) is a wrapper for calloc ( ) that will generate an Asterisk log
message in the case that the allocation fails .
The arguments and return value are the same as calloc ( )
*/
# define ast_calloc(num, len) \
2006-01-13 18:38:55 +00:00
_ast_calloc ( ( num ) , ( len ) , __FILE__ , __LINE__ , __PRETTY_FUNCTION__ )
2006-01-10 23:51:42 +00:00
AST_INLINE_API (
2006-04-19 22:32:07 +00:00
void * __attribute__ ( ( malloc ) ) _ast_calloc ( size_t num , size_t len , const char * file , int lineno , const char * func ) ,
2006-01-10 23:51:42 +00:00
{
void * p ;
p = calloc ( num , len ) ;
2006-01-21 03:09:01 +00:00
if ( ! p )
2006-01-10 23:51:42 +00:00
ast_log ( LOG_ERROR , " Memory Allocation Failure - '%d' bytes in function %s at line %d of %s \n " , ( int ) len , func , lineno , file ) ;
return p ;
}
)
/*!
\ brief A wrapper for realloc ( )
ast_realloc ( ) is a wrapper for realloc ( ) that will generate an Asterisk log
message in the case that the allocation fails .
The arguments and return value are the same as realloc ( )
*/
# define ast_realloc(p, len) \
2006-01-13 18:38:55 +00:00
_ast_realloc ( ( p ) , ( len ) , __FILE__ , __LINE__ , __PRETTY_FUNCTION__ )
2006-01-10 23:51:42 +00:00
AST_INLINE_API (
2006-04-19 22:32:07 +00:00
void * __attribute__ ( ( malloc ) ) _ast_realloc ( void * p , size_t len , const char * file , int lineno , const char * func ) ,
2006-01-10 23:51:42 +00:00
{
void * newp ;
newp = realloc ( p , len ) ;
2006-01-21 03:09:01 +00:00
if ( ! newp )
2006-01-10 23:51:42 +00:00
ast_log ( LOG_ERROR , " Memory Allocation Failure - '%d' bytes in function %s at line %d of %s \n " , ( int ) len , func , lineno , file ) ;
return newp ;
}
)
/*!
\ brief A wrapper for strdup ( )
ast_strdup ( ) is a wrapper for strdup ( ) that will generate an Asterisk log
message in the case that the allocation fails .
ast_strdup ( ) , unlike strdup ( ) , can safely accept a NULL argument . If a NULL
argument is provided , ast_strdup will return NULL without generating any
kind of error log message .
The argument and return value are the same as strdup ( )
*/
# define ast_strdup(str) \
2006-01-13 18:38:55 +00:00
_ast_strdup ( ( str ) , __FILE__ , __LINE__ , __PRETTY_FUNCTION__ )
2006-01-10 23:51:42 +00:00
AST_INLINE_API (
2006-04-19 22:32:07 +00:00
char * __attribute__ ( ( malloc ) ) _ast_strdup ( const char * str , const char * file , int lineno , const char * func ) ,
2006-01-10 23:51:42 +00:00
{
char * newstr = NULL ;
if ( str ) {
newstr = strdup ( str ) ;
2006-01-21 03:09:01 +00:00
if ( ! newstr )
2006-01-10 23:51:42 +00:00
ast_log ( LOG_ERROR , " Memory Allocation Failure - Could not duplicate '%s' in function %s at line %d of %s \n " , str , func , lineno , file ) ;
}
return newstr ;
}
)
/*!
\ brief A wrapper for strndup ( )
ast_strndup ( ) is a wrapper for strndup ( ) that will generate an Asterisk log
message in the case that the allocation fails .
ast_strndup ( ) , unlike strndup ( ) , can safely accept a NULL argument for the
string to duplicate . If a NULL argument is provided , ast_strdup will return
NULL without generating any kind of error log message .
The arguments and return value are the same as strndup ( )
*/
# define ast_strndup(str, len) \
2006-01-13 18:38:55 +00:00
_ast_strndup ( ( str ) , ( len ) , __FILE__ , __LINE__ , __PRETTY_FUNCTION__ )
2006-01-10 23:51:42 +00:00
AST_INLINE_API (
2006-04-19 22:32:07 +00:00
char * __attribute__ ( ( malloc ) ) _ast_strndup ( const char * str , size_t len , const char * file , int lineno , const char * func ) ,
2006-01-10 23:51:42 +00:00
{
char * newstr = NULL ;
if ( str ) {
newstr = strndup ( str , len ) ;
2006-01-21 03:09:01 +00:00
if ( ! newstr )
2006-01-10 23:51:42 +00:00
ast_log ( LOG_ERROR , " Memory Allocation Failure - Could not duplicate '%d' bytes of '%s' in function %s at line %d of %s \n " , ( int ) len , str , func , lineno , file ) ;
}
return newstr ;
}
)
2006-03-19 01:39:14 +00:00
# else
/* If astmm is in use, let it handle these. Otherwise, it will report that
all allocations are coming from this header file */
# define ast_malloc(a) malloc(a)
# define ast_calloc(a,b) calloc(a,b)
# define ast_realloc(a,b) realloc(a,b)
# define ast_strdup(a) strdup(a)
# define ast_strndup(a,b) strndup(a,b)
# endif /* AST_DEBUG_MALLOC */
2006-01-20 19:24:42 +00:00
# if !defined(ast_strdupa) && defined(__GNUC__)
/*!
\ brief duplicate a string in memory from the stack
\ param s The string to duplicate
This macro will duplicate the given string . It returns a pointer to the stack
allocatted memory for the new string .
*/
# define ast_strdupa(s) \
( __extension__ \
( { \
const char * __old = ( s ) ; \
size_t __len = strlen ( __old ) + 1 ; \
char * __new = __builtin_alloca ( __len ) ; \
if ( __builtin_expect ( ! __new , 0 ) ) \
ast_log ( LOG_ERROR , " Stack Allocation Error in " \
" function '%s' at line '%d' of '%s'! \n " , \
__PRETTY_FUNCTION__ , __LINE__ , __FILE__ ) ; \
2006-01-21 18:11:40 +00:00
else \
memcpy ( __new , __old , __len ) ; \
__new ; \
2006-01-20 19:24:42 +00:00
} ) )
# endif
2005-05-02 00:27:54 +00:00
# endif /* _ASTERISK_UTILS_H */