1/**************************************************
2 * SQLManageDataSources
3 *
4 **************************************************
5 * This code was created by Peter Harvey @ CodeByDesign.
6 * Released under LGPL 28.JAN.99
7 *
8 * Contributions from...
9 * -----------------------------------------------
10 * Peter Harvey - pharvey@codebydesign.com
11 **************************************************/
12#include <config.h>
13#include <odbcinstext.h>
14
15/*!
16 * \brief Get the short name of the UI plugin.
17 *
18 * The short name is the file name without path or file extension.
19 *
20 * We silently prepend "lib" here as well.
21 *
22 * \param pszName Place to put short name. Should be FILENAME_MAX bytes.
23 * \param pszUI Our generic window handle.
24 *
25 * \return char* pszName returned for convenience.
26 */
27char *_getUIPluginName( char *pszName, char *pszUI )
28{
29 *pszName = '\0';
30
31 /* is it being provided by caller? */
32 if ( pszUI && *pszUI )
33 {
34 sprintf( pszName, "lib%s", pszUI );
35 return pszName;
36 }
37
38 /* is it being provided by env var? */
39 {
40 char *pEnvVar = getenv( "ODBCINSTUI" );
41 if ( pEnvVar )
42 {
43 sprintf( pszName, "lib%s", pEnvVar );
44 return pszName;
45 }
46 }
47
48 /* is it being provided by odbcinst.ini? */
49 {
50 char sz[FILENAME_MAX];
51 *sz='\0';
52 SQLGetPrivateProfileString( "ODBC", "ODBCINSTUI", "", sz, FILENAME_MAX, "odbcinst.ini" );
53 if ( *sz )
54 {
55 sprintf( pszName, "lib%s", sz );
56 return pszName;
57 }
58 }
59
60 /* default to qt4 */
61 strcpy( pszName, "libodbcinstQ4" );
62
63 return pszName;
64}
65
66/*!
67 * \brief Append the file extension used by the OS for plugins.
68 *
69 * We use SHLIBEXT which is picked up at configure/build time.
70 *
71 * \param pszNameAndExtension Output. Needs to be FILENAME_MAX bytes.
72 * \param pszName Input.
73 *
74 * \return char* pszNameAndExtension returned for convenience.
75 */
76char *_appendUIPluginExtension( char *pszNameAndExtension, char *pszName )
77{
78 if ( strlen( SHLIBEXT ) > 0 )
79 sprintf( pszNameAndExtension, "%s%s", pszName, SHLIBEXT );
80 else
81 sprintf( pszNameAndExtension, "%s.so", pszName );
82
83 return pszName;
84}
85
86/*!
87 * \brief Prepends the path used for the plugins.
88 *
89 * We use DEFLIB_PATH and if it is not available...
90 * path may not get prepended.
91 *
92 * \param pszPathAndName Output. Needs to be FILENAME_MAX bytes.
93 * \param pszName Input.
94 *
95 * \return char* pszPathAndName is returned for convenience.
96 */
97char *_prependUIPluginPath( char *pszPathAndName, char *pszName )
98{
99 if ( strlen( DEFLIB_PATH ) > 0 )
100 sprintf( pszPathAndName, "%s/%s", DEFLIB_PATH, pszName );
101 else
102 sprintf( pszPathAndName, "%s", pszName );
103
104 return pszPathAndName;
105}
106
107/*!
108 * \brief UI to manage most ODBC system information.
109 *
110 * This calls into the UI plugin library to do our work for us. The caller can provide
111 * the name (base name) of the library or let us determine which library to use.
112 * See \sa _getUIPluginName for details on how the choice is made.
113 *
114 * \param hWnd Input. Parent window handle. This is HWND as per the ODBC
115 * specification but in unixODBC we use a generic window
116 * handle. Caller must cast a HODBCINSTWND to HWND at call.
117 *
118 * \return BOOL
119 *
120 * \sa ODBCINSTWND
121 */
122BOOL SQLManageDataSources( HWND hWnd )
123{
124 HODBCINSTWND hODBCInstWnd = (HODBCINSTWND)hWnd;
125 char szName[FILENAME_MAX];
126 char szNameAndExtension[FILENAME_MAX];
127 char szPathAndName[FILENAME_MAX];
128 void * hDLL;
129 BOOL (*pSQLManageDataSources)(HWND);
130
131 inst_logClear();
132
133 /* ODBC specification states that hWnd is mandatory. */
134 if ( !hWnd )
135 {
136 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_HWND, "No hWnd" );
137 return FALSE;
138 }
139
140 /* initialize libtool */
141 if ( lt_dlinit() )
142 {
143 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "lt_dlinit() failed" );
144 return FALSE;
145 }
146
147 /* get plugin name */
148 _appendUIPluginExtension( szNameAndExtension, _getUIPluginName( szName, hODBCInstWnd->szUI ) );
149
150 /* lets try loading the plugin using an implicit path */
151 hDLL = lt_dlopen( szNameAndExtension );
152 if ( hDLL )
153 {
154 /* change the name (SQLManageDataSources to ODBCManageDataSources) to prevent us from calling ourself */
155 pSQLManageDataSources = (BOOL (*)(HWND))lt_dlsym( hDLL, "ODBCManageDataSources" );
156 if ( pSQLManageDataSources )
157 return pSQLManageDataSources( ( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ) );
158 else
159 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() );
160 }
161 else
162 {
163 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_WARNING, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() );
164 /* try with explicit path */
165 _prependUIPluginPath( szPathAndName, szNameAndExtension );
166 hDLL = lt_dlopen( szPathAndName );
167 if ( hDLL )
168 {
169 /* change the name (SQLManageDataSources to ODBCManageDataSources) to prevent us from calling ourself */
170 /* its only safe to use hWnd if szUI was specified by the caller */
171 pSQLManageDataSources = (BOOL (*)(HWND))lt_dlsym( hDLL, "ODBCManageDataSources" );
172 if ( pSQLManageDataSources )
173 return pSQLManageDataSources( ( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ) );
174 else
175 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() );
176 }
177 else
178 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() );
179 }
180
181 /* report failure to caller */
182 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Failed to load/use a UI plugin." );
183
184 return FALSE;
185}
186
187
188