2004-10-06 15:52:01 +00:00
/*
* Asterisk - - A telephony toolkit for Linux .
*
2004-10-06 17:42:31 +00:00
* RealTime App
2004-10-06 15:52:01 +00:00
*
* Copyright ( C ) 1999 - 2004 , Digium , Inc .
*
* Anthony Minessale < anthmct @ yahoo . com >
* Mark Spencer < markster @ digium . com >
*
* This program is free software , distributed under the terms of
* the GNU General Public License
*/
2004-10-06 17:42:31 +00:00
2004-10-06 15:52:01 +00:00
# include <asterisk/file.h>
# include <asterisk/logger.h>
# include <asterisk/channel.h>
# include <asterisk/options.h>
# include <asterisk/pbx.h>
# include <asterisk/config.h>
# include <asterisk/module.h>
# include <asterisk/lock.h>
2004-10-14 04:17:34 +00:00
# include <asterisk/cli.h>
2004-10-06 15:52:01 +00:00
# include <stdlib.h>
# include <unistd.h>
# include <string.h>
2004-10-06 17:42:31 +00:00
2004-10-06 15:52:01 +00:00
# define next_one(var) var = var->next
# define crop_data(str) { *(str) = '\0' ; (str)++; }
2004-10-06 17:42:31 +00:00
static char * tdesc = " Realtime Data Lookup/Rewrite " ;
2004-10-06 15:52:01 +00:00
static char * app = " RealTime " ;
2004-10-06 17:42:31 +00:00
static char * uapp = " RealTimeUpdate " ;
2004-10-06 15:52:01 +00:00
static char * synopsis = " Realtime Data Lookup " ;
2004-10-06 17:42:31 +00:00
static char * usynopsis = " Realtime Data Rewrite " ;
2004-10-06 15:52:01 +00:00
static char * USAGE = " RealTime(<family>|<colmatch>|<value>[|<prefix>]) " ;
2004-10-06 17:42:31 +00:00
static char * UUSAGE = " RealTimeUpdate(<family>|<colmatch>|<value>|<newcol>|<newval>) " ;
2004-10-06 15:52:01 +00:00
static char * desc = " Use the RealTime config handler system to read data into channel variables. \n "
" RealTime(<family>|<colmatch>|<value>[|<prefix>]) \n \n "
" All unique column names will be set as channel variables with optional prefix to the name. \n "
" e.g. prefix of 'var_' would make the column 'name' become the variable ${var_name} \n \n " ;
2004-10-06 17:42:31 +00:00
static char * udesc = " Use the RealTime config handler system to update a value \n "
" RealTimeUpdate(<family>|<colmatch>|<value>|<newcol>|<newval>) \n \n "
" The column <newcol> in 'family' matching column <colmatch>=<value> will be updated to <newval> \n " ;
2004-10-06 15:52:01 +00:00
2004-10-06 17:42:31 +00:00
STANDARD_LOCAL_USER ;
LOCAL_USER_DECL ;
2004-10-06 15:52:01 +00:00
2004-10-14 04:17:34 +00:00
static int cli_load_realtime ( int fd , int argc , char * * argv )
{
char * header_format = " %30s %-30s \n " ;
struct ast_variable * var = NULL ;
if ( argc < 5 ) {
ast_cli ( fd , " You must supply a family name, a column to match on, and a value to match to. \n " ) ;
return RESULT_FAILURE ;
}
var = ast_load_realtime ( argv [ 2 ] , argv [ 3 ] , argv [ 4 ] , NULL ) ;
if ( var ) {
ast_cli ( fd , header_format , " Column Name " , " Column Value " ) ;
ast_cli ( fd , header_format , " -------------------- " , " -------------------- " ) ;
while ( var ) {
ast_cli ( fd , header_format , var - > name , var - > value ) ;
var = var - > next ;
}
} else {
ast_cli ( fd , " No rows found matching search criteria. \n " ) ;
}
return RESULT_SUCCESS ;
}
static int cli_update_realtime ( int fd , int argc , char * * argv ) {
int res = 0 ;
if ( argc < 7 ) {
ast_cli ( fd , " You must supply a family name, a column to update on, a new value, column to match, and value to to match. \n " ) ;
ast_cli ( fd , " Ex: realtime update sipfriends name bobsphone port 4343 \n will execute SQL as UPDATE sipfriends SET port = 4343 WHERE name = bobsphone \n " ) ;
return RESULT_FAILURE ;
}
res = ast_update_realtime ( argv [ 2 ] , argv [ 3 ] , argv [ 4 ] , argv [ 5 ] , argv [ 6 ] , NULL ) ;
if ( res < 0 ) {
ast_cli ( fd , " Failed to update. Check the debug log for possible SQL related entries. \n " ) ;
return RESULT_SUCCESS ;
}
ast_cli ( fd , " Updated RealTime record. \n " ) ;
return RESULT_SUCCESS ;
}
static char cli_load_realtime_usage [ ] =
" Usage: realtime load <family> <colmatch> <value> \n "
" Prints out a list of variables using the RealTime driver. \n " ;
static struct ast_cli_entry cli_load_realtime_cmd = {
{ " realtime " , " load " , NULL , NULL } , cli_load_realtime ,
" Used to print out RealTime variables. " , cli_load_realtime_usage , NULL } ;
static char cli_update_realtime_usage [ ] =
" Usage: realtime update <family> <colmatch> <value> \n "
" Update a single variable using the RealTime driver. \n " ;
static struct ast_cli_entry cli_update_realtime_cmd = {
{ " realtime " , " update " , NULL , NULL } , cli_update_realtime ,
" Used to update RealTime variables. " , cli_update_realtime_usage , NULL } ;
static int realtime_update_exec ( struct ast_channel * chan , void * data )
{
2004-10-06 17:42:31 +00:00
char * family = NULL , * colmatch = NULL , * value = NULL , * newcol = NULL , * newval = NULL ;
struct localuser * u ;
int res = 0 ;
if ( ! data ) {
ast_log ( LOG_ERROR , " Invalid input %s \n " , UUSAGE ) ;
return - 1 ;
}
LOCAL_USER_ADD ( u ) ;
if ( ( family = ast_strdupa ( data ) ) ) {
if ( ( colmatch = strchr ( family , ' | ' ) ) ) {
crop_data ( colmatch ) ;
if ( ( value = strchr ( colmatch , ' | ' ) ) ) {
crop_data ( value ) ;
if ( ( newcol = strchr ( value , ' | ' ) ) ) {
crop_data ( newcol ) ;
if ( ( newval = strchr ( newcol , ' | ' ) ) )
crop_data ( newval ) ;
}
}
}
}
if ( ! ( family & & value & & colmatch & & newcol & & newval ) ) {
ast_log ( LOG_ERROR , " Invalid input: usage %s \n " , UUSAGE ) ;
res = - 1 ;
} else {
ast_update_realtime ( family , colmatch , value , newcol , newval , NULL ) ;
}
2004-10-06 15:52:01 +00:00
2004-10-06 17:42:31 +00:00
LOCAL_USER_REMOVE ( u ) ;
return res ;
2004-10-06 15:52:01 +00:00
2004-10-06 17:42:31 +00:00
}
2004-10-06 15:52:01 +00:00
static int realtime_exec ( struct ast_channel * chan , void * data )
{
int res = 0 ;
struct localuser * u ;
struct ast_variable * var , * itt ;
char * family = NULL , * colmatch = NULL , * value = NULL , * prefix = NULL , * vname = NULL ;
size_t len ;
if ( ! data ) {
ast_log ( LOG_ERROR , " Invalid input: usage %s \n " , USAGE ) ;
return - 1 ;
}
LOCAL_USER_ADD ( u ) ;
if ( ( family = ast_strdupa ( data ) ) ) {
if ( ( colmatch = strchr ( family , ' | ' ) ) ) {
crop_data ( colmatch ) ;
if ( ( value = strchr ( colmatch , ' | ' ) ) ) {
crop_data ( value ) ;
if ( ( prefix = strchr ( value , ' | ' ) ) )
crop_data ( prefix ) ;
}
}
}
if ( ! ( family & & value & & colmatch ) ) {
ast_log ( LOG_ERROR , " Invalid input: usage %s \n " , USAGE ) ;
res = - 1 ;
} else {
if ( option_verbose > 3 )
ast_verbose ( VERBOSE_PREFIX_4 " Realtime Lookup: family:'%s' colmatch:'%s' value:'%s' \n " , family , colmatch , value ) ;
2004-10-07 19:57:50 +00:00
if ( ( var = ast_load_realtime ( family , colmatch , value , NULL ) ) ) {
2004-10-06 15:52:01 +00:00
for ( itt = var ; itt ; itt = itt - > next ) {
if ( prefix ) {
len = strlen ( prefix ) + strlen ( itt - > name ) + 2 ;
vname = alloca ( len ) ;
snprintf ( vname , len , " %s%s " , prefix , itt - > name ) ;
} else
vname = itt - > name ;
pbx_builtin_setvar_helper ( chan , vname , itt - > value ) ;
}
ast_destroy_realtime ( var ) ;
} else if ( option_verbose > 3 )
ast_verbose ( VERBOSE_PREFIX_4 " No Realtime Matches Found. \n " ) ;
}
LOCAL_USER_REMOVE ( u ) ;
return res ;
}
int unload_module ( void )
{
STANDARD_HANGUP_LOCALUSERS ;
2004-10-14 04:17:34 +00:00
ast_cli_unregister ( & cli_load_realtime_cmd ) ;
ast_cli_unregister ( & cli_update_realtime_cmd ) ;
2004-10-06 17:42:31 +00:00
ast_unregister_application ( uapp ) ;
2004-10-06 15:52:01 +00:00
return ast_unregister_application ( app ) ;
}
int load_module ( void )
{
2004-10-14 04:17:34 +00:00
ast_cli_register ( & cli_load_realtime_cmd ) ;
ast_cli_register ( & cli_update_realtime_cmd ) ;
2004-10-06 17:42:31 +00:00
ast_register_application ( uapp , realtime_update_exec , usynopsis , udesc ) ;
2004-10-06 15:52:01 +00:00
return ast_register_application ( app , realtime_exec , synopsis , desc ) ;
}
char * description ( void )
{
return tdesc ;
}
int usecount ( void )
{
int res ;
STANDARD_USECOUNT ( res ) ;
return res ;
}
char * key ( )
{
return ASTERISK_GPL_KEY ;
}