@ -1618,8 +1618,7 @@ int ast_func_write(struct ast_channel *chan, const char *function, const char *v
static void pbx_substitute_variables_helper_full ( struct ast_channel * c , struct varshead * headp , const char * cp1 , char * cp2 , int count )
{
/* Substitutes variables into cp2, based on string cp1, and assuming cp2 to be
zero - filled */
/* Substitutes variables into cp2, based on string cp1, cp2 NO LONGER NEEDS TO BE ZEROED OUT!!!! */
char * cp4 ;
const char * tmp , * whereweare ;
int length , offset , offset2 , isfunction ;
@ -1628,7 +1627,8 @@ static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct v
char * nextvar , * nextexp , * nextthing ;
char * vars , * vare ;
int pos , brackets , needsub , len ;
* cp2 = 0 ; /* just in case nothing ends up there */
whereweare = tmp = cp1 ;
while ( ! ast_strlen_zero ( whereweare ) & & count ) {
/* Assume we're copying the whole remaining string */
@ -1662,6 +1662,7 @@ static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct v
count - = pos ;
cp2 + = pos ;
whereweare + = pos ;
* cp2 = 0 ;
}
if ( nextvar ) {
@ -1702,7 +1703,6 @@ static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct v
if ( ! ltmp )
ltmp = alloca ( VAR_BUF_SIZE ) ;
memset ( ltmp , 0 , VAR_BUF_SIZE ) ;
pbx_substitute_variables_helper_full ( c , headp , var , ltmp , VAR_BUF_SIZE - 1 ) ;
vars = ltmp ;
} else {
@ -1746,6 +1746,7 @@ static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct v
memcpy ( cp2 , cp4 , length ) ;
count - = length ;
cp2 + = length ;
* cp2 = 0 ;
}
} else if ( nextexp ) {
/* We have an expression. Find the start and end, and determine
@ -1789,7 +1790,6 @@ static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct v
if ( ! ltmp )
ltmp = alloca ( VAR_BUF_SIZE ) ;
memset ( ltmp , 0 , VAR_BUF_SIZE ) ;
pbx_substitute_variables_helper_full ( c , headp , var , ltmp , VAR_BUF_SIZE - 1 ) ;
vars = ltmp ;
} else {
@ -1802,6 +1802,7 @@ static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct v
ast_debug ( 1 , " Expression result is '%s' \n " , cp2 ) ;
count - = length ;
cp2 + = length ;
* cp2 = 0 ;
}
}
}
@ -1820,7 +1821,6 @@ void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1,
static void pbx_substitute_variables ( char * passdata , int datalen , struct ast_channel * c , struct ast_exten * e )
{
const char * tmp ;
memset ( passdata , 0 , datalen ) ;
/* Nothing more to do */
if ( ! e - > data )
@ -1847,8 +1847,8 @@ static void pbx_substitute_variables(char *passdata, int datalen, struct ast_cha
* \ retval - 1 on failure .
*/
static int pbx_extension_helper ( struct ast_channel * c , struct ast_context * con ,
const char * context , const char * exten , int priority ,
const char * label , const char * callerid , enum ext_match_t actio n)
const char * context , const char * exten , int priority ,
const char * label , const char * callerid , enum ext_match_t actio n, int * found , int combined_find_spaw n)
{
struct ast_exten * e ;
struct ast_app * app ;
@ -1857,10 +1857,14 @@ static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
char passdata [ EXT_DATA_SIZE ] ;
int matching_action = ( action = = E_MATCH | | action = = E_CANMATCH | | action = = E_MATCHMORE ) ;
ast_rdlock_contexts ( ) ;
if ( found )
* found = 0 ;
e = pbx_find_extension ( c , con , & q , context , exten , priority , label , callerid , action ) ;
if ( e ) {
if ( found )
* found = 1 ;
if ( matching_action ) {
ast_unlock_contexts ( ) ;
return - 1 ; /* success, we found it */
@ -1927,19 +1931,19 @@ static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
ast_unlock_contexts ( ) ;
switch ( q . status ) {
case STATUS_NO_CONTEXT :
if ( ! matching_action )
if ( ! matching_action & & ! combined_find_spawn )
ast_log ( LOG_NOTICE , " Cannot find extension context '%s' \n " , context ) ;
break ;
case STATUS_NO_EXTENSION :
if ( ! matching_action )
if ( ! matching_action & & ! combined_find_spawn )
ast_log ( LOG_NOTICE , " Cannot find extension '%s' in context '%s' \n " , exten , context ) ;
break ;
case STATUS_NO_PRIORITY :
if ( ! matching_action )
if ( ! matching_action & & ! combined_find_spawn )
ast_log ( LOG_NOTICE , " No such priority %d in extension '%s' in context '%s' \n " , priority , exten , context ) ;
break ;
case STATUS_NO_LABEL :
if ( context )
if ( context & & ! combined_find_spawn )
ast_log ( LOG_NOTICE , " No such label '%s' in extension '%s' in context '%s' \n " , label , exten , context ) ;
break ;
default :
@ -2376,32 +2380,32 @@ int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_
int ast_exists_extension ( struct ast_channel * c , const char * context , const char * exten , int priority , const char * callerid )
{
return pbx_extension_helper ( c , NULL , context , exten , priority , NULL , callerid , E_MATCH );
return pbx_extension_helper ( c , NULL , context , exten , priority , NULL , callerid , E_MATCH , 0 , 0 );
}
int ast_findlabel_extension ( struct ast_channel * c , const char * context , const char * exten , const char * label , const char * callerid )
{
return pbx_extension_helper ( c , NULL , context , exten , 0 , label , callerid , E_FINDLABEL );
return pbx_extension_helper ( c , NULL , context , exten , 0 , label , callerid , E_FINDLABEL , 0 , 0 );
}
int ast_findlabel_extension2 ( struct ast_channel * c , struct ast_context * con , const char * exten , const char * label , const char * callerid )
{
return pbx_extension_helper ( c , con , NULL , exten , 0 , label , callerid , E_FINDLABEL );
return pbx_extension_helper ( c , con , NULL , exten , 0 , label , callerid , E_FINDLABEL , 0 , 0 );
}
int ast_canmatch_extension ( struct ast_channel * c , const char * context , const char * exten , int priority , const char * callerid )
{
return pbx_extension_helper ( c , NULL , context , exten , priority , NULL , callerid , E_CANMATCH );
return pbx_extension_helper ( c , NULL , context , exten , priority , NULL , callerid , E_CANMATCH , 0 , 0 );
}
int ast_matchmore_extension ( struct ast_channel * c , const char * context , const char * exten , int priority , const char * callerid )
{
return pbx_extension_helper ( c , NULL , context , exten , priority , NULL , callerid , E_MATCHMORE );
return pbx_extension_helper ( c , NULL , context , exten , priority , NULL , callerid , E_MATCHMORE , 0 , 0 );
}
int ast_spawn_extension ( struct ast_channel * c , const char * context , const char * exten , int priority , const char * callerid )
int ast_spawn_extension ( struct ast_channel * c , const char * context , const char * exten , int priority , const char * callerid , int * found , int combined_find_spawn )
{
return pbx_extension_helper ( c , NULL , context , exten , priority , NULL , callerid , E_SPAWN );
return pbx_extension_helper ( c , NULL , context , exten , priority , NULL , callerid , E_SPAWN , found , combined_find_spawn );
}
/*! helper function to set extension and priority */
@ -2498,50 +2502,7 @@ static int __ast_pbx_run(struct ast_channel *c)
int digit = 0 ;
/* loop on priorities in this context/exten */
while ( ast_exists_extension ( c , c - > context , c - > exten , c - > priority , c - > cid . cid_num ) ) {
found = 1 ;
if ( ( res = ast_spawn_extension ( c , c - > context , c - > exten , c - > priority , c - > cid . cid_num ) ) ) {
/* Something bad happened, or a hangup has been requested. */
if ( strchr ( " 0123456789ABCDEF*# " , res ) ) {
ast_debug ( 1 , " Oooh, got something to jump out with ('%c')! \n " , res ) ;
pos = 0 ;
dst_exten [ pos + + ] = digit = res ;
dst_exten [ pos ] = ' \0 ' ;
break ;
}
if ( res = = AST_PBX_KEEPALIVE ) {
ast_debug ( 1 , " Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s' \n " , c - > context , c - > exten , c - > priority , c - > name ) ;
ast_verb ( 2 , " Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s' \n " , c - > context , c - > exten , c - > priority , c - > name ) ;
error = 1 ;
break ;
}
ast_debug ( 1 , " Spawn extension (%s,%s,%d) exited non-zero on '%s' \n " , c - > context , c - > exten , c - > priority , c - > name ) ;
ast_verb ( 2 , " Spawn extension (%s, %s, %d) exited non-zero on '%s' \n " , c - > context , c - > exten , c - > priority , c - > name ) ;
if ( ( res = = AST_PBX_ERROR ) & & ast_exists_extension ( c , c - > context , " e " , 1 , c - > cid . cid_num ) ) {
/* if we are already on the 'e' exten, don't jump to it again */
if ( ! strcmp ( c - > exten , " e " ) ) {
if ( option_verbose > 1 )
ast_verbose ( VERBOSE_PREFIX_2 " Spawn extension (%s, %s, %d) exited ERROR while already on 'e' exten on '%s' \n " , c - > context , c - > exten , c - > priority , c - > name ) ;
error = 1 ;
break ;
} else {
pbx_builtin_raise_exception ( c , " ERROR " ) ;
continue ;
}
}
if ( c - > _softhangup = = AST_SOFTHANGUP_ASYNCGOTO ) {
c - > _softhangup = 0 ;
} else if ( c - > _softhangup = = AST_SOFTHANGUP_TIMEOUT ) {
/* atimeout, nothing bad */
} else {
if ( c - > cdr )
ast_cdr_update ( c ) ;
error = 1 ;
break ;
}
}
while ( ! ( res = ast_spawn_extension ( c , c - > context , c - > exten , c - > priority , c - > cid . cid_num , & found , 1 ) ) ) {
if ( c - > _softhangup = = AST_SOFTHANGUP_TIMEOUT & & ast_exists_extension ( c , c - > context , " T " , 1 , c - > cid . cid_num ) ) {
set_ext_pri ( c , " T " , 0 ) ; /* 0 will become 1 with the c->priority++; at the end */
/* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
@ -2560,6 +2521,45 @@ static int __ast_pbx_run(struct ast_channel *c)
}
c - > priority + + ;
} /* end while - from here on we can use 'break' to go out */
if ( found & & res ) {
/* Something bad happened, or a hangup has been requested. */
if ( strchr ( " 0123456789ABCDEF*# " , res ) ) {
ast_debug ( 1 , " Oooh, got something to jump out with ('%c')! \n " , res ) ;
pos = 0 ;
dst_exten [ pos + + ] = digit = res ;
dst_exten [ pos ] = ' \0 ' ;
}
if ( res = = AST_PBX_KEEPALIVE ) {
ast_debug ( 1 , " Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s' \n " , c - > context , c - > exten , c - > priority , c - > name ) ;
ast_verb ( 2 , " Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s' \n " , c - > context , c - > exten , c - > priority , c - > name ) ;
error = 1 ;
}
ast_debug ( 1 , " Spawn extension (%s,%s,%d) exited non-zero on '%s' \n " , c - > context , c - > exten , c - > priority , c - > name ) ;
ast_verb ( 2 , " Spawn extension (%s, %s, %d) exited non-zero on '%s' \n " , c - > context , c - > exten , c - > priority , c - > name ) ;
if ( ( res = = AST_PBX_ERROR ) & & ast_exists_extension ( c , c - > context , " e " , 1 , c - > cid . cid_num ) ) {
/* if we are already on the 'e' exten, don't jump to it again */
if ( ! strcmp ( c - > exten , " e " ) ) {
if ( option_verbose > 1 )
ast_verbose ( VERBOSE_PREFIX_2 " Spawn extension (%s, %s, %d) exited ERROR while already on 'e' exten on '%s' \n " , c - > context , c - > exten , c - > priority , c - > name ) ;
error = 1 ;
} else {
pbx_builtin_raise_exception ( c , " ERROR " ) ;
continue ;
}
}
if ( c - > _softhangup = = AST_SOFTHANGUP_ASYNCGOTO ) {
c - > _softhangup = 0 ;
} else if ( c - > _softhangup = = AST_SOFTHANGUP_TIMEOUT ) {
/* atimeout, nothing bad */
} else {
if ( c - > cdr )
ast_cdr_update ( c ) ;
error = 1 ;
break ;
}
}
if ( error )
break ;
@ -2657,15 +2657,14 @@ static int __ast_pbx_run(struct ast_channel *c)
if ( c - > cdr & & ast_opt_end_cdr_before_h_exten )
ast_cdr_end ( c - > cdr ) ;
set_ext_pri ( c , " h " , 1 ) ;
while ( ast_exists_extension ( c , c - > context , c - > exten , c - > priority , c - > cid . cid_num ) ) {
if ( ( res = ast_spawn_extension ( c , c - > context , c - > exten , c - > priority , c - > cid . cid_num ) ) ) {
/* Something bad happened, or a hangup has been requested. */
ast_debug ( 1 , " Spawn extension (%s,%s,%d) exited non-zero on '%s' \n " , c - > context , c - > exten , c - > priority , c - > name ) ;
ast_verb ( 2 , " Spawn extension (%s, %s, %d) exited non-zero on '%s' \n " , c - > context , c - > exten , c - > priority , c - > name ) ;
break ;
}
while ( ( res = ast_spawn_extension ( c , c - > context , c - > exten , c - > priority , c - > cid . cid_num , & found , 1 ) ) ) {
c - > priority + + ;
}
if ( found & & res ) {
/* Something bad happened, or a hangup has been requested. */
ast_debug ( 1 , " Spawn extension (%s,%s,%d) exited non-zero on '%s' \n " , c - > context , c - > exten , c - > priority , c - > name ) ;
ast_verb ( 2 , " Spawn extension (%s, %s, %d) exited non-zero on '%s' \n " , c - > context , c - > exten , c - > priority , c - > name ) ;
}
}
ast_set2_flag ( c , autoloopflag , AST_FLAG_IN_AUTOLOOP ) ;
@ -4930,7 +4929,7 @@ int ast_add_extension2(struct ast_context *con,
int res ;
int length ;
char * p ;
char expand_buf [ VAR_BUF_SIZE ] = { 0 , } ;
char expand_buf [ VAR_BUF_SIZE ] ;
/* if we are adding a hint, and there are global variables, and the hint
contains variable references , then expand them
@ -6078,7 +6077,7 @@ int pbx_builtin_importvar(struct ast_channel *chan, void *data)
char * name ;
char * value ;
char * channel ;
char tmp [ VAR_BUF_SIZE ] = " " ;
char tmp [ VAR_BUF_SIZE ] ;
static int deprecation_warning = 0 ;
if ( ast_strlen_zero ( data ) ) {