/*
** CONNECT.C - This is the module containing the code for ODBC for
** allocation and connection.
**
** (c) 1996 by Dirk Ohme - all rights reserved
*/

#include "cli.h"

/*---------------------------------------------------------------------------*/
/*      CONNECT.C                                                            */
/*                                                                           */
/*      SQLC connection functions.                                           */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*      Allocate an environment (ENV) block.                                 */
/*---------------------------------------------------------------------------*/
RETCODE SQL_API SQLAllocEnv( SQLHENV FAR   *phenv
                           )
{
        /*
        ** check parameter
        */
        LogEntry( LOG_STATUS, "[SQLAllocEnv] phenv = $%08lX", phenv );
        if( NULL == phenv )
        {
                LogEntry( LOG_ERROR,      "[SQLAllocEnv] NULL == phenv" );
                LogEntry( LOG_RETURNCODE, "[SQLAllocEnv] SQL_INVALID_HANDLE" );
                return SQL_INVALID_HANDLE;
        }

        /*
        ** allocate environment
        */
       *phenv = (SQLHENV) malloc( sizeof(ENV) );
        if( SQL_NULL_HENV == *phenv )
        {
                LogEntry( LOG_ERROR,      "[SQLAllocEnv] malloc error" );
                LogEntry( LOG_RETURNCODE, "[SQLAllocEnv] SQL_ERROR" );
               *phenv = SQL_NULL_HENV;
                return SQL_ERROR;
        }

        /*
        ** initialise environment
        */
        LogEntry( LOG_STATUS, "[SQLAllocEnv] *phenv = $%08lX", *phenv );
        memset( *phenv, 0, sizeof(ENV) );
        LogEntry( LOG_RETURNCODE, "[SQLAllocEnv] SQL_SUCCESS" );
        return SQL_SUCCESS;
}

/*---------------------------------------------------------------------------*/
/*      Allocate a DBC block.                                                */
/*---------------------------------------------------------------------------*/
RETCODE SQL_API SQLAllocConnect(
                             LPENV               lpenv,
                             HDBC FAR           *phdbc
                               )
{
        /*
        ** check environment pointer
        */
        LogEntry( LOG_STATUS, "[SQLAllocConnect] lpenv = $%08lX", lpenv );
        LogEntry( LOG_STATUS, "                  phdbc = $%08lX", phdbc );
        if( SQL_NULL_HENV == lpenv )
        {
                LogEntry( LOG_ERROR, "[SQLAllocConnect] NULL == lpenv" );
                LogEntry( LOG_RETURNCODE,
                          "[SQLAllocConnect] SQL_INVALID_HANDLE" );
                return SQL_INVALID_HANDLE;
        }

        /*
        ** check parameter
        */
        if( SQL_NULL_HDBC == phdbc )
        {
                strcpy( lpenv->szSqlState, "S1009" );
                lpenv->pszSqlMsg = "[SQLAllocConnect] NULL == phdbc";
                LogEntry( LOG_ERROR, lpenv->pszSqlMsg );
                LogEntry( LOG_RETURNCODE,
                          "[SQLAllocConnect] SQL_ERROR (%s)",
                          lpenv->szSqlState
                        );
                return SQL_ERROR;
        }

        /*
        ** allocate database access structure
        */
       *phdbc = (SQLHDBC) malloc( sizeof(DBC) );
        if( SQL_NULL_HDBC == *phdbc )
        {
               *phdbc = SQL_NULL_HDBC;
                strcpy( lpenv->szSqlState, "S1001" );
                lpenv->pszSqlMsg = "[SQLAllocConnect] malloc error";
                LogEntry( LOG_ERROR, lpenv->pszSqlMsg );
                LogEntry( LOG_RETURNCODE,
                          "[SQLAllocConnect] SQL_ERROR (%s)",
                          lpenv->szSqlState
                        );
                return SQL_ERROR;
        }

        /*
        ** initialize structure
        */
        LogEntry( LOG_RETURNCODE, "[SQLAllocConnect] *phdbc = $%08lX", *phdbc );
        memset( *phdbc, 0, sizeof(DBC) );

#ifdef mSQL
        ((SQLHDBC)(*phdbc))->hDbSocket  = -1;
#endif
        ((SQLHDBC)(*phdbc))->pSqlEnv    = lpenv;
        ((SQLHDBC)(*phdbc))->pSqlEnv->ciConnections++;
        ((SQLHDBC)(*phdbc))->szSqlState = &lpenv->szSqlState[0];

        LogEntry( LOG_RETURNCODE, "[SQLAllocConnect] SQL_SUCCESS" );
        return SQL_SUCCESS;
}

/*---------------------------------------------------------------------------*/
/*      Connect with Database                                                */
/*---------------------------------------------------------------------------*/
RETCODE SQL_API SQLConnect(  LPDBC               lpdbc,
                             UCHAR FAR          *szDSN,
                             SWORD               cbDSN,
                             UCHAR FAR          *szUID,
                             SWORD               cbUID,
                             UCHAR FAR          *szAuthStr,
                             SWORD               cbAuthStr
                          )
{                                                /*-------------------*/
        char            szDb[64];                /* database name     */
        char            szHost[64];              /* database host     */
        char            szPw[32];                /* database password */
        char            szUser[32];              /* database user     */
#ifdef ORACLE
        char            szBuffer[80];            /* database login    */
#endif
                                                 /*-------------------*/
        char           *pszIdx;                  /* index pointer     */
                                                 /*-------------------*/
        /*
        ** check handle
        */
        LogEntry( LOG_STATUS, "[SQLConnect] lpdbc     = $%08lX", lpdbc );
        LogEntry( LOG_STATUS, "             szDSN     = $%08lX", szDSN );
        LogEntry( LOG_STATUS, "             cbDSN     = %5d",    cbDSN );
        LogEntry( LOG_STATUS, "             szUID     = $%08lX", szUID );
        LogEntry( LOG_STATUS, "             szUID     = %5d",    cbUID );
        LogEntry( LOG_STATUS, "             szAuthStr = $%08lX", szAuthStr );
        LogEntry( LOG_STATUS, "             cbAuthStr = %5d",    cbAuthStr );
        if( SQL_NULL_HDBC == lpdbc ||
            SQL_NULL_HENV == lpdbc->pSqlEnv
          )
        {
                LogEntry( LOG_ERROR, "[SQLConnect] NULL == lpdbc / *lpdbc" );
                LogEntry( LOG_RETURNCODE,
                          "[SQLConnect] SQL_INVALID_HANDLE" );
                return SQL_INVALID_HANDLE;
        }

        /*
        ** check for an already open connection
        */
        if( TRUE == lpdbc->fConnect )
        {
                strcpy( lpdbc->szSqlState, "08002" );
                lpdbc->pszSqlMsg = "[SQLConnect] already connected";
                LogEntry( LOG_ERROR, lpdbc->pszSqlMsg );
                LogEntry( LOG_RETURNCODE,
                          "[SQLConnect] SQL_ERROR (%s)",
                          lpdbc->szSqlState
                        );
                return SQL_ERROR;
        }

        /*
        ** initialise structures
        */
        szDb[0]   =
        szHost[0] =
        szPw[0]   =
        szUser[0] = '\0';

        /*
        ** scan data source name
        ** valid formats: 1)      database
        **                2) user.database
        **                3)      database@host
        **                4) user.database@host
        */
        if( NULL != szDSN )
        {
                /*
                ** check counter
                */
                if( SQL_NTS == cbDSN )
                {
                        cbDSN = strlen( szDSN );
                } /* if( SQL_NTS == cbDSN ) */
                szDSN[cbDSN] = '\0';

                /*
                ** check for user entry
                */
                pszIdx = strchr( szDSN, '.' );
                if( NULL != pszIdx )
                {
                        strncpy( szUser, szDSN, sizeof(szUser) );
#ifdef OS2
                        szUser[ MIN( (int) (pszIdx - szDSN),
                                     sizeof(szUser) - 1      ) ] = '\0';
                        cbDSN -= (int) (pszIdx - szDSN);
#else
                        szUser[ MIN( (((int) pszIdx) - ((int) szDSN)),
                                     sizeof(szUser) - 1 ) ] = '\0';
                        cbDSN -= (((int) pszIdx) - ((int) szDSN));
#endif
                        cbDSN--;
                        szDSN  = &pszIdx[1];
                } /* if( NULL != pszIdx ) */

                /*
                ** check for database entry
                */
                pszIdx = strchr( szDSN, '@' );
                if( NULL == pszIdx )
                {
                        strncpy( szDb, szDSN, sizeof(szDb) );
                        szDb[MIN(cbDSN, sizeof(szDb) - 1)] = '\0';
                } else {
                        strncpy( szDb, szDSN, sizeof(szDb) );
#ifdef OS2
                        szDb[ MIN( (int) (pszIdx - szDSN),
                                   sizeof(szDb) - 1        ) ] = '\0';
                        cbDSN -= (int) (pszIdx - szDSN);
#else
                        szDb[ MIN( (((int) pszIdx) - ((int) szDSN)),
                                   sizeof(szDb) - 1        ) ] = '\0';
                        cbDSN -= (((int) pszIdx) - ((int) szDSN));
#endif
                        cbDSN--;
                        strncpy( szHost, &pszIdx[1], sizeof(szHost) );
                        szHost[MIN(cbDSN, sizeof(szHost) - 1)] = '\0';
                } /* else */
        } /* if( NULL != szDSN ) */

        /*
        ** scan for user identifier
        */
        if( NULL != szUID )
        {
                strncpy( szUser,
                         szUID,
                         (SQL_NTS == cbUID) ? sizeof(szUser)
                                            : MIN(cbUID, sizeof(szUser))
                       );
        }

        /*
        ** scan for authentication string
        */
        if( NULL != szAuthStr )
        {
                strncpy( szPw,
                         szAuthStr,
                         (SQL_NTS == cbAuthStr) ? sizeof(szPw)
                                                : MIN(cbAuthStr, sizeof(szPw))
                       );
        }

        /*
        ** try connection with database
        */
        LogEntry( LOG_SUMMARY, "[SQLConnect] DB   = '%s'", szDb   );
        LogEntry( LOG_SUMMARY, "             host = '%s'", szHost );
        LogEntry( LOG_SUMMARY, "             user = '%s'", szUser );
        LogEntry( LOG_SUMMARY, "             pw   = '%s'", szPw   );

        /*---| connect to server |---*/
#ifdef mSQL
#  ifdef OS2
        lpdbc->hDbSocket = msqlUserConnect( ('\0' == szHost[0]) ? NULL
                                                                : &szHost[0],
                                            ('\0' == szUser[0]) ? NULL
                                                                : &szUser[0]
                                          );
#  else
        lpdbc->hDbSocket = msqlConnect( ('\0' == szHost[0]) ? NULL
                                                            : &szHost[0] );
#  endif
        if( 0 > lpdbc->hDbSocket )
        {
                /*---| get mSQL error message |---*/
                msqlGetErrMsg( lpdbc->szMsqlErrorMsg );

#endif
#ifdef ORACLE
        if( '\0' != szUser )
        {
                strcpy( szBuffer, szUser );
        }
        else
        {
                strcpy( szBuffer, szDb );
        }
        if( '\0' != szPw )
        {
                strcat( szBuffer, "/" );
                strcat( szBuffer, szPw );
        }
        if( '\0' != szHost )
        {
                strcat( szBuffer, "@" );
                strcat( szBuffer, szHost );
        }
        if( orlon(&lpdbc->lda, &lpdbc->hda[0], szBuffer, -1, NULL, -1, -1) )
        {
#endif
                /*---| error processing |---*/
                strcpy( lpdbc->szSqlState, "08001" );
                lpdbc->pszSqlMsg = "[SQLConnect] can't connect to server";
                LogEntry( LOG_ERROR,
                          "[SQLConnect] can't connect to server (%s)",
#ifdef mSQL
                          lpdbc->szMsqlErrorMsg
#endif
#ifdef ORACLE
                          szHost
#endif
                        );
                LogEntry( LOG_RETURNCODE,
                          "[SQLConnect] SQL_ERROR (%s)",
                          lpdbc->szSqlState
                        );
                return SQL_ERROR;
        }

#ifdef mSQL
        /*---| connect to database (mSQL) |---*/
        if( 0 != msqlSelectDB(lpdbc->hDbSocket, szDb) )
        {
                /*---| get mSQL error message |---*/
                msqlGetErrMsg( lpdbc->szMsqlErrorMsg );

                /*---| error processing |---*/
                strcpy( lpdbc->szSqlState, "08004" );
                lpdbc->pszSqlMsg = "[SQLConnect] can't connect to database";
                LogEntry( LOG_ERROR,
                          "[SQLConnect] can't connect to database (%s)",
                          lpdbc->szMsqlErrorMsg
                        );
                LogEntry( LOG_RETURNCODE,
                          "[SQLConnect] SQL_ERROR (%s)",
                          lpdbc->szSqlState
                        );

                /*---| close connection to server |---*/
                msqlClose( lpdbc->hDbSocket );
                lpdbc->hDbSocket = -1;

                return SQL_ERROR;
        }
#endif

        /*
        ** set connection state
        */
        lpdbc->fConnect = TRUE;
        lpdbc->ciActive = 0;

        LogEntry( LOG_RETURNCODE, "[SQLConnect] SQL_SUCCESS" );
        return SQL_SUCCESS;
}

/*---------------------------------------------------------------------------*/
/*      This function as its "normal" behavior is supposed to bring up a     */
/*      dialog box if it isn't given enough information via "szConnStrIn".   */
/*      If it is given enough information, it's supposed to use "szConnStrIn"*/
/*      to establish a database connection.  In either case, it returns a    */
/*      string to the user that is the string that was eventually used to    */
/*      establish the connection.                                            */
/*---------------------------------------------------------------------------*/
RETCODE SQL_API SQLDriverConnect(
                             LPDBC               lpdbc,
                             HWND                hwnd,
                             UCHAR FAR          *szConnStrIn,
                             SWORD               cbConnStrIn,
                             UCHAR FAR          *szConnStrOut,
                             SWORD               cbConnStrOutMax,
                             SWORD FAR          *pcbConnStrOut,
                             UWORD               fDriverCompletion
                                )
{                                                /*-------------------*/
        char            szDb[64];                /* database name     */
        char            szHost[64];              /* database host     */
        char            szPw[32];                /* database password */
        char            szUser[32];              /* database user     */
#ifdef ORACLE
        char            szBuffer[80];            /* database login    */
#endif
                                                 /*-------------------*/
        char           *pszIdx;                  /* index pointer     */
                                                 /*-------------------*/
        /*
        ** check handle and pointers
        */
        LogEntry( LOG_STATUS, "[SQLDriverConnect] lpdbc             = $%08lX", lpdbc );
        LogEntry( LOG_STATUS, "                   hwnd              = %5d", hwnd );
        LogEntry( LOG_STATUS, "                   szConnStrIn       = $%08lX", szConnStrIn );
        LogEntry( LOG_STATUS, "                   cbConnStrIn       = %5d", cbConnStrIn );
        LogEntry( LOG_STATUS, "                   szConnStrOut      = $%08lX", szConnStrOut );
        LogEntry( LOG_STATUS, "                   cbConnStrOutMax   = %5d", cbConnStrOutMax );
        LogEntry( LOG_STATUS, "                   pcbConnStrOut     = $%08lX", pcbConnStrOut );
        LogEntry( LOG_STATUS, "                   fDriverCompletion = %5d", fDriverCompletion );

        if( SQL_NULL_HDBC == lpdbc ||
            SQL_NULL_HENV == lpdbc->pSqlEnv
          )
        {
                LogEntry( LOG_ERROR, "[SQLDriverConnect] NULL == lpdbc / *lpdbc" );
                LogEntry( LOG_RETURNCODE,
                          "[SQLDriverConnect] SQL_INVALID_HANDLE" );
                return SQL_INVALID_HANDLE;
        }

        /*
        ** check for an already open connection
        */
        if( TRUE == lpdbc->fConnect )
        {
                strcpy( lpdbc->szSqlState, "08002" );
                lpdbc->pszSqlMsg = "[SQLDriverConnect] already connected";
                LogEntry( LOG_ERROR, lpdbc->pszSqlMsg );
                LogEntry( LOG_RETURNCODE,
                          "[SQLDriverConnect] SQL_ERROR (%s)",
                          lpdbc->szSqlState
                        );
                return SQL_ERROR;
        }

        /*
        ** initialise structures
        */
        szDb[0]   =
        szHost[0] =
        szPw[0]   =
        szUser[0] = '\0';

        /*
        ** parse input data
        */
        if( NULL != szConnStrIn )
        {
                /*---| terminate string |---*/
                if( SQL_NTS != cbConnStrIn )
                        szConnStrIn[cbConnStrIn] = '\0';

                /*---| parse string |---*/
                pszIdx = strtok( szConnStrIn, ";" );
                while( NULL != pszIdx )
                {
                        /*---| check for known keywords |---*/
                        if( 0 == strncmp(pszIdx, "DSN", 3) )
                        {
                                register char *psz;

                                /*---| check for database / host name |---*/
                                szDb[0]  = szHost[0] = '\0';
                                if( NULL != (pszIdx=strchr(pszIdx, '=')) )
                                {
                                        /*---| remove SPACEs |---*/
                                        do
                                        {
                                                pszIdx++;
                                        }
                                        while( ' ' == *pszIdx );

                                        /*---| fill database name |---*/
                                        psz = &szDb[0];
                                        while( '\0' != *pszIdx &&
                                                '@' != *pszIdx &&
                                                ' ' != *pszIdx )
                                        {
                                                *psz = *pszIdx;
                                                 pszIdx++;
                                                 psz++;
                                        }
                                        *psz = '\0';
                                        if( '@' == *pszIdx )
                                                pszIdx++;

                                        /*---| fill host name |---*/
                                        psz = &szHost[0];
                                        while( '\0' != *pszIdx &&
                                                ' ' != *pszIdx )
                                        {
                                                *psz = *pszIdx;
                                                 pszIdx++;
                                                 psz++;
                                        }
                                }
                        }
                        else if( 0 == strncmp(pszIdx, "UID", 3) )
                        {
                                register char *psz;

                                /*---| check for user name / password |---*/
                                szUser[0] = szPw[0] = '\0';
                                if( NULL != (pszIdx=strchr(pszIdx, '=')) )
                                {
                                        /*---| remove SPACEs |---*/
                                        do
                                        {
                                                pszIdx++;
                                        }
                                        while( ' ' == *pszIdx );

                                        /*---| fill user name |---*/
                                        psz = &szUser[0];
                                        while( '\0' != *pszIdx &&
                                                '/' != *pszIdx &&
                                                ' ' != *pszIdx )
                                        {
                                                *psz = *pszIdx;
                                                 pszIdx++;
                                                 psz++;
                                        }
                                        *psz = '\0';
                                        if( '@' == *pszIdx )
                                                pszIdx++;

                                        /*---| fill password |---*/
                                        psz = &szPw[0];
                                        while( '\0' != *pszIdx &&
                                                ' ' != *pszIdx )
                                        {
                                                *psz = *pszIdx;
                                                 pszIdx++;
                                                 psz++;
                                        }
                                }
                        }
                        else if( 0 == strncmp(pszIdx, "PWD", 3) )
                        {
                                register char *psz;

                                /*---| check for password |---*/
                                szPw[0] = '\0';
                                if( NULL != (pszIdx=strchr(pszIdx, '=')) )
                                {
                                        /*---| remove SPACEs |---*/
                                        do
                                        {
                                                pszIdx++;
                                        }
                                        while( ' ' == *pszIdx );

                                        /*---| fill password |---*/
                                        psz = &szPw[0];
                                        while( '\0' != *pszIdx &&
                                                ' ' != *pszIdx )
                                        {
                                                *psz = *pszIdx;
                                                 pszIdx++;
                                                 psz++;
                                        }
                                }
                        }
                        else
                        {
                                LogEntry( LOG_WARNING,
                                          "[SQLDriverConnect] unknown input keyword '%s'",
                                          pszIdx
                                        );
                        }

                        /*---| next keyword |---*/
                        pszIdx = strtok( NULL, ";" );
                }
        }

        /*
        ** prompt for completion - not implemented yet!
        */
        switch( fDriverCompletion )
        {
                case SQL_DRIVER_PROMPT:
                case SQL_DRIVER_COMPLETE:
                case SQL_DRIVER_COMPLETE_REQUIRED:
                case SQL_DRIVER_NOPROMPT:
                default:
                        break;
        }

        /*
        ** fill szConnStrOut with data - not implemented yet!
        */
        if( NULL != szConnStrOut )
        {
                strncpy( szConnStrOut, szConnStrIn, cbConnStrOutMax );
                if( NULL != pcbConnStrOut )
                {
                        *pcbConnStrOut = MIN( strlen(szConnStrOut),
                                              cbConnStrOutMax );
                }
        }

        /*
        ** try connection with database
        */
        LogEntry( LOG_SUMMARY, "[SQLDriverConnect] DB   = '%s'", szDb   );
        LogEntry( LOG_SUMMARY, "                   host = '%s'", szHost );
        LogEntry( LOG_SUMMARY, "                   user = '%s'", szUser );
        LogEntry( LOG_SUMMARY, "                   pw   = '%s'", szPw   );

        /*---| connect to server |---*/
#ifdef mSQL
#  ifdef OS2
        lpdbc->hDbSocket = msqlUserConnect( ('\0' == szHost[0]) ? NULL
                                                                : &szHost[0],
                                            ('\0' == szUser[0]) ? NULL
                                                                : &szUser[0]
                                          );
#  else
        lpdbc->hDbSocket = msqlConnect( ('\0' == szHost[0]) ? NULL
                                                            : &szHost[0] );
#  endif
        if( 0 > lpdbc->hDbSocket )
        {
                /*---| get mSQL error message |---*/
                msqlGetErrMsg( lpdbc->szMsqlErrorMsg );

#endif
#ifdef ORACLE
        if( '\0' != szUser )
        {
                strcpy( szBuffer, szUser );
        }
        else
        {
                strcpy( szBuffer, szDb );
        }
        if( '\0' != szPw )
        {
                strcat( szBuffer, "/" );
                strcat( szBuffer, szPw );
        }
        if( '\0' != szHost )
        {
                strcat( szBuffer, "@" );
                strcat( szBuffer, szHost );
        }
        if( orlon(&lpdbc->lda, &lpdbc->hda[0], szBuffer, -1, NULL, -1, -1) )
        {
#endif
                /*---| error processing |---*/
                strcpy( lpdbc->szSqlState, "08001" );
                lpdbc->pszSqlMsg = "[SQLDriverConnect] can't connect to server";
                LogEntry( LOG_ERROR,
                          "[SQLDriverConnect] can't connect to server (%s)",
#ifdef mSQL
                          lpdbc->szMsqlErrorMsg
#endif
#ifdef ORACLE
                          szHost
#endif
                        );
                LogEntry( LOG_RETURNCODE,
                          "[SQLDriverConnect] SQL_ERROR (%s)",
                          lpdbc->szSqlState
                        );
                return SQL_ERROR;
        }

#ifdef mSQL
        /*---| connect to database (mSQL) |---*/
        if( 0 != msqlSelectDB(lpdbc->hDbSocket, szDb) )
        {
                /*---| get mSQL error message |---*/
                msqlGetErrMsg( lpdbc->szMsqlErrorMsg );

                /*---| error processing |---*/
                strcpy( lpdbc->szSqlState, "08004" );
                lpdbc->pszSqlMsg = "[SQLDriverConnect] can't connect to database";
                LogEntry( LOG_ERROR,
                          "[SQLDriverConnect] can't connect to database (%s)",
                          lpdbc->szMsqlErrorMsg
                        );
                LogEntry( LOG_RETURNCODE,
                          "[SQLDriverConnect] SQL_ERROR (%s)",
                          lpdbc->szSqlState
                        );

                /*---| close connection to server |---*/
                msqlClose( lpdbc->hDbSocket );
                lpdbc->hDbSocket = -1;

                return SQL_ERROR;
        }
#endif

        /*
        ** set connection state
        */
        lpdbc->fConnect = TRUE;
        lpdbc->ciActive = 0;

        LogEntry( LOG_RETURNCODE, "[SQLDriverConnect] SQL_SUCCESS" );
        return SQL_SUCCESS;
}

/*---------------------------------------------------------------------------*/
/*      Browse Connection Info ?                                             */
/*---------------------------------------------------------------------------*/
RETCODE SQL_API SQLBrowseConnect(
                             LPDBC               lpdbc,
                             UCHAR FAR          *szConnStrIn,
                             SWORD               cbConnStrIn,
                             UCHAR FAR          *szConnStrOut,
                             SWORD               cbConnStrOutMax,
                             SWORD FAR          *pcbConnStrOut
                                )
{

/*
** under construction
*/

        LogEntry( LOG_RETURNCODE, "[SQLBrowseConnect] SQL_SUCCESS" );
        return SQL_SUCCESS;
}

/*---------------------------------------------------------------------------*/
/*      Disconnect from Database                                             */
/*---------------------------------------------------------------------------*/
RETCODE SQL_API SQLDisconnect(
                             LPDBC               lpdbc
                             )
{
        /*
        ** check parameter
        */
        LogEntry( LOG_STATUS, "[SQLDisconnect] lpdbc = $%08lX", lpdbc );
        if( SQL_NULL_HDBC == lpdbc ||
            SQL_NULL_HENV == lpdbc->pSqlEnv
          )
        {
                LogEntry( LOG_ERROR,
                          "[SQLDisconnect] NULL == lpdbc / *lpdbc" );
                LogEntry( LOG_RETURNCODE,
                          "[SQLDisconnect] SQL_INVALID_HANDLE" );
                return SQL_INVALID_HANDLE;
        }

        /*
        ** check transaction state
        */
        if( 0 < lpdbc->ciActive )
        {
                strcpy( lpdbc->szSqlState, "25000" );
                lpdbc->pszSqlMsg = "[SQLDisconnect] transaction in progress";
                LogEntry( LOG_ERROR, lpdbc->pszSqlMsg );
                LogEntry( LOG_RETURNCODE,
                          "[SQLDisconnect] SQL_ERROR (%s)",
                          lpdbc->szSqlState
                        );
                return SQL_ERROR;
        }

        /*
        ** check connection state
        */
        if( FALSE == lpdbc->fConnect )
        {
                strcpy( lpdbc->szSqlState, "08003" );
                lpdbc->pszSqlMsg = "[SQLDisconnect] not connected";
                LogEntry( LOG_WARNING, lpdbc->pszSqlMsg );
                LogEntry( LOG_RETURNCODE,
                          "[SQLDisconnect] SQL_SUCCESS_WITH_INFO (%s)",
                          lpdbc->szSqlState
                        );
                return SQL_SUCCESS_WITH_INFO;
        }

        /*
        ** close connection
        */
#ifdef mSQL
        /*---| check mSQL handle |---*/
        if( 0 > lpdbc->hDbSocket )
#endif
#ifdef ORACLE
        /*---| close connection to Oracle server |---*/
        if( ologof(&lpdbc->lda) )
#endif
        {
                strcpy( lpdbc->szSqlState, "58004" );
#ifdef mSQL
                lpdbc->pszSqlMsg = "[SQLDisconnect] no valid mSQL handle";
#endif
#ifdef ORACLE
                lpdbc->pszSqlMsg = "[SQLDisconnect] error during close";
#endif
                LogEntry( LOG_ERROR, lpdbc->pszSqlMsg );
                LogEntry( LOG_RETURNCODE,
                          "[SQLDisconnect] SQL_ERROR (%s)",
                          lpdbc->szSqlState
                        );
                return SQL_ERROR;
        }

#ifdef mSQL
        /*---| close connection to mSQL server |---*/
        msqlClose( lpdbc->hDbSocket );
        lpdbc->hDbSocket = -1;
#endif

        /*---| reset connection state |---*/
        lpdbc->fConnect = FALSE;
        LogEntry( LOG_RETURNCODE, "[SQLDisconnect] SQL_SUCCESS" );
        return SQL_SUCCESS;
}

/*---------------------------------------------------------------------------*/
/*      Free DBC Block                                                       */
/*---------------------------------------------------------------------------*/
RETCODE SQL_API SQLFreeConnect(
                             LPDBC               lpdbc
                              )
{
        /*
        ** check parameter
        */
        LogEntry( LOG_STATUS, "[SQLFreeConnect] lpdbc = $%08lX", lpdbc );
        if( SQL_NULL_HDBC == lpdbc ||
            SQL_NULL_HENV == lpdbc->pSqlEnv
          )
        {
                LogEntry( LOG_ERROR,
                          "[SQLFreeConnect] NULL == lpdbc / *lpdbc" );
                LogEntry( LOG_RETURNCODE,
                          "[SQLFreeConnect] SQL_INVALID_HANDLE" );
                return SQL_INVALID_HANDLE;
        }

        /*
        ** check connection state
        */
        if( TRUE == lpdbc->fConnect )
        {
                strcpy( lpdbc->szSqlState, "S1010" );
                lpdbc->pszSqlMsg = "[SQLFreeConnect] connected";
                LogEntry( LOG_ERROR, lpdbc->pszSqlMsg );
                LogEntry( LOG_RETURNCODE,
                          "[SQLFreeConnect] SQL_ERROR (%s)",
                          lpdbc->szSqlState
                        );
                return SQL_ERROR;
        }

        /*
        ** free memory
        */
        lpdbc->pSqlEnv->ciConnections--;
        free( lpdbc );
        LogEntry( LOG_RETURNCODE, "[SQLFreeConnect] SQL_SUCCESS" );
        return SQL_SUCCESS;
}

/*---------------------------------------------------------------------------*/
/*      Free Environment                                                     */
/*---------------------------------------------------------------------------*/
RETCODE SQL_API SQLFreeEnv(  LPENV               lpenv
                          )
{
        /*
        ** check parameter
        */
        LogEntry( LOG_STATUS, "[SQLFreeEnv] lpenv = $%08lX", lpenv );
        if( SQL_NULL_HENV == lpenv )
        {
                LogEntry( LOG_ERROR, "[SQLFreeEnv] NULL == lpenv" );
                LogEntry( LOG_RETURNCODE, "[SQLFreeEnv] SQL_INVALID_HANDLE" );
                return SQL_INVALID_HANDLE;
        }

        /*
        ** check connection state
        */
        if( 0 != lpenv->ciConnections )
        {
                strcpy( lpenv->szSqlState, "S1010" );
                lpenv->pszSqlMsg = "[SQLFreeEnv] connection open (close first)";
                LogEntry( LOG_ERROR, lpenv->pszSqlMsg );
                LogEntry( LOG_RETURNCODE,
                          "[SQLFreeEnv] SQL_ERROR (%s)",
                          lpenv->szSqlState
                        );
                return SQL_ERROR;
        }

        /*
        ** free memory
        */
        free( lpenv );
        LogEntry( LOG_RETURNCODE, "[SQLFreeEnv] SQL_SUCCESS" );
        return SQL_SUCCESS;
}

/*===| end of file |=========================================================*/
