2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Asterisk  - -  An  open  source  telephony  toolkit . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( C )  2016 ,  CFWare ,  LLC 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Corey  Farrell  < git @ cfware . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  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 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  program  is  free  software ,  distributed  under  the  terms  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  the  GNU  General  Public  License  Version  2.  See  the  LICENSE  file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  at  the  top  of  the  source  tree . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \file
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  PBX  variables  routines . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ author  Corey  Farrell  < git @ cfware . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*** MODULEINFO
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< support_level > core < / support_level > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/_private.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/app.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/ast_expr.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/chanvars.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/cli.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/linkedlists.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/lock.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/module.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/paths.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/pbx.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/stasis_channels.h" 
  
						 
					
						
							
								
									
										
										
										
											2022-07-23 22:17:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/test.h" 
  
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "pbx_private.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*** DOCUMENTATION
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< application  name = " Set "  language = " en_US " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Set  channel  variable  or  function  value . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< syntax  argsep = " = " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " name "  required = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " value "  required = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > This  function  can  be  used  to  set  the  value  of  channel  variables  or  dialplan  functions . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											When  setting  variables ,  if  the  variable  name  is  prefixed  with  < literal > _ < / literal > , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											the  variable  will  be  inherited  into  channels  created  from  the  current  channel . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											If  the  variable  name  is  prefixed  with  < literal > __ < / literal > ,  the  variable  will  be 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											inherited  into  channels  created  from  the  current  channel  and  all  children  channels . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< note > < para > If  ( and  only  if ) ,  in  < filename > / etc / asterisk / asterisk . conf < / filename > ,  you  have 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											a  < literal > [ compat ] < / literal >  category ,  and  you  have  < literal > app_set  =  1.4 < / literal >  under  that ,  then 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											the  behavior  of  this  app  changes ,  and  strips  surrounding  quotes  from  the  right  hand  side  as 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											it  did  previously  in  1.4 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											The  advantages  of  not  stripping  out  quoting ,  and  not  caring  about  the  separator  characters  ( comma  and  vertical  bar ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											were  sufficient  to  make  these  changes  in  1.6 .  Confusion  about  how  many  backslashes  would  be  needed  to  properly 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											protect  separators  and  quotes  in  various  database  access  strings  has  been  greatly 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reduced  by  these  changes . < / para > < / note > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< see - also > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " application " > MSet < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " function " > GLOBAL < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " function " > SET < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " function " > ENV < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / see - also > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< / application > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< application  name = " MSet "  language = " en_US " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Set  channel  variable ( s )  or  function  value ( s ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " set1 "  required = " true "  argsep = " = " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< argument  name = " name1 "  required = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< argument  name = " value1 "  required = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " set2 "  multiple = " true "  argsep = " = " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< argument  name = " name2 "  required = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< argument  name = " value2 "  required = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > This  function  can  be  used  to  set  the  value  of  channel  variables  or  dialplan  functions . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											When  setting  variables ,  if  the  variable  name  is  prefixed  with  < literal > _ < / literal > , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											the  variable  will  be  inherited  into  channels  created  from  the  current  channel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											If  the  variable  name  is  prefixed  with  < literal > __ < / literal > ,  the  variable  will  be 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											inherited  into  channels  created  from  the  current  channel  and  all  children  channels . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											MSet  behaves  in  a  similar  fashion  to  the  way  Set  worked  in  1.2 / 1.4  and  is  thus 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											prone  to  doing  things  that  you  may  not  expect .  For  example ,  it  strips  surrounding 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											double - quotes  from  the  right - hand  side  ( value ) .  If  you  need  to  put  a  separator 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											character  ( comma  or  vert - bar ) ,  you  will  need  to  escape  them  by  inserting  a  backslash 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											before  them .  Avoid  its  use  if  possible . < / para > 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-20 20:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											< para > This  application  allows  up  to  99  variables  to  be  set  at  once . < / para > 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										< / description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< see - also > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " application " > Set < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / see - also > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< / application > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								AST_RWLOCK_DEFINE_STATIC ( globalslock ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  varshead  globals  =  AST_LIST_HEAD_NOLOCK_INIT_VALUE ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  extract  offset : length  from  variable  name . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  1  if  there  is  a  offset : length  part ,  which  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  trimmed  off  ( values  go  into  variables ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  parse_variable_name ( char  * var ,  int  * offset ,  int  * length ,  int  * isfunc )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  parens  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* length  =  INT_MAX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* isfunc  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( ;  * var ;  var + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( * var  = =  ' ( ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											( * isfunc ) + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parens + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( * var  = =  ' ) ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parens - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( * var  = =  ' : '  & &  parens  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* var + +  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sscanf ( var ,  " %30d:%30d " ,  offset ,  length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  1 ;  /* offset:length valid */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * \ brief  takes  a  substring .  It  is  ok  to  call  with  value  = =  workspace . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  offset  <  0  means  start  from  the  end  of  the  string  and  set  the  beginning 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *    to  be  that  many  characters  back . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  length  is  the  length  of  the  substring ,  a  value  less  than  0  means  to  leave 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  that  many  off  the  end . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  workspace 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  workspace_len 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Always  return  a  copy  in  workspace . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * substring ( const  char  * value ,  int  offset ,  int  length ,  char  * workspace ,  size_t  workspace_len )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * ret  =  workspace ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  lr ; 	/* length of the input string after the copy */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_copy_string ( workspace ,  value ,  workspace_len ) ;  /* always make a copy */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lr  =  strlen ( ret ) ;  /* compute length after copy, so we never go out of the workspace */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Quick check if no need to do anything */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( offset  = =  0  & &  length  > =  lr ) 	/* take the whole string */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( offset  <  0 ) 	{ 	/* translate negative offset into positive ones */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										offset  =  lr  +  offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( offset  <  0 )  /* If the negative offset was greater than the length of the string, just start at the beginning */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* too large offset result in empty string so we know what to return */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( offset  > =  lr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ret  +  lr ; 	/* the final '\0' */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ret  + =  offset ; 		/* move to the start position */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( length  > =  0  & &  length  <  lr  -  offset ) 	/* truncate if necessary */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ret [ length ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else  if  ( length  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( lr  >  offset  -  length )  /* After we remove from the front and from the rear, is there anything left? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ret [ lr  +  length  -  offset ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ret [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  char  * ast_str_substring ( struct  ast_str  * value ,  int  offset ,  int  length )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  lr ; 	/* length of the input string after the copy */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lr  =  ast_str_strlen ( value ) ;  /* compute length after copy, so we never go out of the workspace */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-23 22:17:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_assert ( lr  = =  strlen ( ast_str_buffer ( value ) ) ) ;  /* ast_str_strlen should always agree with strlen */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* Quick check if no need to do anything */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( offset  = =  0  & &  length  > =  lr ) 	/* take the whole string */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ast_str_buffer ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( offset  <  0 ) 	{ 	/* translate negative offset into positive ones */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										offset  =  lr  +  offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( offset  <  0 )  /* If the negative offset was greater than the length of the string, just start at the beginning */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* too large offset result in empty string so we know what to return */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( offset  > =  lr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_str_reset ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ast_str_buffer ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( offset  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Go ahead and chop off the beginning */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memmove ( ast_str_buffer ( value ) ,  ast_str_buffer ( value )  +  offset ,  ast_str_strlen ( value )  -  offset  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lr  - =  offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( length  > =  0  & &  length  <  lr )  { 	/* truncate if necessary */ 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 18:25:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_str_truncate ( value ,  length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  if  ( length  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( lr  >  - length )  {  /* After we remove from the front and from the rear, is there anything left? */ 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 18:25:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_str_truncate ( value ,  lr  +  length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_reset ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Nothing to do, but update the buffer length */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_str_update ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ast_str_buffer ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief  Support for Asterisk built-in variables in the dialplan
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\ note 	See  also  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									-  \ ref  AstVar 	Channel  variables 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									-  \ ref  AstCauses  The  HANGUPCAUSE  variable 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  pbx_retrieve_variable ( struct  ast_channel  * c ,  const  char  * var ,  char  * * ret ,  char  * workspace ,  int  workspacelen ,  struct  varshead  * headp )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * str  =  ast_str_create ( 16 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * cret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cret  =  ast_str_retrieve_variable ( & str ,  0 ,  c ,  headp ,  var ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_copy_string ( workspace ,  ast_str_buffer ( str ) ,  workspacelen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* ret  =  cret  ?  workspace  :  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  char  * ast_str_retrieve_variable ( struct  ast_str  * * str ,  ssize_t  maxlen ,  struct  ast_channel  * c ,  struct  varshead  * headp ,  const  char  * var )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  not_found  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * tmpvar ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * s ; 	/* the result */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  offset ,  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ,  need_substring ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  varshead  * places [ 2 ]  =  {  headp ,  & globals  } ; 	/* list of places where we may look */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  workspace [ 20 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( c )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_lock ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										places [ 0 ]  =  ast_channel_varshead ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Make  a  copy  of  var  because  parse_variable_name ( )  modifies  the  string . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Then  if  called  directly ,  we  might  need  to  run  substring ( )  on  the  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  remember  this  for  later  in  ' need_substring ' ,  ' offset '  and  ' length ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tmpvar  =  ast_strdupa ( var ) ; 	/* parse_variable_name modifies the string */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									need_substring  =  parse_variable_name ( tmpvar ,  & offset ,  & length ,  & i  /* ignored */ ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Look  first  into  predefined  variables ,  then  into  variable  lists . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Variable  ' s '  points  to  the  result ,  according  to  the  following  rules : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  s  = =  & not_found  ( set  at  the  beginning )  means  that  we  did  not  find  a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * 	matching  variable  and  need  to  look  into  more  places . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  If  s  ! =  & not_found ,  s  is  a  valid  result  string  as  follows : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  s  =  NULL  if  the  variable  does  not  have  a  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * 	you  typically  do  this  when  looking  for  an  unset  predefined  variable . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  s  =  workspace  if  the  result  has  been  assembled  there ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * 	typically  done  when  the  result  is  built  e . g .  with  an  snprintf ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * 	so  we  don ' t  need  to  do  an  additional  copy . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  s  ! =  workspace  in  case  we  have  a  string ,  that  needs  to  be  copied 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * 	( the  ast_copy_string  is  done  once  for  all  at  the  end ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * 	Typically  done  when  the  result  is  already  available  in  some  string . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  =  & not_found ; 	/* default value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( c )  { 	/* This group requires a valid channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Names with common parts are looked up a piece at a time using strncmp. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strncmp ( var ,  " CALL " ,  4 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! strncmp ( var  +  4 ,  " ING " ,  3 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! strcmp ( var  +  7 ,  " PRES " ) )  { 			/* CALLINGPRES */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_str_set ( str ,  maxlen ,  " %d " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_party_id_presentation ( & ast_channel_caller ( c ) - > id ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													s  =  ast_str_buffer ( * str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ! strcmp ( var  +  7 ,  " ANI2 " ) )  { 		/* CALLINGANI2 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_str_set ( str ,  maxlen ,  " %d " ,  ast_channel_caller ( c ) - > ani2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													s  =  ast_str_buffer ( * str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ! strcmp ( var  +  7 ,  " TON " ) )  { 		/* CALLINGTON */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_str_set ( str ,  maxlen ,  " %d " ,  ast_channel_caller ( c ) - > id . number . plan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													s  =  ast_str_buffer ( * str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ! strcmp ( var  +  7 ,  " TNS " ) )  { 		/* CALLINGTNS */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_str_set ( str ,  maxlen ,  " %d " ,  ast_channel_dialed ( c ) - > transit_network_select ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													s  =  ast_str_buffer ( * str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " HINT " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_str_get_hint ( str ,  maxlen ,  NULL ,  0 ,  c ,  ast_channel_context ( c ) ,  ast_channel_exten ( c ) )  ?  ast_str_buffer ( * str )  :  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " HINTNAME " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_str_get_hint ( NULL ,  0 ,  str ,  maxlen ,  c ,  ast_channel_context ( c ) ,  ast_channel_exten ( c ) )  ?  ast_str_buffer ( * str )  :  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " EXTEN " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_channel_exten ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " CONTEXT " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_channel_context ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " PRIORITY " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( str ,  maxlen ,  " %d " ,  ast_channel_priority ( c ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_str_buffer ( * str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " CHANNEL " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_channel_name ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " UNIQUEID " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_channel_uniqueid ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " HANGUPCAUSE " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( str ,  maxlen ,  " %d " ,  ast_channel_hangupcause ( c ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_str_buffer ( * str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( s  = =  & not_found )  {  /* look for more */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcmp ( var ,  " EPOCH " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( str ,  maxlen ,  " %d " ,  ( int )  time ( NULL ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_str_buffer ( * str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " SYSTEMNAME " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_config_AST_SYSTEM_NAME ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-29 12:25:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " ASTCACHEDIR " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_config_AST_CACHE_DIR ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " ASTETCDIR " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_config_AST_CONFIG_DIR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " ASTMODDIR " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_config_AST_MODULE_DIR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " ASTVARLIBDIR " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_config_AST_VAR_DIR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " ASTDBDIR " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_config_AST_DB ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " ASTKEYDIR " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_config_AST_KEY_DIR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " ASTDATADIR " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_config_AST_DATA_DIR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " ASTAGIDIR " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_config_AST_AGI_DIR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " ASTSPOOLDIR " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_config_AST_SPOOL_DIR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " ASTRUNDIR " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_config_AST_RUN_DIR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " ASTLOGDIR " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_config_AST_LOG_DIR ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-08 15:09:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " ASTSBINDIR " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  ast_config_AST_SBIN_DIR ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( var ,  " ENTITYID " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_eid_to_str ( workspace ,  sizeof ( workspace ) ,  & ast_eid_default ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  =  workspace ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* if not found, look into chanvars or global vars */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  s  = =  & not_found  & &  i  <  ARRAY_LEN ( places ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_var_t  * variables ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! places [ i ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( places [ i ]  = =  & globals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_rwlock_rdlock ( & globalslock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_LIST_TRAVERSE ( places [ i ] ,  variables ,  entries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! strcmp ( ast_var_name ( variables ) ,  var ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												s  =  ast_var_value ( variables ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( places [ i ]  = =  & globals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_rwlock_unlock ( & globalslock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( s  = =  & not_found  | |  s  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 5 ,  " Result of '%s' is NULL \n " ,  var ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ret  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 5 ,  " Result of '%s' is '%s' \n " ,  var ,  s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( s  ! =  ast_str_buffer ( * str ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( str ,  maxlen ,  " %s " ,  s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ret  =  ast_str_buffer ( * str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( need_substring )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ret  =  ast_str_substring ( * str ,  offset ,  length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 2 ,  " Final result of '%s' is '%s' \n " ,  var ,  ret ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( c )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_unlock ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-27 11:31:04 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ast_str_substitute_variables_full2 ( struct  ast_str  * * buf ,  ssize_t  maxlen ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * c ,  struct  varshead  * headp ,  const  char  * templ , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  * used ,  int  use_both ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Substitutes variables into buf, based on string templ */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * whereweare ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_str  * substr1  =  ast_str_create ( 16 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * substr2  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * substr3  =  ast_str_create ( 16 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_str_reset ( * buf ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! substr1  | |  ! substr3 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( used )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* used  =  ast_str_strlen ( * buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_free ( substr1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_free ( substr3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									whereweare  =  templ ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ! ast_strlen_zero ( whereweare ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  char  * nextvar  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  char  * nextexp  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  char  * nextthing ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  char  * vars ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  char  * vare ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  * finalvars ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  brackets ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  needsub ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* reset our buffer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_str_reset ( substr3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Determine how much simply needs to be copied to the output buf. */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										nextthing  =  strchr ( whereweare ,  ' $ ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( nextthing )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pos  =  nextthing  -  whereweare ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											switch  ( nextthing [ 1 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ' { ' : 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Variable substitution */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												nextvar  =  nextthing ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ' [ ' : 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Expression substitution */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												nextexp  =  nextthing ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* '$' is not part of a substitution so include it too. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												+ + pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* We're copying the whole remaining string */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  strlen ( whereweare ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( pos )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Copy that many bytes */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_append_substr ( buf ,  maxlen ,  whereweare ,  pos ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											whereweare  + =  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( nextvar )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int  offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  offset2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  isfunction ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											/* We have a variable.  Find the start and end, and determine
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   if  we  are  going  to  have  to  recursively  call  ourselves  on  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   contents  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											vars  =  vare  =  nextvar  +  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											brackets  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											needsub  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Find the end of it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											while  ( brackets  & &  * vare )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ( vare [ 0 ]  = =  ' $ ' )  & &  ( vare [ 1 ]  = =  ' { ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													needsub + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													brackets + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													vare + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												}  else  if  ( vare [ 0 ]  = =  ' { ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													brackets + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( vare [ 0 ]  = =  ' } ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													brackets - - ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  if  ( ( vare [ 0 ]  = =  ' $ ' )  & &  ( vare [ 1 ]  = =  ' [ ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													needsub + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													vare + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												vare + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											len  =  vare  -  vars ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( brackets )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Error in extension logic (missing '}') \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Don't count the closing '}' in the length. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												- - len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Skip totally over variable string */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											whereweare  =  vare ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Store variable name expression to lookup. */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_str_set_substr ( & substr1 ,  0 ,  vars ,  len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-27 11:31:04 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 5 ,  " Evaluating '%s' (from '%s' len %d) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_str_buffer ( substr1 ) ,  vars ,  len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Substitute if necessary */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( needsub )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! substr2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													substr2  =  ast_str_create ( 16 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! substr2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-27 11:31:04 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_str_substitute_variables_full2 ( & substr2 ,  0 ,  c ,  headp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_str_buffer ( substr1 ) ,  NULL ,  use_both ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												finalvars  =  ast_str_buffer ( substr2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												finalvars  =  ast_str_buffer ( substr1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parse_variable_name ( finalvars ,  & offset ,  & offset2 ,  & isfunction ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( isfunction )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Evaluate function */ 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-27 11:31:04 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( c )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													res  =  ast_func_read2 ( c ,  finalvars ,  & substr3 ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-27 11:31:04 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_debug ( 2 ,  " Function %s result is '%s' from channel \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														finalvars ,  res  ?  " "  :  ast_str_buffer ( substr3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! c  | |  ( c  & &  res  <  0  & &  use_both ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													struct  varshead  old ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													struct  ast_channel  * bogus ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bogus  =  ast_dummy_channel_alloc ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													if  ( bogus )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														old  =  * ast_channel_varshead ( bogus ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-27 11:31:04 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( headp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															* ast_channel_varshead ( bogus )  =  * headp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														res  =  ast_func_read2 ( bogus ,  finalvars ,  & substr3 ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														/* Don't deallocate the varshead that was passed in */ 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-27 11:31:04 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( headp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															* ast_channel_varshead ( bogus )  =  old ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_channel_unref ( bogus ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_log ( LOG_ERROR ,  " Unable to allocate bogus channel for function value substitution. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														res  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-27 11:31:04 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_debug ( 2 ,  " Function %s result is '%s' from headp \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														finalvars ,  res  ?  " "  :  ast_str_buffer ( substr3 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-27 11:31:04 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												const  char  * result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( c )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													result  =  ast_str_retrieve_variable ( & substr3 ,  0 ,  c ,  NULL ,  finalvars ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 2 ,  " Variable %s result is '%s' from channel \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														finalvars ,  S_OR ( result ,  " " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! c  | |  ( c  & &  ! result  & &  use_both ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													result  =  ast_str_retrieve_variable ( & substr3 ,  0 ,  NULL ,  headp ,  finalvars ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 2 ,  " Variable %s result is '%s' from headp \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														finalvars ,  S_OR ( result ,  " " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  ( result  ?  0  :  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_str_substring ( substr3 ,  offset ,  offset2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_str_append ( buf ,  maxlen ,  " %s " ,  ast_str_buffer ( substr3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( nextexp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* We have an expression.  Find the start and end, and determine
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   if  we  are  going  to  have  to  recursively  call  ourselves  on  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   contents  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											vars  =  vare  =  nextexp  +  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											brackets  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											needsub  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Find the end of it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											while  ( brackets  & &  * vare )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ( vare [ 0 ]  = =  ' $ ' )  & &  ( vare [ 1 ]  = =  ' [ ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													needsub + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													brackets + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													vare + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( vare [ 0 ]  = =  ' [ ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													brackets + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( vare [ 0 ]  = =  ' ] ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													brackets - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ( vare [ 0 ]  = =  ' $ ' )  & &  ( vare [ 1 ]  = =  ' { ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													needsub + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													vare + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												vare + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											len  =  vare  -  vars ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( brackets )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Error in extension logic (missing ']') \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Don't count the closing ']' in the length. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												- - len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Skip totally over expression */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											whereweare  =  vare ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Store expression to evaluate. */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_str_set_substr ( & substr1 ,  0 ,  vars ,  len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Substitute if necessary */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( needsub )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! substr2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													substr2  =  ast_str_create ( 16 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! substr2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-27 11:31:04 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_str_substitute_variables_full2 ( & substr2 ,  0 ,  c ,  headp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_str_buffer ( substr1 ) ,  NULL ,  use_both ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												finalvars  =  ast_str_buffer ( substr2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												finalvars  =  ast_str_buffer ( substr1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_str_expr ( & substr3 ,  0 ,  c ,  finalvars ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 2 ,  " Expression result is '%s' \n " ,  ast_str_buffer ( substr3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_append ( buf ,  maxlen ,  " %s " ,  ast_str_buffer ( substr3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( used )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* used  =  ast_str_strlen ( * buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									ast_free ( substr1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( substr2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( substr3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-27 11:31:04 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ast_str_substitute_variables_full ( struct  ast_str  * * buf ,  ssize_t  maxlen ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan ,  struct  varshead  * headp ,  const  char  * templ ,  size_t  * used ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_str_substitute_variables_full2 ( buf ,  maxlen ,  chan ,  headp ,  templ ,  used ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  ast_str_substitute_variables ( struct  ast_str  * * buf ,  ssize_t  maxlen ,  struct  ast_channel  * chan ,  const  char  * templ )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_str_substitute_variables_full ( buf ,  maxlen ,  chan ,  NULL ,  templ ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ast_str_substitute_variables_varshead ( struct  ast_str  * * buf ,  ssize_t  maxlen ,  struct  varshead  * headp ,  const  char  * templ )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_str_substitute_variables_full ( buf ,  maxlen ,  NULL ,  headp ,  templ ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  pbx_substitute_variables_helper_full ( struct  ast_channel  * c ,  struct  varshead  * headp ,  const  char  * cp1 ,  char  * cp2 ,  int  count ,  size_t  * used )  
						 
					
						
							
								
									
										
										
										
											2021-11-15 21:08:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_substitute_variables_helper_full_location ( c ,  headp ,  cp1 ,  cp2 ,  count ,  used ,  NULL ,  NULL ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  pbx_substitute_variables_helper_full_location ( struct  ast_channel  * c ,  struct  varshead  * headp ,  const  char  * cp1 ,  char  * cp2 ,  int  count ,  size_t  * used ,  char  * context ,  char  * exten ,  int  pri )  
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Substitutes variables into cp2, based on string cp1, cp2 NO LONGER NEEDS TO BE ZEROED OUT!!!!  */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * whereweare ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * orig_cp2  =  cp2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 12:36:17 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  ltmp [ VAR_BUF_SIZE ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  var [ VAR_BUF_SIZE ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* cp2  =  0 ;  /* just in case nothing ends up there */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									whereweare  =  cp1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ! ast_strlen_zero ( whereweare )  & &  count )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										char  * nextvar  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  * nextexp  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  * nextthing ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  * vars ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  * vare ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  brackets ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  needsub ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Determine how much simply needs to be copied to the output buf. */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										nextthing  =  strchr ( whereweare ,  ' $ ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( nextthing )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pos  =  nextthing  -  whereweare ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											switch  ( nextthing [ 1 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ' { ' : 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Variable substitution */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												nextvar  =  nextthing ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ' [ ' : 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Expression substitution */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												nextexp  =  nextthing ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* '$' is not part of a substitution so include it too. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												+ + pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* We're copying the whole remaining string */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  strlen ( whereweare ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( pos )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Can't copy more than 'count' bytes */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( pos  >  count ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pos  =  count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Copy that many bytes */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memcpy ( cp2 ,  whereweare ,  pos ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											count  - =  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cp2  + =  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											whereweare  + =  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* cp2  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( nextvar )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int  offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  offset2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  isfunction ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-13 22:49:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											char  * cp4  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 12:36:17 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											char  workspace [ VAR_BUF_SIZE ]  =  " " ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											/* We have a variable.  Find the start and end, and determine
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   if  we  are  going  to  have  to  recursively  call  ourselves  on  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   contents  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											vars  =  vare  =  nextvar  +  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											brackets  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											needsub  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Find the end of it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											while  ( brackets  & &  * vare )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ( vare [ 0 ]  = =  ' $ ' )  & &  ( vare [ 1 ]  = =  ' { ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													needsub + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													brackets + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													vare + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												}  else  if  ( vare [ 0 ]  = =  ' { ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													brackets + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( vare [ 0 ]  = =  ' } ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													brackets - - ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  if  ( ( vare [ 0 ]  = =  ' $ ' )  & &  ( vare [ 1 ]  = =  ' [ ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													needsub + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													vare + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												vare + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											len  =  vare  -  vars ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( brackets )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Error in extension logic (missing '}') \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Don't count the closing '}' in the length. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												- - len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Skip totally over variable string */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											whereweare  =  vare ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Store variable name expression to lookup (and truncate). */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( var ,  vars ,  len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Substitute if necessary */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( needsub )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 08:49:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pbx_substitute_variables_helper_full_location ( c ,  headp ,  var ,  ltmp ,  VAR_BUF_SIZE  -  1 ,  NULL ,  context ,  exten ,  pri ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												vars  =  ltmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												vars  =  var ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parse_variable_name ( vars ,  & offset ,  & offset2 ,  & isfunction ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( isfunction )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Evaluate function */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( c  | |  ! headp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													cp4  =  ast_func_read ( c ,  vars ,  workspace ,  VAR_BUF_SIZE )  ?  NULL  :  workspace ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													struct  varshead  old ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													struct  ast_channel  * bogus ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bogus  =  ast_dummy_channel_alloc ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( bogus )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														old  =  * ast_channel_varshead ( bogus ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														* ast_channel_varshead ( bogus )  =  * headp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														cp4  =  ast_func_read ( bogus ,  vars ,  workspace ,  VAR_BUF_SIZE )  ?  NULL  :  workspace ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														/* Don't deallocate the varshead that was passed in */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														* ast_channel_varshead ( bogus )  =  old ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_channel_unref ( bogus ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_log ( LOG_ERROR ,  " Unable to allocate bogus channel for function value substitution. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														cp4  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 2 ,  " Function %s result is '%s' \n " ,  vars ,  cp4  ?  cp4  :  " (null) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Retrieve variable value */ 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 21:08:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* For dialplan location, if we were told what to substitute explicitly, use that instead */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( exten  & &  ! strcmp ( vars ,  " EXTEN " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_copy_string ( workspace ,  exten ,  VAR_BUF_SIZE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 08:49:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													cp4  =  workspace ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 21:08:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  if  ( context  & &  ! strcmp ( vars ,  " CONTEXT " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_copy_string ( workspace ,  context ,  VAR_BUF_SIZE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 08:49:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													cp4  =  workspace ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 21:08:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  if  ( pri  & &  ! strcmp ( vars ,  " PRIORITY " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													snprintf ( workspace ,  VAR_BUF_SIZE ,  " %d " ,  pri ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 08:49:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													cp4  =  workspace ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 21:08:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													pbx_retrieve_variable ( c ,  vars ,  & cp4 ,  workspace ,  VAR_BUF_SIZE ,  headp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( cp4 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cp4  =  substring ( cp4 ,  offset ,  offset2 ,  workspace ,  VAR_BUF_SIZE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												length  =  strlen ( cp4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( length  >  count ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													length  =  count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												memcpy ( cp2 ,  cp4 ,  length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												count  - =  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cp2  + =  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												* cp2  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( nextexp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* We have an expression.  Find the start and end, and determine
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   if  we  are  going  to  have  to  recursively  call  ourselves  on  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   contents  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											vars  =  vare  =  nextexp  +  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											brackets  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											needsub  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Find the end of it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											while  ( brackets  & &  * vare )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ( vare [ 0 ]  = =  ' $ ' )  & &  ( vare [ 1 ]  = =  ' [ ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													needsub + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													brackets + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													vare + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( vare [ 0 ]  = =  ' [ ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													brackets + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( vare [ 0 ]  = =  ' ] ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													brackets - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ( vare [ 0 ]  = =  ' $ ' )  & &  ( vare [ 1 ]  = =  ' { ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													needsub + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													vare + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												vare + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											len  =  vare  -  vars ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( brackets )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Error in extension logic (missing ']') \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Don't count the closing ']' in the length. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												- - len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Skip totally over expression */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											whereweare  =  vare ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Store expression to evaluate (and truncate). */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( var ,  vars ,  len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Substitute if necessary */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( needsub )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 08:49:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pbx_substitute_variables_helper_full_location ( c ,  headp ,  var ,  ltmp ,  VAR_BUF_SIZE  -  1 ,  NULL ,  context ,  exten ,  pri ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												vars  =  ltmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												vars  =  var ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											length  =  ast_expr ( vars ,  cp2 ,  count ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( length )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Expression result is '%s' \n " ,  cp2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												count  - =  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cp2  + =  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												* cp2  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( used )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* used  =  cp2  -  orig_cp2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  pbx_substitute_variables_helper ( struct  ast_channel  * c ,  const  char  * cp1 ,  char  * cp2 ,  int  count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pbx_substitute_variables_helper_full ( c ,  ( c )  ?  ast_channel_varshead ( c )  :  NULL ,  cp1 ,  cp2 ,  count ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  pbx_substitute_variables_varshead ( struct  varshead  * headp ,  const  char  * cp1 ,  char  * cp2 ,  int  count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2018-01-18 20:19:00 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pbx_substitute_variables_helper_full ( NULL ,  headp ,  cp1 ,  cp2 ,  count ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief CLI support for listing global variables in a parseable way */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * handle_show_globals ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_var_t  * newvariable ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > command  =  " dialplan show globals " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Usage: dialplan show globals \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        List current global dialplan variables and their values \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rwlock_rdlock ( & globalslock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_TRAVERSE  ( & globals ,  newvariable ,  entries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										i + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  "    %s=%s \n " ,  ast_var_name ( newvariable ) ,  ast_var_value ( newvariable ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rwlock_unlock ( & globalslock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  " \n     -- %d variable(s) \n " ,  i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief CLI support for listing chanvar's variables in a parseable way */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * handle_show_chanvar ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_var_t  * var ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > command  =  " dialplan show chanvar " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Usage: dialplan show chanvar <channel> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        List current channel variables and their values \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ast_complete_channels ( a - > line ,  a - > word ,  a - > pos ,  a - > n ,  3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( a - > argc  ! =  e - > args  +  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_SHOWUSAGE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									chan  =  ast_channel_get_by_name ( a - > argv [ e - > args ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " Channel '%s' not found \n " ,  a - > argv [ e - > args ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_FAILURE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_TRAVERSE ( ast_channel_varshead ( chan ) ,  var ,  entries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " %s=%s \n " ,  ast_var_name ( var ) ,  ast_var_value ( var ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_unref ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-26 21:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \brief CLI support for executing function */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * handle_eval_function ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * c  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * fn ,  * substituted ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  workspace [ 1024 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > command  =  " dialplan eval function " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Usage: dialplan eval function <name(args)> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        Evaluate a dialplan function call \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        A dummy channel is used to evaluate \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        the function call, so only global \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        variables should be used. \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( a - > argc  ! =  e - > args  +  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_SHOWUSAGE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c  =  ast_dummy_channel_alloc ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! c )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " Unable to allocate bogus channel for function evaluation. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_FAILURE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fn  =  ( char  * )  a - > argv [ 3 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_substitute_variables_helper ( c ,  fn ,  workspace ,  sizeof ( workspace ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									substituted  =  ast_strdupa ( workspace ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									workspace [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ret  =  ast_func_read ( c ,  substituted ,  workspace ,  sizeof ( workspace ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c  =  ast_channel_unref ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  " Return Value: %s (%d) \n " ,  ret  ?  " Failure "  :  " Success " ,  ret ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  " Result: %s \n " ,  workspace ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  char  * handle_set_global ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > command  =  " dialplan set global " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Usage: dialplan set global <name> <value> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        Set global dialplan variable <name> to <value> \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( a - > argc  ! =  e - > args  +  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_SHOWUSAGE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( NULL ,  a - > argv [ 3 ] ,  a - > argv [ 4 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  " \n     -- Global variable '%s' set to '%s' \n " ,  a - > argv [ 3 ] ,  a - > argv [ 4 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * handle_set_chanvar ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * chan_name ,  * var_name ,  * var_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > command  =  " dialplan set chanvar " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Usage: dialplan set chanvar <channel> <varname> <value> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        Set channel variable <varname> to <value> \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ast_complete_channels ( a - > line ,  a - > word ,  a - > pos ,  a - > n ,  3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( a - > argc  ! =  e - > args  +  3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_SHOWUSAGE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									chan_name  =  a - > argv [ e - > args ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var_name  =  a - > argv [ e - > args  +  1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var_value  =  a - > argv [ e - > args  +  2 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( chan  =  ast_channel_get_by_name ( chan_name ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " Channel '%s' not found \n " ,  chan_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_FAILURE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  var_name ,  var_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									chan  =  ast_channel_unref ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  " \n     -- Channel variable '%s' set to '%s' for '%s' \n " ,   var_name ,  var_value ,  chan_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  pbx_builtin_serialize_variables ( struct  ast_channel  * chan ,  struct  ast_str  * * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_var_t  * variables ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * var ,  * val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  total  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_str_reset ( * buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_TRAVERSE ( ast_channel_varshead ( chan ) ,  variables ,  entries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( var  =  ast_var_name ( variables ) )  & &  ( val  =  ast_var_value ( variables ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_str_append ( buf ,  0 ,  " %s=%s \n " ,  var ,  val )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_ERROR ,  " Data Buffer Size Exceeded! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												total + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  total ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  char  * pbx_builtin_getvar_helper ( struct  ast_channel  * chan ,  const  char  * name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_var_t  * variables ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * ret  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  varshead  * places [ 2 ]  =  {  NULL ,  & globals  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										places [ 0 ]  =  ast_channel_varshead ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  2 ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! places [ i ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( places [ i ]  = =  & globals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_rwlock_rdlock ( & globalslock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_LIST_TRAVERSE ( places [ i ] ,  variables ,  entries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! strcmp ( name ,  ast_var_name ( variables ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  =  ast_var_value ( variables ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( places [ i ]  = =  & globals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_rwlock_unlock ( & globalslock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ret ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  pbx_builtin_pushvar_helper ( struct  ast_channel  * chan ,  const  char  * name ,  const  char  * value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_var_t  * newvariable ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  varshead  * headp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( name [ strlen ( name ) - 1 ]  = =  ' ) ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  * function  =  ast_strdupa ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Cannot push a value onto a function \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_func_write ( chan ,  function ,  value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										headp  =  ast_channel_varshead ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_rwlock_wrlock ( & globalslock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										headp  =  & globals ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( value  & &  ( newvariable  =  ast_var_assign ( name ,  value ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( headp  = =  & globals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_verb ( 2 ,  " Setting global variable '%s' to '%s' \n " ,  name ,  value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_LIST_INSERT_HEAD ( headp ,  newvariable ,  entries ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_rwlock_unlock ( & globalslock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  pbx_builtin_setvar_helper ( struct  ast_channel  * chan ,  const  char  * name ,  const  char  * value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_var_t  * newvariable ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  varshead  * headp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * nametail  =  name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*! True if the old value was not an empty string. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  old_value_existed  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( name [ strlen ( name )  -  1 ]  = =  ' ) ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  * function  =  ast_strdupa ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ast_func_write ( chan ,  function ,  value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										headp  =  ast_channel_varshead ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_rwlock_wrlock ( & globalslock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										headp  =  & globals ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* For comparison purposes, we have to strip leading underscores */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( * nametail  = =  ' _ ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nametail + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( * nametail  = =  ' _ ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											nametail + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_TRAVERSE_SAFE_BEGIN ( headp ,  newvariable ,  entries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( strcmp ( ast_var_name ( newvariable ) ,  nametail )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* there is already such a variable, delete it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											AST_LIST_REMOVE_CURRENT ( entries ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											old_value_existed  =  ! ast_strlen_zero ( ast_var_value ( newvariable ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_var_delete ( newvariable ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_TRAVERSE_SAFE_END ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( value  & &  ( newvariable  =  ast_var_assign ( name ,  value ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( headp  = =  & globals )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_verb ( 2 ,  " Setting global variable '%s' to '%s' \n " ,  name ,  value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_LIST_INSERT_HEAD ( headp ,  newvariable ,  entries ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_publish_varset ( chan ,  name ,  value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( old_value_existed )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* We just deleted a non-empty dialplan variable. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_publish_varset ( chan ,  name ,  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_rwlock_unlock ( & globalslock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  pbx_builtin_setvar ( struct  ast_channel  * chan ,  const  char  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * name ,  * value ,  * mydata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( data ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Set requires one variable name/value pair. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mydata  =  ast_strdupa ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									name  =  strsep ( & mydata ,  " = " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									value  =  mydata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Set requires an '=' to be a valid assignment. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( strchr ( name ,  '   ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s'). \n " ,  name ,  mydata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  name ,  value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  pbx_builtin_setvar_multiple ( struct  ast_channel  * chan ,  const  char  * vdata )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_DECLARE_APP_ARGS ( args , 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-20 20:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										AST_APP_ARG ( pair ) [ 99 ] ;  /* parse up to 99 variables */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_DECLARE_APP_ARGS ( pair , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( vdata ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " MSet requires at least one variable name/value pair. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									data  =  ast_strdupa ( vdata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_STANDARD_APP_ARGS ( args ,  data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( x  =  0 ;  x  <  args . argc ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_NONSTANDARD_APP_ARGS ( pair ,  args . pair [ x ] ,  ' = ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( pair . argc  = =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pbx_builtin_setvar_helper ( chan ,  pair . name ,  pair . value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( strchr ( pair . name ,  '   ' ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s'). \n " ,  pair . name ,  pair . value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " MSet: ignoring entry '%s' with no '=' \n " ,  pair . name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " MSet: ignoring entry '%s' with no '=' (in %s@%s:%d \n " ,  pair . name ,  ast_channel_exten ( chan ) ,  ast_channel_context ( chan ) ,  ast_channel_priority ( chan ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  pbx_builtin_clear_globals ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_var_t  * vardata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rwlock_wrlock ( & globalslock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( vardata  =  AST_LIST_REMOVE_HEAD ( & globals ,  entries ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_var_delete ( vardata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rwlock_unlock ( & globalslock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-23 22:17:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef TEST_FRAMEWORK 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								AST_TEST_DEFINE ( test_variable_substrings )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ,  res  =  AST_TEST_PASS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan ;  /* dummy channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * str ;  /* fancy string for holding comparing value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * test_strings [ ] [ 5 ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ " somevaluehere " ,  " CALLERID(num):0:25 " ,  " somevaluehere " } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ " somevaluehere " ,  " CALLERID(num):0:5 " ,  " somev " } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ " somevaluehere " ,  " CALLERID(num):4:5 " ,  " value " } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ " somevaluehere " ,  " CALLERID(num):0:-4 " ,  " somevalue " } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ " somevaluehere " ,  " CALLERID(num):-4 " ,  " here " } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  TEST_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										info - > name  =  " variable_substrings " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										info - > category  =  " /main/pbx/ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										info - > summary  =  " Test variable substring resolution " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										info - > description  =  " Verify that variable substrings are calculated correctly " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AST_TEST_NOT_RUN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  TEST_EXECUTE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( chan  =  ast_dummy_channel_alloc ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_test_status_update ( test ,  " Unable to allocate dummy channel \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AST_TEST_FAIL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( str  =  ast_str_create ( 64 ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_test_status_update ( test ,  " Unable to allocate dynamic string buffer \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_release ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AST_TEST_FAIL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  ARRAY_LEN ( test_strings ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  substituted [ 512 ] ,  tmp [ 512 ]  =  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_set_callerid ( chan ,  test_strings [ i ] [ 0 ] ,  NULL ,  test_strings [ i ] [ 0 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										snprintf ( tmp ,  sizeof ( tmp ) ,  " ${%s} " ,  test_strings [ i ] [ 1 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* test ast_str_substitute_variables */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_str_substitute_variables ( & str ,  0 ,  chan ,  tmp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Comparing STR %s with %s \n " ,  ast_str_buffer ( str ) ,  test_strings [ i ] [ 2 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( strcmp ( test_strings [ i ] [ 2 ] ,  ast_str_buffer ( str ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_test_status_update ( test ,  " Format string '%s' substituted to '%s' using str sub.  Expected '%s'. \n " ,  test_strings [ i ] [ 0 ] ,  ast_str_buffer ( str ) ,  test_strings [ i ] [ 2 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  AST_TEST_FAIL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* test pbx_substitute_variables_helper */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pbx_substitute_variables_helper ( chan ,  tmp ,  substituted ,  sizeof ( substituted )  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Comparing PBX %s with %s \n " ,  substituted ,  test_strings [ i ] [ 2 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( strcmp ( test_strings [ i ] [ 2 ] ,  substituted ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_test_status_update ( test ,  " Format string '%s' substituted to '%s' using pbx sub.  Expected '%s'. \n " ,  test_strings [ i ] [ 0 ] ,  substituted ,  test_strings [ i ] [ 2 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  AST_TEST_FAIL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_release ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  struct  ast_cli_entry  vars_cli [ ]  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_show_globals ,  " Show global dialplan variables " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_show_chanvar ,  " Show channel variables " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-26 21:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_eval_function ,  " Evaluate dialplan function " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_set_global ,  " Set global dialplan variable " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_set_chanvar ,  " Set a channel variable " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  unload_pbx_variables ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cli_unregister_multiple ( vars_cli ,  ARRAY_LEN ( vars_cli ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_unregister_application ( " Set " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_unregister_application ( " MSet " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_clear_globals ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-23 22:17:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AST_TEST_UNREGISTER ( test_variable_substrings ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  load_pbx_variables ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  | =  ast_cli_register_multiple ( vars_cli ,  ARRAY_LEN ( vars_cli ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  | =  ast_register_application2 ( " Set " ,  pbx_builtin_setvar ,  NULL ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  | =  ast_register_application2 ( " MSet " ,  pbx_builtin_setvar_multiple ,  NULL ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_register_cleanup ( unload_pbx_variables ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-23 22:17:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AST_TEST_REGISTER ( test_variable_substrings ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 17:15:14 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}