@ -931,37 +931,88 @@ int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int ds
return ret ;
}
/*! \internal
* \ brief Format a phone number as a domain in an ENUM - adjacent way .
*
* Creates a domain name suitable for query by :
*
* 1. Removing non - digits
* 2. Adding a ' . ' between adjacent digits
* 3. Reversing the string
* 4. Appending the specified suffix ( or e164 . arpa if none is specified )
*/
static char * format_numeric_domain ( const char * number , const char * suffix )
{
char * buffer , * dst ;
size_t suffix_length ;
size_t number_length = strlen ( number ) ;
const char * src = number + number_length - 1 ;
if ( ! suffix ) {
suffix = " e164.arpa " ;
}
suffix_length = strlen ( suffix ) ;
dst = buffer = ast_malloc (
( number_length * 2 ) /* We need 2 bytes per input digit */
+ suffix_length /* ... plus however long the suffix is */
+ 1 /* ... plus room for the '.' separator */
+ 1 /* ... and room for the \0 byte at the end */ ) ;
if ( buffer ) {
while ( src > = number ) {
if ( isdigit ( * src ) ) {
* dst + + = * src ;
* dst + + = ' . ' ;
}
src - - ;
}
/* The length arguments below make sure that the \0 byte is copied into
the final string */
if ( * suffix = = ' . ' ) {
memcpy ( dst , & suffix [ 1 ] , suffix_length ) ;
} else {
memcpy ( dst , suffix , suffix_length + 1 ) ;
}
}
return buffer ;
}
int ast_get_txt ( struct ast_channel * chan , const char * number , char * txt , int txtlen , char * suffix )
{
struct txt_context context ;
char tmp [ 259 + 512 ] ;
int pos = strlen ( number ) - 1 ;
int newpos = 0 ;
int ret = - 1 ;
char * domain ;
int ret ;
int autoservice = 0 ;
ast_debug ( 4 , " ast_get_txt: Number = '%s', suffix = '%s' \n " , number , suffix ) ;
if ( pos > 128 ) {
pos = 128 ;
domain = format_numeric_domain ( number , suffix ) ;
if ( ! domain ) {
return - 1 ;
}
while ( pos > = 0 ) {
if ( isdigit ( number [ pos ] ) ) {
tmp [ newpos + + ] = number [ pos ] ;
tmp [ newpos + + ] = ' . ' ;
}
pos - - ;
if ( chan ) {
/* DNS might take a while, so service the channel while we're blocked */
autoservice = ! ast_autoservice_start ( chan ) ;
}
ast_copy_string ( & tmp [ newpos ] , suffix , sizeof ( tmp ) - newpos ) ;
if ( ret < 0 ) {
ast_debug ( 2 , " No such number found in ENUM: %s (%s) \n " , tmp , strerror ( errno ) ) ;
ret = 0 ;
} else {
ret = ast_search_dns ( & context , domain , C_IN , T_TXT , txt_callback ) ;
if ( ret > 0 ) {
ast_copy_string ( txt , context . txt , txtlen ) ;
} else {
ast_debug ( 2 , " No such number found in ENUM: %s (%s) \n " , domain , strerror ( errno ) ) ;
}
return ret ;
if ( autoservice ) {
ast_autoservice_stop ( chan ) ;
}
ast_free ( domain ) ;
return 0 ;
}
/*! \brief Initialize the ENUM support subsystem */