2004-10-06 15:52:01 +00:00
/*
2005-09-14 20:46:50 +00:00
* Asterisk -- An open source telephony toolkit.
2004-10-06 15:52:01 +00:00
*
2005-01-21 07:06:25 +00:00
* Copyright (C) 1999 - 2005, Digium, Inc.
2004-10-06 15:52:01 +00:00
*
* Anthony Minessale <anthmct@yahoo.com>
* Mark Spencer <markster@digium.com>
*
2005-09-14 20:46:50 +00:00
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
2004-10-06 15:52:01 +00:00
* This program is free software, distributed under the terms of
2005-09-14 20:46:50 +00:00
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
*/
2005-10-24 20:12:06 +00:00
/*! \file
2005-09-14 20:46:50 +00:00
*
2005-10-24 20:12:06 +00:00
* \brief RealTime App
2005-12-30 21:18:06 +00:00
*
* \author Anthony Minessale <anthmct@yahoo.com>
* \author Mark Spencer <markster@digium.com>
2005-09-14 20:46:50 +00:00
*
2005-11-06 15:09:47 +00:00
* \ingroup applications
2004-10-06 15:52:01 +00:00
*/
2004-10-06 17:42:31 +00:00
2006-06-07 18:54:56 +00:00
#include "asterisk.h"
ASTERISK_FILE_VERSION ( __FILE__ , "$Revision$" )
2005-06-06 22:39:32 +00:00
#include <stdlib.h>
2005-11-08 04:48:00 +00:00
#include <stdio.h>
2005-06-06 22:39:32 +00:00
#include <string.h>
2005-11-08 04:48:00 +00:00
#include <unistd.h>
2005-06-06 22:39:32 +00:00
2005-04-21 06:02:45 +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"
#include "asterisk/cli.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)++; }
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>)" ;
2005-12-21 15:16:08 +00:00
static char * desc =
"Use the RealTime config handler system to read data into channel variables. \n "
2004-10-06 15:52:01 +00:00
"RealTime(<family>|<colmatch>|<value>[|<prefix>]) \n\n "
2005-12-21 15:16:08 +00:00
"All unique column names will be set as channel variables with optional prefix \n "
"to the name. For example, a prefix of 'var_' would make the column 'name' \n "
"become the variable ${var_name}. REALTIMECOUNT will be set with the number \n "
"of values read. \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 "
2005-12-21 15:16:08 +00:00
"The column <newcol> in 'family' matching column <colmatch>=<value> will be \n "
"updated to <newval>. REALTIMECOUNT will be set with the number of rows \n "
"updated or -1 if an error occurs. \n " ;
2004-10-06 15:52:01 +00:00
2006-09-18 19:54:18 +00:00
static int cli_realtime_load ( int fd , int argc , char ** argv )
2004-10-14 04:17:34 +00:00
{
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 ;
}
2006-09-18 19:54:18 +00:00
static int cli_realtime_update ( int fd , int argc , char ** argv ) {
2004-10-14 04:17:34 +00:00
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 ;
}
2005-07-07 22:32:20 +00:00
ast_cli ( fd , "Updated %d RealTime record%s. \n " , res , ( res != 1 ) ? "s" : "" );
2004-10-14 04:17:34 +00:00
return RESULT_SUCCESS ;
}
2006-09-18 19:54:18 +00:00
static char cli_realtime_load_usage [] =
2004-10-14 04:17:34 +00:00
"Usage: realtime load <family> <colmatch> <value> \n "
" Prints out a list of variables using the RealTime driver. \n " ;
2006-09-18 19:54:18 +00:00
static char cli_realtime_update_usage [] =
2004-10-14 04:17:34 +00:00
"Usage: realtime update <family> <colmatch> <value> \n "
" Update a single variable using the RealTime driver. \n " ;
2006-09-18 19:54:18 +00:00
static struct ast_cli_entry cli_realtime [] = {
{ { "realtime" , "load" , NULL , NULL },
cli_realtime_load , "Used to print out RealTime variables." ,
cli_realtime_load_usage , NULL },
{ { "realtime" , "update" , NULL , NULL },
cli_realtime_update , "Used to update RealTime variables." ,
cli_realtime_update_usage , NULL },
};
2004-10-14 04:17:34 +00:00
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 ;
2006-08-21 02:11:39 +00:00
struct ast_module_user * u ;
2005-12-21 15:16:08 +00:00
int res = 0 , count = 0 ;
char countc [ 13 ];
2005-10-19 18:19:02 +00:00
2006-05-02 22:46:12 +00:00
ast_log ( LOG_WARNING , "The RealTimeUpdate application has been deprecated in favor of the REALTIME dialplan function. \n " );
2005-10-26 19:48:14 +00:00
if ( ast_strlen_zero ( data )) {
2005-10-19 18:19:02 +00:00
ast_log ( LOG_ERROR , "Invalid input: usage %s \n " , UUSAGE );
return - 1 ;
}
2006-08-21 02:11:39 +00:00
u = ast_module_user_add ( chan );
2005-10-19 18:19:02 +00:00
2006-05-10 13:22:15 +00:00
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 );
2004-10-06 17:42:31 +00:00
}
}
}
2006-01-21 17:50:04 +00:00
if ( ! ( family && value && colmatch && newcol && newval ) ) {
2004-10-06 17:42:31 +00:00
ast_log ( LOG_ERROR , "Invalid input: usage %s \n " , UUSAGE );
res = - 1 ;
} else {
2005-12-21 15:16:08 +00:00
count = ast_update_realtime ( family , colmatch , value , newcol , newval , NULL );
2004-10-06 17:42:31 +00:00
}
2004-10-06 15:52:01 +00:00
2005-12-21 15:16:08 +00:00
snprintf ( countc , sizeof ( countc ), "%d" , count );
pbx_builtin_setvar_helper ( chan , "REALTIMECOUNT" , countc );
2006-08-21 02:11:39 +00:00
ast_module_user_remove ( u );
2005-10-19 18:19:02 +00:00
2004-10-06 17:42:31 +00:00
return res ;
}
2004-10-06 15:52:01 +00:00
static int realtime_exec ( struct ast_channel * chan , void * data )
{
2005-12-21 15:16:08 +00:00
int res = 0 , count = 0 ;
2006-08-21 02:11:39 +00:00
struct ast_module_user * u ;
2004-10-06 15:52:01 +00:00
struct ast_variable * var , * itt ;
char * family = NULL , * colmatch = NULL , * value = NULL , * prefix = NULL , * vname = NULL ;
2005-12-21 15:16:08 +00:00
char countc [ 13 ];
2004-10-06 15:52:01 +00:00
size_t len ;
2005-10-19 18:19:02 +00:00
2006-05-02 22:46:12 +00:00
ast_log ( LOG_WARNING , "The RealTime application has been deprecated in favor of the REALTIME dialplan function. \n " );
2005-10-26 19:48:14 +00:00
if ( ast_strlen_zero ( data )) {
2004-10-06 15:52:01 +00:00
ast_log ( LOG_ERROR , "Invalid input: usage %s \n " , USAGE );
return - 1 ;
}
2005-10-19 18:19:02 +00:00
2006-08-21 02:11:39 +00:00
u = ast_module_user_add ( chan );
2005-10-19 18:19:02 +00:00
2006-05-10 13:22:15 +00:00
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 );
2004-10-06 15:52:01 +00:00
}
}
2006-01-21 17:50:04 +00:00
if ( ! ( family && value && colmatch ) ) {
2004-10-06 15:52:01 +00:00
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 );
2005-12-21 15:16:08 +00:00
count ++ ;
2004-10-06 15:52:01 +00:00
}
2005-01-25 06:10:20 +00:00
ast_variables_destroy ( var );
2004-10-06 15:52:01 +00:00
} else if ( option_verbose > 3 )
ast_verbose ( VERBOSE_PREFIX_4 "No Realtime Matches Found. \n " );
}
2005-12-21 15:16:08 +00:00
snprintf ( countc , sizeof ( countc ), "%d" , count );
pbx_builtin_setvar_helper ( chan , "REALTIMECOUNT" , countc );
2004-10-06 15:52:01 +00:00
2006-08-21 02:11:39 +00:00
ast_module_user_remove ( u );
2004-10-06 15:52:01 +00:00
return res ;
}
2006-08-21 02:11:39 +00:00
static int unload_module ( void )
2004-10-06 15:52:01 +00:00
{
2005-10-18 22:52:21 +00:00
int res ;
2006-09-18 19:54:18 +00:00
ast_cli_unregister_multiple ( cli_realtime , sizeof ( cli_realtime ) / sizeof ( struct ast_cli_entry ));
res = ast_unregister_application ( uapp );
2005-10-18 22:52:21 +00:00
res |= ast_unregister_application ( app );
2006-08-21 02:11:39 +00:00
ast_module_user_hangup_all ();
2005-10-18 22:52:21 +00:00
return res ;
2004-10-06 15:52:01 +00:00
}
2006-08-21 02:11:39 +00:00
static int load_module ( void )
2004-10-06 15:52:01 +00:00
{
2005-10-18 22:52:21 +00:00
int res ;
2006-09-18 19:54:18 +00:00
ast_cli_register_multiple ( cli_realtime , sizeof ( cli_realtime ) / sizeof ( struct ast_cli_entry ));
res = ast_register_application ( uapp , realtime_update_exec , usynopsis , udesc );
2005-10-18 22:52:21 +00:00
res |= ast_register_application ( app , realtime_exec , synopsis , desc );
return res ;
2004-10-06 15:52:01 +00:00
}
2006-08-21 02:11:39 +00:00
AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY , "Realtime Data Lookup/Rewrite" );