Index: scripts/macosx/postflight =================================================================== --- scripts/macosx/postflight (revision 1041) +++ scripts/macosx/postflight (working copy) @@ -9,18 +9,17 @@ # ---------------------------------------------------------------------- # ENSURE WE HAVE INI FILES # -# Upon a fresh install of OSX these files do not exist. The ODBC -# Installer library calls should create these files for us when we do -# stuff like request to register a driver but this does not seem to -# happen and the request fails. So we we start by making sure we have -# some, mostly, empty ini files in place before we make installer -# calls. +# Upon a fresh install of OS X these files do not exist. The ODBC Installer +# library calls should create these files for us when we do stuff like +# request to register a driver but this does not seem to happen and the +# request fails. So we we start by making sure we have some, mostly, empty +# ini files in place before we make installer calls. # -# Also note that there are many places where these ini files *could* -# go based upon the search algorythm in the default ODBC system or any -# other ODBC system which may get installed. We choose the following -# because they seem to be the ones created when we use the standard -# ODBC Admin. GUI application. +# Also note that there are many places where these ini files *could* go +# based upon the search algorithm in the default ODBC system or any other +# ODBC system which may get installed. We choose the following because they +# seem to be the ones created when we use the standard ODBC Administrator +# application. # ---------------------------------------------------------------------- libdir=/usr/local/lib @@ -31,7 +30,7 @@ echo "Ensuring $admdir, odbcinst.ini and odbc.ini exists..." if [ ! -d $admdir ] ; then mkdir $admdir - chmod 755 $admdir + chmod 775 $admdir chown root:admin $admdir fi @@ -43,7 +42,7 @@ echo "TraceAutoStop = 0" >> $admdir/odbc.ini echo "TraceFile =" >> $admdir/odbc.ini echo "TraceLibrary =" >> $admdir/odbc.ini - chmod 644 $admdir/odbc.ini + chmod 664 $admdir/odbc.ini chown root:admin $admdir/odbc.ini fi @@ -53,7 +52,7 @@ echo "[ODBC Connection Pooling]" >> $admdir/odbcinst.ini echo "PerfMon = 0" >> $admdir/odbcinst.ini echo "Retry Wait = " >> $admdir/odbcinst.ini - chmod 644 $admdir/odbcinst.ini + chmod 664 $admdir/odbcinst.ini chown root:admin $admdir/odbcinst.ini fi done @@ -73,7 +72,7 @@ # ---------------------------------------------------------------------- # REGISTER THE DRIVER # ---------------------------------------------------------------------- -echo "Registring driver..." +echo "Registering driver..." $bindir/myodbc3i -a -ds -t"MySQL ODBC 3.51 Driver;Driver=$libdir/libmyodbc3.so;Setup=$libdir/libmyodbc3S.so;" -w0 # ---------------------------------------------------------------------- Index: ChangeLog =================================================================== --- ChangeLog (revision 1041) +++ ChangeLog (working copy) @@ -13,6 +13,10 @@ * SSL connections could not be established properly. Added the server certificate verification flag. (Bug #29955) * Added deprecated SQLSetParam function. (Bug #29871) + * Worked around bug in iODBC installer library that made it impossible + to create a system DSN, particularly on Mac OS X, where the installer + created the /Library/ODBC/*.ini files with insufficient permissions. + (Bug #31495) ---- Index: setup/MYODBCSetupConfigDSNAdd.c =================================================================== --- setup/MYODBCSetupConfigDSNAdd.c (revision 1041) +++ setup/MYODBCSetupConfigDSNAdd.c (working copy) @@ -28,13 +28,7 @@ */ BOOL MYODBCSetupConfigDSNAdd( HWND hWnd, MYODBCUTIL_DATASOURCE *pDataSource ) { - /* - Hang on to the configuration mode, our setup dialog (or maybe just iODBC) - sometimes does things that cause it to be changed. - */ - UWORD configMode; - if (!SQLGetConfigMode(&configMode)) - return FALSE; + SAVE_MODE(); pDataSource->nMode = MYODBCUTIL_DATASOURCE_MODE_DSN_ADD; @@ -82,9 +76,12 @@ */ if ( !SQLValidDSN( pDataSource->pszDSN ) ) { + RESTORE_MODE(); SQLPostInstallerError( ODBC_ERROR_REQUEST_FAILED, "DSN contains illegal characters or length does not make sense." ); return FALSE; } + + RESTORE_MODE(); } /*! @@ -131,10 +128,6 @@ return FALSE; } - /* Restore the configuration mode before we write the DSN. */ - if (!SQLSetConfigMode(configMode)) - return FALSE; - /*! ODBC RULE Index: util/MYODBCUtilWriteDataSource.c =================================================================== --- util/MYODBCUtilWriteDataSource.c (revision 1041) +++ util/MYODBCUtilWriteDataSource.c (working copy) @@ -20,81 +20,60 @@ #include "MYODBCUtil.h" + /*! \brief Creates/replaces the given data source. The use of SQLWriteDSNToIni() means this function does not really update an existing DSN so much as replaces it. -*/ +*/ BOOL MYODBCUtilWriteDataSource( MYODBCUTIL_DATASOURCE *pDataSource ) { - /* + SAVE_MODE(); + + /* SQLWriteDSNToIni is *supposed* to replace any existing DSN with same name but fails (at least on unixODBC) to do so. So we ensure that any existing DSN with same name is removed with the following call. - */ + */ if ( !SQLRemoveDSNFromIni( pDataSource->pszDSN ) ) return FALSE; + RESTORE_MODE(); + /* create/replace data source name */ if ( !SQLWriteDSNToIni( pDataSource->pszDSN, pDataSource->pszDRIVER ) ) return FALSE; + RESTORE_MODE(); + + /* A little helper to avoid duplicated code. */ +#define WRITE_VALUE(field, name) \ + if (pDataSource->psz##field && \ + !SQLWritePrivateProfileString(pDataSource->pszDSN, name, \ + pDataSource->psz##field, "odbc.ini")) \ + return FALSE; \ + RESTORE_MODE() + /* add details */ - if ( pDataSource->pszDATABASE && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "DATABASE", pDataSource->pszDATABASE, "odbc.ini" ) ) - return FALSE; - if ( pDataSource->pszDESCRIPTION && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "DESCRIPTION", pDataSource->pszDESCRIPTION, "odbc.ini" ) ) - return FALSE; - if ( pDataSource->pszOPTION && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "OPTION", pDataSource->pszOPTION, "odbc.ini" ) ) - return FALSE; - if ( pDataSource->pszPASSWORD && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "PWD", pDataSource->pszPASSWORD, "odbc.ini" ) ) - return FALSE; - if ( pDataSource->pszPORT && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "PORT", pDataSource->pszPORT, "odbc.ini" ) ) - return FALSE; - if ( pDataSource->pszSERVER && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "SERVER", pDataSource->pszSERVER, "odbc.ini" ) ) - return FALSE; - if ( pDataSource->pszSOCKET && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "SOCKET", pDataSource->pszSOCKET, "odbc.ini" ) ) - return FALSE; - if ( pDataSource->pszSTMT && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "STMT", pDataSource->pszSTMT, "odbc.ini" ) ) - return FALSE; - if ( pDataSource->pszUSER && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "UID", pDataSource->pszUSER, "odbc.ini" ) ) - return FALSE; - if ( pDataSource->pszSSLCA && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "SSLCA", pDataSource->pszSSLCA, "odbc.ini" ) ) - return FALSE; - if ( pDataSource->pszSSLCAPATH && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "SSLCAPATH", pDataSource->pszSSLCAPATH, "odbc.ini" ) ) - return FALSE; - if ( pDataSource->pszSSLCERT && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "SSLCERT", pDataSource->pszSSLCERT, "odbc.ini" ) ) - return FALSE; - if ( pDataSource->pszSSLCIPHER && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "SSLCIPHER", pDataSource->pszSSLCIPHER, "odbc.ini" ) ) - return FALSE; - if ( pDataSource->pszSSLKEY && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "SSLKEY", pDataSource->pszSSLKEY, "odbc.ini" ) ) - return FALSE; - if ( pDataSource->pszSSLVERIFY && - !SQLWritePrivateProfileString( pDataSource->pszDSN, "SSLVERIFY", pDataSource->pszSSLVERIFY, "odbc.ini" ) ) - return FALSE; - if (pDataSource->pszCHARSET && - !SQLWritePrivateProfileString(pDataSource->pszDSN, "CHARSET", - pDataSource->pszCHARSET, "odbc.ini")) - return FALSE; + WRITE_VALUE(DATABASE, "DATABASE"); + WRITE_VALUE(DESCRIPTION, "DESCRIPTION"); + WRITE_VALUE(OPTION, "OPTION"); + WRITE_VALUE(PASSWORD, "PWD"); + WRITE_VALUE(PORT, "PORT"); + WRITE_VALUE(SERVER, "SERVER"); + WRITE_VALUE(SOCKET, "SOCKET"); + WRITE_VALUE(STMT, "STMT"); + WRITE_VALUE(USER, "UID"); + WRITE_VALUE(SSLCA, "SSLCA"); + WRITE_VALUE(SSLCAPATH, "SSLCAPATH"); + WRITE_VALUE(SSLCERT, "SSLCERT"); + WRITE_VALUE(SSLCIPHER, "SSLCIPHER"); + WRITE_VALUE(SSLKEY, "SSLKEY"); + WRITE_VALUE(SSLVERIFY, "SSLVERIFY"); + WRITE_VALUE(CHARSET, "CHARSET"); return TRUE; } - - - Index: util/MYODBCUtilWriteDriver.c =================================================================== --- util/MYODBCUtilWriteDriver.c (revision 1041) +++ util/MYODBCUtilWriteDriver.c (working copy) @@ -31,21 +31,29 @@ the driver registration. \note If section pDriver->pszName does not exist it will be created - otherwise it is updated. -*/ + otherwise it is updated. +*/ BOOL MYODBCUtilWriteDriver( MYODBCUTIL_DRIVER *pDriver ) { - if ( pDriver->pszName && + SAVE_MODE(); + if ( pDriver->pszName && !SQLWritePrivateProfileString( pDriver->pszName, NULL, NULL, "ODBCINST.INI" ) ) - return FALSE; + { + return FALSE; + } + RESTORE_MODE(); if ( pDriver->pszDRIVER && !SQLWritePrivateProfileString( pDriver->pszName, "DRIVER", pDriver->pszDRIVER, "ODBCINST.INI" ) ) - return FALSE; + { + return FALSE; + } + RESTORE_MODE(); if ( pDriver->pszSETUP && !SQLWritePrivateProfileString( pDriver->pszName, "SETUP", pDriver->pszSETUP, "ODBCINST.INI" ) ) - return FALSE; + { + return FALSE; + } + RESTORE_MODE(); return TRUE; } - - Index: util/MYODBCUtilGetDataSourceNames.c =================================================================== --- util/MYODBCUtilGetDataSourceNames.c (revision 1041) +++ util/MYODBCUtilGetDataSourceNames.c (working copy) @@ -75,9 +75,7 @@ return FALSE; } -#if defined(__APPLE__) && 0 - nChars = GetPrivateProfileString( NULL, NULL, "", pszBuffer, nBuffer - 1, "ODBC.INI" ); -#elif defined(WIN32) +#if defined(WIN32) /* This returns no data as does having a NULL for 1st arg!? Index: util/MYODBCUtilGetDriverNames.c =================================================================== --- util/MYODBCUtilGetDriverNames.c (revision 1041) +++ util/MYODBCUtilGetDriverNames.c (working copy) @@ -38,6 +38,7 @@ BOOL MYODBCUtilGetDriverNames( char *pszBuffer, int nBuffer ) { int nChars = 0; + SAVE_MODE(); /* sanity check @@ -49,9 +50,7 @@ } -#if defined(__APPLE__) && 0 - nChars = GetPrivateProfileString( NULL, NULL, "", pszBuffer, nBuffer - 1, "ODBCINST.INI" ); -#elif defined(WIN32) +#if defined(WIN32) nChars = ( SQLGetInstalledDrivers( pszBuffer, nBuffer - 1, NULL ) ? 1 : 0 ); #else nChars = SQLGetPrivateProfileString( NULL, NULL, "", pszBuffer, nBuffer - 1, "ODBCINST.INI" ); @@ -62,5 +61,7 @@ return FALSE; } + RESTORE_MODE(); + return TRUE; } Index: util/MYODBCUtilDSNExists.c =================================================================== --- util/MYODBCUtilDSNExists.c (revision 1041) +++ util/MYODBCUtilDSNExists.c (working copy) @@ -30,6 +30,7 @@ { char szSectionNames[SQL_MAX_DSN_LENGTH * MYODBCUTIL_MAX_DSN_NAMES]; char * pszSectionName; + SAVE_MODE(); if ( !pszDataSourceName || !(*pszDataSourceName) ) return FALSE; @@ -52,26 +53,19 @@ if ( SQLGetPrivateProfileString( pszDataSourceName, NULL, "", szSectionNames, sizeof( szSectionNames ) - 1, "ODBC.INI" ) > 0 ) return TRUE; else -#elif defined(__APPLE__) && 0 - /*! - \note OSX - - SQLGetPrivateProfileString is the proper call and is available - but - at this time it appears utterly broken. So we call an alternative - instead. - */ - if ( GetPrivateProfileString( NULL, NULL, NULL, szSectionNames, sizeof( szSectionNames ) - 1, "ODBC.INI" ) < 1 ) #else if ( SQLGetPrivateProfileString( NULL, NULL, "", szSectionNames, sizeof( szSectionNames ) - 1, "ODBC.INI" ) < 1 ) #endif { - /*! oops - we take easy way out and just say we did not find it */ - return FALSE; + /*! oops - we take easy way out and just say we did not find it */ + return FALSE; } + RESTORE_MODE(); + /*! Scan result and return TRUE if we find a match. - */ + */ pszSectionName = szSectionNames; while( *pszSectionName ) { Index: util/MYODBCUtil.h =================================================================== --- util/MYODBCUtil.h (revision 1041) +++ util/MYODBCUtil.h (working copy) @@ -61,6 +61,21 @@ #define min( a, b ) (((a) < (b)) ? (a) : (b)) #endif + +/* + Most of the installer API functions in iODBC incorrectly reset the + config mode, so we need to save and restore it whenever we call those + functions. These macros reduce the clutter a little bit. +*/ +#if USE_IODBC +# define SAVE_MODE() UWORD config_mode; (void)SQLGetConfigMode(&config_mode) +# define RESTORE_MODE() (void)SQLSetConfigMode(config_mode) +#else +# define SAVE_MODE() +# define RESTORE_MODE() +#endif + + /* Could use DRIVER_NAME but trying to keep dependency upon driver specific code to a min */ #define MYODBCINST_DRIVER_NAME "MySQL ODBC 3.51 Driver" Index: util/MYODBCUtilReadDataSource.c =================================================================== --- util/MYODBCUtilReadDataSource.c (revision 1041) +++ util/MYODBCUtilReadDataSource.c (working copy) @@ -46,6 +46,7 @@ char * pszEntryName; char szValue[4096]; int nChars; + SAVE_MODE(); #if defined(WIN32) UWORD nMode = ODBC_BOTH_DSN; @@ -62,11 +63,14 @@ *szEntryNames = '\0'; /* Get the list of key names for the DSN's section. */ - if ( ( nChars = SQLGetPrivateProfileString( pszDSN, NULL, "", szEntryNames, sizeof( szEntryNames ) - 1, "ODBC.INI" ) ) < 1 ) - { - return FALSE; - } + nChars= SQLGetPrivateProfileString(pszDSN, NULL, "", + szEntryNames, sizeof(szEntryNames) - 1, + "ODBC.INI"); + if (nChars < 1) + return FALSE; + RESTORE_MODE(); + #if defined(WIN32) { /* @@ -239,6 +243,8 @@ */ } + RESTORE_MODE(); + pszEntryName += strlen( pszEntryName ) + 1; } /* while */ @@ -248,9 +254,11 @@ { if ( SQLGetPrivateProfileString( MYODBCUTIL_ODBCINI_HEADER_SECTION, "", "", szEntryNames, sizeof( szEntryNames ) - 1, "ODBC.INI" ) < 1 ) { - return FALSE; + return FALSE; } + RESTORE_MODE(); + pszEntryName = szEntryNames; while ( *pszEntryName ) { @@ -262,6 +270,7 @@ pDataSource->pszDRIVER = _global_strdup( szValue ); } } + RESTORE_MODE(); pszEntryName += strlen( pszEntryName ) + 1; } } Index: util/MYODBCUtilReadDriver.c =================================================================== --- util/MYODBCUtilReadDriver.c (revision 1041) +++ util/MYODBCUtilReadDriver.c (working copy) @@ -37,6 +37,7 @@ char szEntryNames[SQL_MAX_DSN_LENGTH * MYODBCUTIL_MAX_DSN_NAMES]; char * pszEntryName = NULL; char szValue[4096]; + SAVE_MODE(); /* * Ensure that we have the friendly name of the driver... @@ -60,19 +61,25 @@ else if ( pszFileName && *pszFileName ) { /* get list of sections (friendly driver names)... */ - if ( !MYODBCUtilGetDriverNames( szSectionNames, sizeof(szSectionNames) ) ) - return FALSE; + if (!MYODBCUtilGetDriverNames(szSectionNames, sizeof(szSectionNames))) + return FALSE; + RESTORE_MODE(); + /* get value of DRIVER entry... */ pszSectionName = szSectionNames; while ( *pszSectionName ) { if ( SQLGetPrivateProfileString( pszSectionName, "DRIVER", "", szValue, sizeof( szValue ) - 1, "ODBCINST.INI" ) > 0 ) { + RESTORE_MODE(); + if ( strcmp( szValue, pszFileName ) == 0 ) break; } - + + RESTORE_MODE(); + pszSectionName += strlen( pszSectionName ) + 1; } /* while */ } @@ -93,6 +100,8 @@ return FALSE; } + RESTORE_MODE(); + pszEntryName = szEntryNames; while ( *pszEntryName ) { @@ -115,6 +124,9 @@ /* What the ? */ } } + + RESTORE_MODE(); + pszEntryName += strlen( pszEntryName ) + 1; } /* while */