2004-06-11 00:12:35 +00:00
/*
* Asterisk - - A telephony toolkit for Linux .
*
* Copyright ( C ) 1999 , Mark Spencer
*
* Mark Spencer < markster @ linux - support . net >
*
* res_config_odbc . c < odbc + odbc plugin for portable configuration engine >
* Copyright ( C ) 2004 Anthony Minessale II < anthmct @ yahoo . com >
*/
# include <asterisk/file.h>
# include <asterisk/logger.h>
# include <asterisk/channel.h>
# include <asterisk/pbx.h>
# include <asterisk/config.h>
# include <asterisk/config_pvt.h>
# include <asterisk/module.h>
2004-06-22 18:49:00 +00:00
# include <asterisk/lock.h>
2004-06-11 00:12:35 +00:00
# include <stdlib.h>
# include <unistd.h>
# include <string.h>
# include <asterisk/res_odbc.h>
2004-07-08 20:16:28 +00:00
static char * tdesc = " ODBC Configuration " ;
2004-06-11 00:12:35 +00:00
static struct ast_config_reg reg1 ;
STANDARD_LOCAL_USER ;
LOCAL_USER_DECL ;
2004-07-08 20:16:28 +00:00
static struct ast_config * config_odbc ( char * file , struct ast_config * new_config_s , struct ast_category * * new_cat_p , struct ast_variable * * new_v_p , int recur
2004-06-11 00:12:35 +00:00
# ifdef PRESERVE_COMMENTS
2004-07-08 20:16:28 +00:00
, struct ast_comment_struct * acs
2004-06-11 00:12:35 +00:00
# endif
2004-07-08 20:16:28 +00:00
)
{
struct ast_config * config , * new ;
struct ast_variable * v , * cur_v , * new_v ;
struct ast_category * cur_cat , * new_cat ;
2004-07-14 13:57:15 +00:00
char table [ 128 ] = " " ;
char connection [ 128 ] = " " ;
2004-07-08 20:16:28 +00:00
int configured = 0 , res = 0 ;
odbc_obj * obj ;
2004-07-13 22:53:17 +00:00
SQLINTEGER err = 0 , commented = 0 , cat_metric = 0 , var_metric = 0 , last_cat_metric = 0 ;
2004-07-08 20:16:28 +00:00
SQLBIGINT id ;
2004-11-25 18:13:16 +00:00
char sql [ 255 ] = " " , filename [ 128 ] = " " , category [ 128 ] = " " , var_name [ 128 ] = " " , var_val [ 512 ] = " " ;
2004-07-13 22:53:17 +00:00
SQLSMALLINT rowcount = 0 ;
2004-07-08 20:16:28 +00:00
SQLHSTMT stmt ;
2004-07-14 13:57:15 +00:00
char last [ 80 ] = " " ;
2004-07-08 20:16:28 +00:00
int cat_started = 0 ;
int var_started = 0 ;
if ( new_config_s ) {
new = new_config_s ;
cat_started + + ;
} else {
new = ast_new_config ( ) ;
2004-06-11 00:12:35 +00:00
}
2004-07-08 20:16:28 +00:00
last [ 0 ] = ' \0 ' ;
if ( ! file | | ! strcmp ( file , " res_config_odbc.conf " ) )
return NULL ; // cant configure myself with myself !
config = ast_load ( " res_config_odbc.conf " ) ;
if ( config ) {
for ( v = ast_variable_browse ( config , " settings " ) ; v ; v = v - > next ) {
if ( ! strcmp ( v - > name , " table " ) ) {
2004-07-14 13:57:15 +00:00
strncpy ( table , v - > value , sizeof ( table ) - 1 ) ;
2004-07-08 20:16:28 +00:00
configured + + ;
} else if ( ! strcmp ( v - > name , " connection " ) ) {
2004-07-14 13:57:15 +00:00
strncpy ( connection , v - > value , sizeof ( connection ) - 1 ) ;
2004-07-08 20:16:28 +00:00
configured + + ;
}
}
ast_destroy ( config ) ;
2004-06-11 00:12:35 +00:00
}
2004-07-08 20:16:28 +00:00
if ( configured < 2 )
return NULL ;
obj = fetch_odbc_obj ( connection ) ;
if ( ! obj )
return NULL ;
res = SQLAllocHandle ( SQL_HANDLE_STMT , obj - > con , & stmt ) ;
SQLBindCol ( stmt , 1 , SQL_C_ULONG , & id , sizeof ( id ) , & err ) ;
SQLBindCol ( stmt , 2 , SQL_C_ULONG , & cat_metric , sizeof ( cat_metric ) , & err ) ;
SQLBindCol ( stmt , 3 , SQL_C_ULONG , & var_metric , sizeof ( var_metric ) , & err ) ;
SQLBindCol ( stmt , 4 , SQL_C_ULONG , & commented , sizeof ( commented ) , & err ) ;
SQLBindCol ( stmt , 5 , SQL_C_CHAR , & filename , sizeof ( filename ) , & err ) ;
SQLBindCol ( stmt , 6 , SQL_C_CHAR , & category , sizeof ( category ) , & err ) ;
SQLBindCol ( stmt , 7 , SQL_C_CHAR , & var_name , sizeof ( var_name ) , & err ) ;
SQLBindCol ( stmt , 8 , SQL_C_CHAR , & var_val , sizeof ( var_val ) , & err ) ;
2004-08-23 19:07:15 +00:00
snprintf ( sql , sizeof ( sql ) , " select * from %s where filename='%s' and commented=0 order by filename,cat_metric desc,var_metric asc,category,var_name,var_val,id " , table , file ) ;
2004-07-08 20:16:28 +00:00
res = SQLExecDirect ( stmt , sql , SQL_NTS ) ;
if ( ( res ! = SQL_SUCCESS ) & & ( res ! = SQL_SUCCESS_WITH_INFO ) ) {
ast_log ( LOG_WARNING , " SQL select error! \n [%s] \n \n " , sql ) ;
return NULL ;
2004-06-11 00:12:35 +00:00
}
2004-07-08 20:16:28 +00:00
res = SQLNumResultCols ( stmt , & rowcount ) ;
2004-06-11 00:12:35 +00:00
2004-07-08 20:16:28 +00:00
if ( ( res ! = SQL_SUCCESS ) & & ( res ! = SQL_SUCCESS_WITH_INFO ) ) {
ast_log ( LOG_WARNING , " SQL select error! \n [%s] \n \n " , sql ) ;
return NULL ;
}
2004-06-11 00:12:35 +00:00
2004-07-08 20:16:28 +00:00
if ( rowcount ) {
res = SQLFetch ( stmt ) ;
cat_started = 0 ;
2004-06-11 00:12:35 +00:00
2004-07-08 20:16:28 +00:00
cur_cat = * new_cat_p ;
cur_v = * new_v_p ;
2004-06-11 00:12:35 +00:00
2004-07-08 20:16:28 +00:00
if ( cur_cat )
cat_started = 1 ;
if ( cur_v )
var_started = 1 ;
2004-06-11 00:12:35 +00:00
2004-07-08 20:16:28 +00:00
while ( res ! = SQL_NO_DATA ) {
if ( ! strcmp ( var_name , " #include " ) & & recur < MAX_INCLUDE_LEVEL ) {
2004-06-11 00:12:35 +00:00
2004-07-08 20:16:28 +00:00
config_odbc ( var_val , new , & cur_cat , & cur_v , recur + 1
# ifdef PRESERVE_COMMENTS
, acs
# endif
) ;
} else {
2004-07-09 14:47:59 +00:00
if ( strcmp ( last , category ) | | last_cat_metric ! = cat_metric ) {
2004-07-14 13:57:15 +00:00
strncpy ( last , category , sizeof ( last ) - 1 ) ;
2004-07-09 14:47:59 +00:00
last_cat_metric = cat_metric ;
2004-07-08 20:16:28 +00:00
new_cat = ( struct ast_category * ) ast_new_category ( category ) ;
if ( ! cat_started ) {
cat_started + + ;
new - > root = new_cat ;
cur_cat = new - > root ;
} else {
cur_cat - > next = new_cat ;
cur_cat = cur_cat - > next ;
}
var_started = 0 ;
}
new_v = ast_new_variable ( var_name , var_val ) ;
if ( ! var_started ) {
var_started + + ;
cur_cat - > root = new_v ;
cur_v = cur_cat - > root ;
} else {
cur_v - > next = new_v ;
cur_v = cur_v - > next ;
}
}
// next row
res = SQLFetch ( stmt ) ;
}
SQLFreeHandle ( SQL_HANDLE_STMT , stmt ) ;
} else {
ast_log ( LOG_NOTICE , " found nothing \n " ) ;
}
return new ;
2004-06-11 00:12:35 +00:00
2004-07-08 20:16:28 +00:00
}
2004-06-11 00:12:35 +00:00
2004-07-08 20:16:28 +00:00
int unload_module ( void )
2004-06-11 00:12:35 +00:00
{
2004-07-08 20:16:28 +00:00
ast_cust_config_deregister ( & reg1 ) ;
ast_log ( LOG_NOTICE , " res_config_odbc unloaded. \n " ) ;
2004-06-11 00:12:35 +00:00
STANDARD_HANGUP_LOCALUSERS ;
return 0 ;
}
2004-07-08 20:16:28 +00:00
int load_module ( void )
2004-06-11 00:12:35 +00:00
{
2004-07-08 20:16:28 +00:00
memset ( & reg1 , 0 , sizeof ( struct ast_config_reg ) ) ;
2004-07-14 13:57:15 +00:00
strncpy ( reg1 . name , " odbc " , sizeof ( reg1 . name ) - 1 ) ;
2004-06-11 00:12:35 +00:00
reg1 . func = config_odbc ;
2004-07-08 20:16:28 +00:00
ast_cust_config_register ( & reg1 ) ;
ast_log ( LOG_NOTICE , " res_config_odbc loaded. \n " ) ;
2004-06-11 00:12:35 +00:00
return 0 ;
}
2004-07-08 20:16:28 +00:00
char * description ( void )
2004-06-11 00:12:35 +00:00
{
2004-07-08 20:16:28 +00:00
return tdesc ;
2004-06-11 00:12:35 +00:00
}
2004-07-08 20:16:28 +00:00
int usecount ( void )
2004-06-11 00:12:35 +00:00
{
/* never unload a config module */
return 1 ;
}
2004-07-08 20:16:28 +00:00
char * key ( )
2004-06-11 00:12:35 +00:00
{
2004-07-08 20:16:28 +00:00
return ASTERISK_GPL_KEY ;
2004-06-11 00:12:35 +00:00
}