Hi,

I'm trying to make odbcexec work with Asterisk 1.6.

I had the attached code (app_odbcexec, not the standard one) working great
with asterisk 1.2 an MSSQL Server on heavy load PBXs with no problem, I'm
trying to port this to asterisk 1.6 but I'm failing to do so.
I attach de working code in 1.2 (app_odbcexec) and my try to port it to 1.6
(app_odbcexec1.6).

Anyone can help??

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 <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");
/*
 * 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;
}
_______________________________________________
-- 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