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; }