Ok, sorry for the response on the same thread.

This is a new one.

 

The main thing is that with this I set the Store Procedure or Query directly
on the dialplan line, is easier to configure, change, manage, etc.

I also know that works great with heavy load, and it reconnects when the
network goes down and up.

 

Can you help me porting this app? I think woun`t be difficult for someone
that has port other app.

 

 

Attachments: (app_odbcexec) working great on 1.2

             (app_odbcexec1.6) my try to port to 1.6

 

Any idea?? Anybody?

 

Should this be on development list?

 

Thanks



/*
 * Asterisk -- A telephony toolkit for Linux.
 *
 * ODBC exec function
 *
 * Robert Hanzlik <[EMAIL PROTECTED]>
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License
 *
 * Copyright (c) Digium
 * 
 * Based on work by Mark Spencer and Jefferson Noxon - app_db.c
 * and Brian K. West - app_dbodbc.c
 *
 */

#include <sys/types.h>
#include <stdio.h>
#include <asterisk/options.h>
#include <asterisk/config.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/pbx.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>

#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>

static char *tdesc = "Database query functions for Asterisk extension logic";

static char *q_descrip =
  "  ODBCquery(varname=query): Retrieves a value from the database query\n"
  "and stores it in the given variable.  Always returns 0.  If the\n"
  "query failes, jumps to priority n+101 if available.\n";

static char *e_descrip =
  "  ODBCexec(query): Executes a database query. Always returns 0.\n"
  "If the query failes, jumps to priority n+101 if available.\n";

static char *q_app = "ODBCquery";
static char *e_app = "ODBCexec";

static char *q_synopsis = "Retrieve a value from a ODBC query";
static char *e_synopsis = "Execute a ODBC query";

AST_MUTEX_DEFINE_STATIC(odbc_lock);

static SQLHENV                  HOdbcEnv;
static int      ODBC_res;                       /* global ODBC Result of 
Functions */
static SQLHDBC  ODBC_con;                       /* global ODBC Connection 
Handle */
static SQLHSTMT ODBC_stmt;                      /* global ODBC Statement Handle 
*/

static char *config = "odbcexec.conf";
static char *dsn = NULL, *username = NULL, *password = NULL;
static int dsn_alloc = 0, username_alloc = 0, password_alloc = 0;
static int connected = 0;

static int ast_odbcexec(const char *query, char *out, int outlen);
static int odbc_load_module(void);
static int odbc_init(void);
static int odbc_unload_module(void);
static int odbc_do_query(char *sqlcmd);
static void reconect(void);

STANDARD_LOCAL_USER;

LOCAL_USER_DECL;

void LogErrMsg(char * source, long rc,SQLSMALLINT HandleType,SQLHANDLE Handle);

void LogErrMsg(char * source, long rc,SQLSMALLINT HandleType,SQLHANDLE Handle)
{
        SQLSMALLINT len;
        SQLCHAR             msg[200],buffer[200];
        SQLCHAR             sqlstat[10];
        
        ast_log(LOG_ERROR, "Error %s %d\n",source,rc);
        SQLGetDiagRec(HandleType,Handle,1, 
                        sqlstat, &rc,msg,100,&len);
        ast_log(LOG_ERROR, "%s (%d)\n",msg,rc);
}


static int odbcexec_exec(struct ast_channel *chan, void *data)
{
        int arglen, res;
        char *argv;

        arglen = strlen (data);
        argv = alloca (arglen + 1);
        if (!argv)                      /* Why would this fail? */
        {
                ast_log (LOG_DEBUG, "Memory allocation failed\n");
                return 0;
        }

        memcpy (argv, data, arglen + 1);
        
        if (option_verbose > 2)
                ast_verbose (VERBOSE_PREFIX_3 "odbcexec: query=%s\n", argv);

        ast_mutex_lock(&odbc_lock);
        res = odbc_do_query(argv);
        ast_mutex_unlock(&odbc_lock);
        if(res==-1) {
                if (option_verbose > 2)
                        ast_verbose (VERBOSE_PREFIX_3 "odbcexec: Query 
failed.\n");
                  /* Send the call to n+101 priority, where n is the current 
priority */
                
                if (ast_exists_extension (chan, chan->context, chan->exten, 
chan->priority + 101, chan->cid.cid_num))
                        chan->priority += 100;
        }
        return 0;
}

static int odbcexec_query(struct ast_channel *chan, void *data)
{
        int arglen;
        char *argv, *varname, *query;
        char dbresult[256];

        arglen = strlen (data);
        argv = alloca (arglen + 1);
        if (!argv)                      /* Why would this fail? */
        {
                ast_log (LOG_DEBUG, "Memory allocation failed\n");
                return 0;
        }

        memcpy (argv, data, arglen + 1);

        if (strchr (argv, '='))
        {
                varname = strsep (&argv, "=");
                query = strsep (&argv, "\0");
                if (!varname || !query)
                {
                        ast_log (LOG_DEBUG, "Ignoring; Syntax error in 
argument\n");
                        return 0;
                }

                if (option_verbose > 2)
                        ast_verbose (VERBOSE_PREFIX_3 "odbcquery: varname=%s, 
query=%s\n", varname, query);

                if (!ast_odbcexec (query, dbresult, sizeof (dbresult) - 1))
                {
                        pbx_builtin_setvar_helper (chan, varname, dbresult);
                        if (option_verbose > 2)
                                ast_verbose (VERBOSE_PREFIX_3 "odbcquery: set 
variable %s to %s\n", varname, dbresult);
                }
                else
                {
                        if (option_verbose > 2)
                                ast_verbose (VERBOSE_PREFIX_3 "odbcquery: Value 
not found in database.\n");
                          /* Send the call to n+101 priority, where n is the 
current priority */
                        if (ast_exists_extension (chan, chan->context, 
chan->exten, chan->priority + 101, chan->cid.cid_num))
                                chan->priority += 100;
                }

        }
        else
        {
                ast_log (LOG_DEBUG, "Ignoring, no parameters\n");
        }

        return 0;
}

static int odbc_init(void)
{
        long int ODBC_err;
        short int ODBC_mlen;
        char ODBC_msg[200], ODBC_stat[10];

        ast_verbose(VERBOSE_PREFIX_3 "odbc_init called\n");
        
        if ( HOdbcEnv == SQL_NULL_HANDLE || !connected)
        {
                ODBC_res = SQLAllocEnv(&HOdbcEnv);
                if (!SQL_SUCCEEDED(ODBC_res)) {
                        ast_log(LOG_ERROR, "SQLAllocEnv failed\n");
                        return -1;
                }
        
                ODBC_res = SQLAllocConnect(HOdbcEnv, &ODBC_con);
                if (!SQL_SUCCEEDED(ODBC_res)) {
                        ast_log(LOG_ERROR, "SQLAllocConnect failed\n");
                        SQLFreeHandle(SQL_HANDLE_ENV, HOdbcEnv);
                        HOdbcEnv=NULL;
                        return -1;
                }
        }

        ODBC_res = SQLConnect(ODBC_con, (SQLCHAR*)dsn, SQL_NTS, 
(SQLCHAR*)username, SQL_NTS, (SQLCHAR*)password, SQL_NTS);

        if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
        {
                if(option_verbose > 3)
                        ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: Error 
SQLConnect %d\n", ODBC_res);
                LogErrMsg("SQLConnect", ODBC_res, SQL_HANDLE_DBC, ODBC_con);
                SQLFreeHandle(SQL_HANDLE_ENV, HOdbcEnv);
                connected = 0;
                return -1;
        }
        else
        {
                if(option_verbose > 3)
                        ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: Connected 
to %s\n", dsn);
                connected = 1;
        }

        return 0;
}

static int odbc_load_module(void)
{
        int retval;
        int res;
        struct ast_config *cfg;
        struct ast_variable *var;
        char *tmp;

        cfg = ast_config_load(config);
        if (!cfg)
        {
                ast_log(LOG_WARNING, "app_odbcexec: Unable to load config for 
unixODBC: %s\n", config);
                return 0;
        }
        
        var = ast_variable_browse(cfg, "global");
        if (!var) {
                /* nothing configured */
                return 0;
        }

        tmp = ast_variable_retrieve(cfg,"global","dsn");
        if (tmp)
        {
                dsn = malloc(strlen(tmp) + 1);
                if (dsn != NULL)
                {
                        dsn_alloc = 1;
                        strcpy(dsn,tmp);
                }
                else
                {
                        ast_log(LOG_ERROR,"app_odbcexec: Out of memory 
error.\n");
                        return -1;
                }
        }
        else
        {
                ast_log(LOG_WARNING,"app_odbcexec: dsn not specified.  Assuming 
asteriskdb\n");
                dsn = "asteriskdb";
        }

        tmp = ast_variable_retrieve(cfg,"global","username");
        if (tmp)
        {
                username = malloc(strlen(tmp) + 1);
                if (username != NULL)
                {
                        username_alloc = 1;
                        strcpy(username,tmp);
                }
                else
                {
                        ast_log(LOG_ERROR,"app_odbcexec: Out of memory 
error.\n");
                        return -1;
                }
        }
        else
        {
                ast_log(LOG_WARNING,"app_odbcexec: username not specified.  
Assuming root\n");
                username = "root";
        }

        tmp = ast_variable_retrieve(cfg,"global","password");
        if (tmp)
        {
                password = malloc(strlen(tmp) + 1);
                if (password != NULL)
                {
                        password_alloc = 1;
                        strcpy(password,tmp);
                }
                else
                {
                        ast_log(LOG_ERROR,"app_odbcexec: Out of memory 
error.\n");
                        return -1;
                }
        }
        else
        {
                ast_log(LOG_WARNING,"app_odbcexec: database password not 
specified.  Assuming blank\n");
                password = "";
        }

        ast_config_destroy(cfg);
        if(option_verbose > 3)
        {
                ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: dsn is %s\n",dsn);
                ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: username is 
%s\n",username);
                ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: password is 
[secret]\n");

        }
        
        res = odbc_init();
        if(res < 0)
        {
                ast_log(LOG_ERROR, "app_odbcexec: Unable to connect to 
datasource: %s\n", dsn);
                ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: Unable to connect 
to datasource: %s\n", dsn);
        }

        retval = ast_register_application (q_app, odbcexec_query, q_synopsis, 
q_descrip);
        if (!retval)
                retval = ast_register_application (e_app, odbcexec_exec, 
e_synopsis, e_descrip);
        return retval;
}

static int odbc_do_query(char *sqlcmd)
{
        long int ODBC_err;
        short int ODBC_mlen;
        char ODBC_msg[200], ODBC_stat[10];
                int res2;

        ODBC_res = SQLAllocHandle(SQL_HANDLE_STMT, ODBC_con, &ODBC_stmt);

        if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
        {
                if(option_verbose > 3)
                        ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: Failure in 
AllocStatement %d\n", ODBC_res);
                LogErrMsg("SQLAllocHandle",ODBC_res,SQL_HANDLE_STMT,ODBC_con);
                SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);      
                connected = 0;
                reconect();
                
                return -1;
        }

        ODBC_res = SQLPrepare(ODBC_stmt, sqlcmd, SQL_NTS);


        if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
        {
                if(option_verbose > 3)
                        ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: Error in 
PREPARE %d\n", ODBC_res);
                LogErrMsg("SQLPrepare", ODBC_res, SQL_HANDLE_DBC, ODBC_con);
                SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
                reconect();
                return -1;
        }

        ODBC_res = SQLExecute(ODBC_stmt);

        if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
        {
                if(option_verbose > 3)
                        ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: Error in 
Query %d\n", ODBC_res);
                LogErrMsg("SQLExecute",ODBC_res,SQL_HANDLE_STMT,ODBC_stmt);
                SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
                connected = 0;
                return -1;
        }
        else
        {
                if(option_verbose > 3)
                        ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: Query 
Successful!\n");
                connected = 1;
        }
        return 0;
}

static void reconect(void)
{
        int res;

        if (connected)
        {
                SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
                SQLDisconnect(ODBC_con);
                SQLFreeHandle(SQL_HANDLE_DBC, ODBC_con);
                SQLFreeHandle(SQL_HANDLE_ENV, HOdbcEnv);
                connected = 0;
        
        }

        res = odbc_init();
        if(res < 0)
        {
                ast_log(LOG_ERROR, "app_odbcexec: Unable to connect to 
datasource: %s\n", dsn);
                ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: Unable to connect 
to datasource: %s\n", dsn);
        }


}

static int odbc_unload_module(void)
{
        int retval;
        if (connected)
        {
                if(option_verbose > 3)
                        ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: 
Disconnecting from %s\n", dsn);
                SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
                SQLDisconnect(ODBC_con);
                SQLFreeHandle(SQL_HANDLE_DBC, ODBC_con);
                SQLFreeHandle(SQL_HANDLE_ENV, HOdbcEnv);
                connected = 0;
        }
        if (dsn && dsn_alloc)
        {
                if(option_verbose > 3)
                        ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: free 
dsn\n");
                free(dsn);
                dsn = NULL;
                dsn_alloc = 0;
        }
        if (username && username_alloc)
        {
                if(option_verbose > 3)
                        ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: free 
username\n");
                free(username);
                username = NULL;
                username_alloc = 0;
        }
        if (password && password_alloc)
        {
                if(option_verbose > 3)
                        ast_verbose( VERBOSE_PREFIX_4 "app_odbcexec: free 
password\n");
                free(password);
                password = NULL;
                password_alloc = 0;
        }
        retval = ast_unregister_application (q_app);
        retval |= ast_unregister_application (e_app);
        return retval;
}

static int ast_odbcexec(const char *query, char *value, int valuelen)
{
        int res;
        long int ODBC_err;
        char sqlcmd[1024];
        char tmp[256] = "";
        memset(sqlcmd,0,1024);
        ast_mutex_lock(&odbc_lock);
        sprintf(sqlcmd, "%s", query);
        res = odbc_do_query(sqlcmd);
        SQLBindCol(ODBC_stmt, 1, SQL_C_CHAR, &tmp, 50, &ODBC_err);
        if((ODBC_res = SQLFetch(ODBC_stmt) != SQL_NO_DATA))
        {
                strcpy(value, tmp);
        }
        else
        {
                res = -1;
        }
        SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
        ast_mutex_unlock(&odbc_lock);
        return res;
}

int unload_module (void)
{
        STANDARD_HANGUP_LOCALUSERS;
        return odbc_unload_module();
}

int reload(void)
{
        connected = 0;
        odbc_unload_module();
        return odbc_load_module();
}

int load_module (void)
{

        return odbc_load_module();
}

char *description (void)
{
        return tdesc;
}

int usecount (void)
{
        int res;
        STANDARD_USECOUNT (res);
        return res;
}

char *key ()
{
        return ASTERISK_GPL_KEY;
}
/*
 * Asterisk -- A telephony toolkit for Linux.
 *
 * ODBC exec function
 *
 * Robert Hanzlik <[EMAIL PROTECTED]>
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License
 *
 * Copyright (c) Digium
 * 
 * Based on work by Mark Spencer and Jefferson Noxon - app_db.c
 * and Brian K. West - app_dbodbc.c
 *
 */

#include <asterisk.h>



#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/app.h>
#include <asterisk/channel.h>
#include <asterisk/config.h>





#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>

#define AST_MODULE "app_odbcexec"

static char *tdesc = "Database query functions for Asterisk extension logic";

static char *q_descrip =
  "  ODBCquery(varname=query): Retrieves a value from the database query\n"
  "and stores it in the given variable.  Always returns 0.  If the\n"
  "query failes, jumps to priority n+101 if available.\n";

static char *e_descrip =
  "  ODBCexec(query): Executes a database query. Always returns 0.\n"
  "If the query failes, jumps to priority n+101 if available.\n";

static char *q_app = "ODBCquery";
static char *e_app = "ODBCexec";

static char *q_synopsis = "Retrieve a value from a ODBC query";
static char *e_synopsis = "Execute a ODBC query";

AST_MUTEX_DEFINE_STATIC(odbc_lock);

static SQLHENV                  HOdbcEnv;
static int      ODBC_res;                       /* global ODBC Result of 
Functions */
static SQLHDBC  ODBC_con;                       /* global ODBC Connection 
Handle */
static SQLHSTMT ODBC_stmt;                      /* global ODBC Statement Handle 
*/

static char *config = "odbcexec.conf";
static char *dsn = NULL, *username = NULL, *password = NULL;
static int dsn_alloc = 0, username_alloc = 0, password_alloc = 0;
static int connected = 0;

static int ast_odbcexec(const char *query, char *out, int outlen);
static int odbc_load_module(int);
static int odbc_init(void);
static int odbc_unload_module(void);
static int odbc_do_query(char *sqlcmd);
static void reconect(void);


void LogErrMsg(char * source, long rc,SQLSMALLINT HandleType,SQLHANDLE Handle);

void LogErrMsg(char * source, long rc,SQLSMALLINT HandleType,SQLHANDLE Handle)
{
        SQLSMALLINT len;
        SQLCHAR             msg[200],buffer[200];
        SQLCHAR             sqlstat[10];
        
        ast_log(LOG_ERROR, "Error %s %d\n",source,rc);
        SQLGetDiagRec(HandleType,Handle,1, 
                        sqlstat, &rc,msg,100,&len);
        ast_log(LOG_ERROR, "%s (%d)\n",msg,rc);
}


static int odbcexec_exec(struct ast_channel *chan, void *data)
{
        int arglen, res;
        char *argv;

        arglen = strlen (data);
        argv = alloca (arglen + 1);
        if (!argv)                      /* Why would this fail? */
        {
                ast_log (LOG_DEBUG, "Memory allocation failed\n");
                return 0;
        }

        memcpy (argv, data, arglen + 1);
        
  ast_verb (3, "odbcexec: query=%s\n", argv);

        ast_mutex_lock(&odbc_lock);
        res = odbc_do_query(argv);
        ast_mutex_unlock(&odbc_lock);
        if(res==-1) {
        
                        ast_verb (3, "odbcexec: Query failed.\n");
                  /* Send the call to n+101 priority, where n is the current 
priority */
                
                if (ast_exists_extension (chan, chan->context, chan->exten, 
chan->priority + 101, chan->cid.cid_num))
                        chan->priority += 100;
        }
        return 0;
}

static int odbcexec_query(struct ast_channel *chan, void *data)
{
        int arglen;
        char *argv, *varname, *query;
        char dbresult[256];

        arglen = strlen (data);
        argv = alloca (arglen + 1);
        if (!argv)                      /* Why would this fail? */
        {
                ast_log (LOG_DEBUG, "Memory allocation failed\n");
                return 0;
        }

        memcpy (argv, data, arglen + 1);

        if (strchr (argv, '='))
        {
                varname = strsep (&argv, "=");
                query = strsep (&argv, "\0");
                if (!varname || !query)
                {
                        ast_log (LOG_DEBUG, "Ignoring; Syntax error in 
argument\n");
                        return 0;
                }

                
                        ast_verb (3, "odbcquery: varname=%s, query=%s\n", 
varname, query);

                if (!ast_odbcexec (query, dbresult, sizeof (dbresult) - 1))
                {
                        pbx_builtin_setvar_helper (chan, varname, dbresult);
                
                                ast_verb (3, "odbcquery: set variable %s to 
%s\n", varname, dbresult);
                }
                else
                {

                                ast_verb (3,"odbcquery: Value not found in 
database.\n");
                          /* Send the call to n+101 priority, where n is the 
current priority */
                        if (ast_exists_extension (chan, chan->context, 
chan->exten, chan->priority + 101, chan->cid.cid_num))
                                chan->priority += 100;
                }

        }
        else
        {
                ast_log (LOG_DEBUG, "Ignoring, no parameters\n");
        }

        return 0;
}

static int odbc_init(void)
{
        long int ODBC_err;
        short int ODBC_mlen;
        char ODBC_msg[200], ODBC_stat[10];

        ast_verb(3, "odbc_init called\n");
        
        if ( HOdbcEnv == SQL_NULL_HANDLE || !connected)
        {
                ODBC_res = SQLAllocEnv(&HOdbcEnv);
                if (!SQL_SUCCEEDED(ODBC_res)) {
                        ast_log(LOG_ERROR, "SQLAllocEnv failed\n");
                        return -1;
                }
        
                ODBC_res = SQLAllocConnect(HOdbcEnv, &ODBC_con);
                if (!SQL_SUCCEEDED(ODBC_res)) {
                        ast_log(LOG_ERROR, "SQLAllocConnect failed\n");
                        SQLFreeHandle(SQL_HANDLE_ENV, HOdbcEnv);
                        HOdbcEnv=NULL;
                        return -1;
                }
        }

        ODBC_res = SQLConnect(ODBC_con, (SQLCHAR*)dsn, SQL_NTS, 
(SQLCHAR*)username, SQL_NTS, (SQLCHAR*)password, SQL_NTS);

        if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
        {
        
                        ast_verb( 4, "app_odbcexec: Error SQLConnect %d\n", 
ODBC_res);
                LogErrMsg("SQLConnect", ODBC_res, SQL_HANDLE_DBC, ODBC_con);
                SQLFreeHandle(SQL_HANDLE_ENV, HOdbcEnv);
                connected = 0;
                return -1;
        }
        else
        {
                
                        ast_verb( 4, "app_odbcexec: Connected to %s\n", dsn);
                connected = 1;
        }

        return 0;
}

static int odbc_load_module(int reload)
{
        int retval;
        int res;
        struct ast_config *cfg;
        struct ast_variable *var;
        struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 
0 };
        char *tmp;

        cfg = ast_config_load(config, config_flags);
        if (!cfg)
        {
                ast_log(LOG_WARNING, "app_odbcexec: Unable to load config for 
unixODBC: %s\n", config);
                return 0;
        }
        
        var = ast_variable_browse(cfg, "global");
        if (!var) {
                /* nothing configured */
                return 0;
        }

        tmp = ast_variable_retrieve(cfg,"global","dsn");
        if (tmp)
        {
                dsn = malloc(strlen(tmp) + 1);
                if (dsn != NULL)
                {
                        dsn_alloc = 1;
                        strcpy(dsn,tmp);
                }
                else
                {
                        ast_log(LOG_ERROR,"app_odbcexec: Out of memory 
error.\n");
                        return -1;
                }
        }
        else
        {
                ast_log(LOG_WARNING,"app_odbcexec: dsn not specified.  Assuming 
asteriskdb\n");
                dsn = "asteriskdb";
        }

        tmp = ast_variable_retrieve(cfg,"global","username");
        if (tmp)
        {
                username = malloc(strlen(tmp) + 1);
                if (username != NULL)
                {
                        username_alloc = 1;
                        strcpy(username,tmp);
                }
                else
                {
                        ast_log(LOG_ERROR,"app_odbcexec: Out of memory 
error.\n");
                        return -1;
                }
        }
        else
        {
                ast_log(LOG_WARNING,"app_odbcexec: username not specified.  
Assuming root\n");
                username = "root";
        }

        tmp = ast_variable_retrieve(cfg,"global","password");
        if (tmp)
        {
                password = malloc(strlen(tmp) + 1);
                if (password != NULL)
                {
                        password_alloc = 1;
                        strcpy(password,tmp);
                }
                else
                {
                        ast_log(LOG_ERROR,"app_odbcexec: Out of memory 
error.\n");
                        return -1;
                }
        }
        else
        {
                ast_log(LOG_WARNING,"app_odbcexec: database password not 
specified.  Assuming blank\n");
                password = "";
        }

        ast_config_destroy(cfg);
        
                ast_verb( 4, "app_odbcexec: dsn is %s\n",dsn);
                ast_verb( 4, "app_odbcexec: username is %s\n",username);
                ast_verb( 4, "app_odbcexec: password is [secret]\n");

        
        
        res = odbc_init();
        if(res < 0)
        {
                ast_log(LOG_ERROR, "app_odbcexec: Unable to connect to 
datasource: %s\n", dsn);
                ast_verb( 4, "app_odbcexec: Unable to connect to datasource: 
%s\n", dsn);
        }

        retval = ast_register_application (q_app, odbcexec_query, q_synopsis, 
q_descrip);
        if (!retval)
                retval = ast_register_application (e_app, odbcexec_exec, 
e_synopsis, e_descrip);
        return retval;
}

static int odbc_do_query(char *sqlcmd)
{
        long int ODBC_err;
        short int ODBC_mlen;
        char ODBC_msg[200], ODBC_stat[10];
                int res2;

        ODBC_res = SQLAllocHandle(SQL_HANDLE_STMT, ODBC_con, &ODBC_stmt);

        if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
        {
                
                        ast_verb( 4, "app_odbcexec: Failure in AllocStatement 
%d\n", ODBC_res);
                LogErrMsg("SQLAllocHandle",ODBC_res,SQL_HANDLE_STMT,ODBC_con);
                SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);      
                connected = 0;
                reconect();
                
                return -1;
        }

        ODBC_res = SQLPrepare(ODBC_stmt, sqlcmd, SQL_NTS);


        if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
        {
        
                        ast_verb( 4, "app_odbcexec: Error in PREPARE %d\n", 
ODBC_res);
                LogErrMsg("SQLPrepare", ODBC_res, SQL_HANDLE_DBC, ODBC_con);
                SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
                reconect();
                return -1;
        }

        ODBC_res = SQLExecute(ODBC_stmt);

        if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
        {
        
                        ast_verb( 4, "app_odbcexec: Error in Query %d\n", 
ODBC_res);
                LogErrMsg("SQLExecute",ODBC_res,SQL_HANDLE_STMT,ODBC_stmt);
                SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
                connected = 0;
                return -1;
        }
        else
        {
                
                        ast_verb( 4, "app_odbcexec: Query Successful!\n");
                connected = 1;
        }
        return 0;
}

static void reconect(void)
{
        int res;

        if (connected)
        {
                SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
                SQLDisconnect(ODBC_con);
                SQLFreeHandle(SQL_HANDLE_DBC, ODBC_con);
                SQLFreeHandle(SQL_HANDLE_ENV, HOdbcEnv);
                connected = 0;
        
        }

        res = odbc_init();
        if(res < 0)
        {
                ast_log(LOG_ERROR, "app_odbcexec: Unable to connect to 
datasource: %s\n", dsn);
                ast_verb( 4, "app_odbcexec: Unable to connect to datasource: 
%s\n", dsn);
        }


}

static int odbc_unload_module(void)
{
        int retval;
        if (connected)
        {
                
                        ast_verb( 4, "app_odbcexec: Disconnecting from %s\n", 
dsn);
                SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
                SQLDisconnect(ODBC_con);
                SQLFreeHandle(SQL_HANDLE_DBC, ODBC_con);
                SQLFreeHandle(SQL_HANDLE_ENV, HOdbcEnv);
                connected = 0;
        }
        if (dsn && dsn_alloc)
        {
        
                        ast_verb( 4, "app_odbcexec: free dsn\n");
                free(dsn);
                dsn = NULL;
                dsn_alloc = 0;
        }
        if (username && username_alloc)
        {
                
                        ast_verb( 4, "app_odbcexec: free username\n");
                free(username);
                username = NULL;
                username_alloc = 0;
        }
        if (password && password_alloc)
        {
        
                        ast_verb( 4, "app_odbcexec: free password\n");
                free(password);
                password = NULL;
                password_alloc = 0;
        }
        retval = ast_unregister_application (q_app);
        retval |= ast_unregister_application (e_app);
        return retval;
}

static int ast_odbcexec(const char *query, char *value, int valuelen)
{
        int res;
        long int ODBC_err;
        char sqlcmd[1024];
        char tmp[256] = "";
        memset(sqlcmd,0,1024);
        ast_mutex_lock(&odbc_lock);
        sprintf(sqlcmd, "%s", query);
        res = odbc_do_query(sqlcmd);
        SQLBindCol(ODBC_stmt, 1, SQL_C_CHAR, &tmp, 50, &ODBC_err);
        if((ODBC_res = SQLFetch(ODBC_stmt) != SQL_NO_DATA))
        {
                strcpy(value, tmp);
        }
        else
        {
                res = -1;
        }
        SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
        ast_mutex_unlock(&odbc_lock);
        return res;
}

int unload_module (void)
{

  ast_module_user_hangup_all();
        return odbc_unload_module();
}

int reload(void)
{
        connected = 0;
        odbc_unload_module();
        return odbc_load_module(1);
}

int load_module (void)
{

        return odbc_load_module(0);
}

AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ODBC exec Querys");
_______________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

asterisk-users mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-users

Reply via email to