Example #1
0
int uodbc_open_stats(
    void **rh,
    unsigned int mode)
{
    key_t                       ipc_key;
    int                         shm_created = 0;
    uodbc_stats_handle_t        *h = NULL;
    uodbc_stats_handle_t        lh;
    char                        odbcini[1024];
    unsigned int                i;
    int                         shmflg;

    if (!rh)
    {
        return -1;
    }
    if (!_odbcinst_SystemINI(odbcini, FALSE))
    {
        snprintf(errmsg, sizeof(errmsg), "Failed to find system odbc.ini");
        return -1;
    }
    memset(&lh, '\0', sizeof(lh));
    memcpy(lh.id, UODBC_STATS_ID, 5);
    lh.shm_id = -1;
    lh.sem_id = -1;
    lh.pid = getpid();
    
    /*
     * Check the odbc.ini file used in ftok() exists.
     */
    if (access(odbcini, F_OK) < 0)
    {
        snprintf(errmsg, sizeof(errmsg), "Cannot locate %s", odbcini);
        return -1;
    }
    
    /*
     *  Get a unique IPC key.
     */
    if ((ipc_key = ftok(odbcini, (char)PROJECT_ID)) < 0)
    {
        snprintf(errmsg, sizeof(errmsg),
                 "Failed to obtain IPC key - %s", strerror(errno));
        return -1;
    }
    
    /*
     *  See if the semaphore exists and create if it doesn't.
     */
    lh.sem_id = semget(ipc_key, 1, IPC_ACCESS_MODE | IPC_CREAT | IPC_EXCL);
    if (lh.sem_id < 0)
    {
        if (errno != EEXIST)
        {
            snprintf(errmsg, sizeof(errmsg),
                     "Failed to get semaphore ID - %s",
                     strerror(errno));
            return -1;
        }
        
        lh.sem_id = semget(ipc_key, 1, IPC_ACCESS_MODE | IPC_CREAT);
        if (lh.sem_id < 0)
        {
            snprintf(errmsg, sizeof(errmsg),
                     "Failed to create semaphore - %s", strerror(errno));
            return -1;
        }
    }
    /*
     *  Create/map shared memory
     */
    if (mode & UODBC_STATS_WRITE)
        shmflg = IPC_ACCESS_MODE | IPC_CREAT | IPC_EXCL;
    else
        shmflg = IPC_ACCESS_MODE;        
    
    lh.shm_id = shmget(ipc_key, sizeof(uodbc_stats_t), shmflg);
    if (lh.shm_id < 0)
    {
        if (mode & UODBC_STATS_READ)
        {
            snprintf(errmsg, sizeof(errmsg),
                     "No statistics available yet");
            return -1;
        }
        if (errno == EEXIST)
        { 
            lh.shm_id = shmget(ipc_key, sizeof(uodbc_stats_t), IPC_ACCESS_MODE);
            if (lh.shm_id < 0)
            {
                snprintf(errmsg, sizeof(errmsg),
                         "Shared memory exists but cannot map it - %s",
                         strerror(errno));
                return -1;
            }
        }
        else
        {
            snprintf(errmsg, sizeof(errmsg),
                     "Failed to get shared memory ID - %s",
                     strerror(errno));
            return -1;
        }
    }
    else
    {
        if (mode & UODBC_STATS_WRITE) shm_created = 1;
    }
    
    lh.stats = (uodbc_stats_t *)shmat(lh.shm_id, 0, 0);
    if (lh.stats == (uodbc_stats_t *)-1)
    {
        snprintf(errmsg, sizeof(errmsg),
                 "Failed to attach to shared memory - %s", strerror(errno));
        return -1;
    }
    else if (shm_created)
    {
        unsigned int    i;
        int lk;
        
        lk = acquire_sem_lock(lh.sem_id);
        memset(lh.stats, '\0', sizeof(uodbc_stats_t));
        for (i = 0; i < (sizeof(lh.stats->perpid) / sizeof(lh.stats->perpid[0])); i++)
        {
            lh.stats->perpid[i].pid = (pid_t)0;
        }
        if (lk == 0) release_sem_lock(lh.sem_id);
    }
    if ((h = calloc(1, sizeof(uodbc_stats_handle_t))) == NULL) return -1;
    memcpy(h, &lh, sizeof(uodbc_stats_handle_t));
    /*
     *  If caller asked for write access it is assumed it is going to
     *  change the statistics and so it needs an entry in the stats.
     */
    if (mode & UODBC_STATS_WRITE)
    {
        int lk;
        
        lk = acquire_sem_lock(lh.sem_id);
        for (i = 0;
             i < (sizeof(h->stats->perpid) / sizeof(h->stats->perpid[0]));
             i++)
        {
            if (h->stats->perpid[i].pid == (pid_t)0)
            {
                h->stats->perpid[i].pid = getpid();
                h->stats->perpid[i].n_env = 0;
                h->stats->perpid[i].n_dbc = 0;
                h->stats->perpid[i].n_stmt = 0;
                h->stats->perpid[i].n_desc = 0;
                break;
            }
        }
        if (lk == 0) release_sem_lock(lh.sem_id);
    }
    
    *(uodbc_stats_handle_t **)rh = h;
    return 0;
}
int SQLGetPrivateProfileString( LPCSTR  pszSection,
                                LPCSTR  pszEntry,
                                LPCSTR  pszDefault,
                                LPSTR   pRetBuffer,
                                int     nRetBuffer,
                                LPCSTR  pszFileName
                              )
{
    HINI    hIni;
    int     nBufPos         = 0;
    char    szValue[INI_MAX_PROPERTY_VALUE+1];
    char    szFileName[ODBC_FILENAME_MAX+1];
    UWORD   nConfigMode;
    int     ini_done = 0;
    int     ret;

    inst_logClear();

    if ( check_ini_cache( &ret, pszSection, pszEntry, pszDefault, pRetBuffer, nRetBuffer, pszFileName ))
    {
        return ret;
    }

    /* SANITY CHECKS */
    if ( pRetBuffer == NULL || nRetBuffer < 2 )
    {
        inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" );
        return -1;
    }
    if ( pszSection != NULL && pszEntry != NULL && pszDefault == NULL )
    {
        inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "need default value - try empty string" );
        return -1;
    }

    *pRetBuffer = '\0';

    /*****************************************************
     * SOME MS CODE (ie some drivers) MAY USE THIS FUNCTION TO GET ODBCINST INFO SO...
     *****************************************************/
    if ( pszFileName != NULL )
    {
        if ( strstr( pszFileName, "odbcinst" ) || strstr( pszFileName, "ODBCINST" ) )
        {
            ret = _SQLGetInstalledDrivers(  pszSection, pszEntry, pszDefault, pRetBuffer, nRetBuffer );

            if ( ret == -1 )
            {
                /* try to use any default provided */
                if ( pRetBuffer && nRetBuffer > 0 )
                {
                    if ( pszDefault )
                    {
                        strncpy( pRetBuffer, pszDefault, nRetBuffer );
                        pRetBuffer[ nRetBuffer - 1 ] = '\0';
                    }
                }
            }
            else
            {
                save_ini_cache( ret, pszSection, pszEntry, pszDefault, pRetBuffer, nRetBuffer, pszFileName );
            }

            return ret;
        }
    }

    /*****************************************************
     * GATHER ALL RELEVANT DSN INFORMATION INTO AN hIni
     *****************************************************/
    if ( pszFileName != 0 && pszFileName[0] == '/' )
    {
#ifdef __OS2__
        if ( iniOpen( &hIni, (char*)pszFileName, "#;", '[', ']', '=', TRUE, 1L )
             != INI_SUCCESS )
#else
        if ( iniOpen( &hIni, (char*)pszFileName, "#;", '[', ']', '=', TRUE )
             != INI_SUCCESS )
#endif
        {
            inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL,
                             ODBC_ERROR_COMPONENT_NOT_FOUND, "" );
            return -1;
        }
    }
    else
    {
        nConfigMode     = __get_config_mode();
        nBufPos         = 0;
        szFileName[0]   = '\0';

        switch ( nConfigMode )
        {
        case ODBC_BOTH_DSN:
            if ( _odbcinst_UserINI( szFileName, TRUE ))
            {
#ifdef __OS2__
                if ( iniOpen( &hIni, (char*) szFileName, "#;", '[', ']', '=', TRUE, 1L )
                     == INI_SUCCESS )
#else
                if ( iniOpen( &hIni, (char*) szFileName, "#;", '[', ']', '=', TRUE )
                     == INI_SUCCESS )
#endif
                {
                    ini_done = 1;
                }
            }
            _odbcinst_SystemINI( szFileName, TRUE );
            if ( !ini_done )
            {
#ifdef __OS2__
                if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE, 1L )
                     != INI_SUCCESS )
#else
                if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE )
                     != INI_SUCCESS )
#endif
                {
                    inst_logPushMsg( __FILE__, __FILE__, __LINE__,
                                     LOG_CRITICAL, ODBC_ERROR_COMPONENT_NOT_FOUND, "" );
                    return -1;
                }
            }
            else
            {
                iniAppend( hIni, szFileName );
            }
            break;

        case ODBC_USER_DSN:
            _odbcinst_UserINI( szFileName, TRUE );
#ifdef __OS2__
            if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE, 1L )
                 != INI_SUCCESS )
#else
            if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE )
                 != INI_SUCCESS )
#endif
            {
                inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL,
                                 ODBC_ERROR_COMPONENT_NOT_FOUND, "" );
                return -1;
            }
            break;

        case ODBC_SYSTEM_DSN:
            _odbcinst_SystemINI( szFileName, TRUE );
#ifdef __OS2__
            if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE, 1L )
                 != INI_SUCCESS )
#else
            if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE )
                 != INI_SUCCESS )
#endif
            {
                inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL,
                                 ODBC_ERROR_COMPONENT_NOT_FOUND, "" );
                return -1;
            }
            break;

        default:
            inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL,
                             ODBC_ERROR_GENERAL_ERR, "Invalid Config Mode" );
            return -1;
        }
    }

    /*****************************************************
     * EXTRACT SECTIONS
     *****************************************************/
    if ( pszSection == NULL )
    {
        _odbcinst_GetSections( hIni, pRetBuffer, nRetBuffer, &nBufPos );
    }
    /*****************************************************
     * EXTRACT ENTRIES
     *****************************************************/
    else if ( pszEntry == NULL )
    {
        _odbcinst_GetEntries( hIni, pszSection, pRetBuffer, nRetBuffer, &nBufPos );
    }
    /*****************************************************
     * EXTRACT AN ENTRY
     *****************************************************/
    else
    {
        if ( pszSection == NULL || pszEntry == NULL || pszDefault == NULL )
        {
            inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" );
            return -1;
        }

        /* TRY TO GET THE ONE ITEM MATCHING Section & Entry */
        if ( iniPropertySeek( hIni, (char *)pszSection, (char *)pszEntry, "" ) != INI_SUCCESS )
        {
            /*
             * (NG) this seems to be ignoring the length of pRetBuffer !!!
             */
            /* strncpy( pRetBuffer, pszDefault, INI_MAX_PROPERTY_VALUE ); */
            if ( pRetBuffer && nRetBuffer > 0 && pszDefault )
            {
                strncpy( pRetBuffer, pszDefault, nRetBuffer );
                pRetBuffer[ nRetBuffer - 1 ] = '\0';
            }
        }
        else
        {
            iniValue( hIni, szValue );
	    if ( pRetBuffer ) 
	    {
	        strncpy( pRetBuffer, szValue, nRetBuffer );
	        pRetBuffer[ nRetBuffer - 1 ] = '\0';
	    }
            nBufPos = strlen( szValue );
        }
    }

    iniClose( hIni );

    ret = strlen( pRetBuffer );

    save_ini_cache( ret, pszSection, pszEntry, pszDefault, pRetBuffer, nRetBuffer, pszFileName );

    return ret;
}