1/**************************************************
2 * ODBCINSTConstructProperties
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/*
16static const char *aYesNo[] =
17{
18 "Yes",
19 "No",
20 NULL
21};
22*/
23
24/*!
25 * \brief Builds a property list for pszDriver.
26 *
27 * Adds common DSN properties (Name,Driver,Description) and then asks the
28 * drivers setup to load any additional properties.
29 *
30 * This is used to support editing DSN properties without forcing the driver
31 * developer to create a UI for the many different UI implementations. The
32 * driver developer can just implement ODBCINSTGetProperties. This function
33 * can then call ODBCINSTGetProperties to get properties. The code that calls
34 * this function can then display the properties in the UI in use.
35 *
36 * \param pszDriver Friendly driver name.
37 * \param hFirstProperty Place to store the properties list. The properties (including
38 * some of the elements within each HODBCINSTPROPERTY may
39 * need to be freed using \sa ODBCINSTDestructProperties.
40 *
41 * \return int
42 * \retval ODBCINST_ERROR Called failed. No memory was allocated at hFirstProperty. The
43 * likely reasons for this; \li failed to lookup setup library name
44 * \li failed to load setup library \li failed to find
45 * ODBCINSTGetProperties symbol in setup library
46 * \retval ODBCINST_SUCCESS Success! Do not forget to call ODBCINSTDestructProperties to
47 * free memory used by the properties when you are done.
48 *
49 * \sa ODBCINSTDestructProperties
50 */
51int ODBCINSTConstructProperties( char *pszDriver, HODBCINSTPROPERTY *hFirstProperty )
52{
53 char szError[LOG_MSG_MAX+1];
54 char szDriverSetup[ODBC_FILENAME_MAX+1];
55 HINI hIni;
56 int (*pODBCINSTGetProperties)( HODBCINSTPROPERTY );
57 void *hDLL = NULL;
58 HODBCINSTPROPERTY hLastProperty;
59 char szSectionName[INI_MAX_OBJECT_NAME+1];
60 char szIniName[ ODBC_FILENAME_MAX * 2 + 1 ];
61 char b1[ ODBC_FILENAME_MAX + 1 ], b2[ ODBC_FILENAME_MAX + 1 ];
62
63 /* SANITY CHECKS */
64 if ( pszDriver == NULL )
65 {
66 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Need a driver name. Make it the friendly name." );
67 return ODBCINST_ERROR;
68 }
69#ifdef VMS
70 sprintf( szIniName, "%s:%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ));
71#else
72 sprintf( szIniName, "%s/%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ));
73#endif
74
75 /* GET DRIVER SETUP FILE NAME FOR GIVEN DRIVER */
76#ifdef __OS2__
77 if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', FALSE, 1L ) != INI_SUCCESS )
78#else
79 if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', FALSE ) != INI_SUCCESS )
80#endif
81 {
82 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Could not open odbcinst.ini" );
83 return ODBCINST_ERROR;
84 }
85
86#ifdef PLATFORM64
87 /* ASSUME USER FRIENDLY NAME FOR STARTERS */
88 if ( iniPropertySeek( hIni, pszDriver, "Setup64", "" ) == INI_SUCCESS )
89 {
90 }
91 else if ( iniPropertySeek( hIni, pszDriver, "Setup", "" ) == INI_SUCCESS )
92 {
93 }
94 else
95 {
96 /* NOT USER FRIENDLY NAME I GUESS SO ASSUME DRIVER FILE NAME */
97 if ( iniPropertySeek( hIni, "", "Driver64", pszDriver ) == INI_SUCCESS )
98 {
99 iniObject( hIni, szSectionName );
100 if ( iniPropertySeek( hIni, szSectionName, "Setup64", "" ) != INI_SUCCESS )
101 {
102 sprintf( szError, "Could not find Setup property for (%s) in system information", pszDriver );
103 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, szError );
104 iniClose( hIni );
105 return ODBCINST_ERROR;
106 }
107 }
108 else if ( iniPropertySeek( hIni, "", "Driver", pszDriver ) == INI_SUCCESS )
109 {
110 iniObject( hIni, szSectionName );
111 if ( iniPropertySeek( hIni, szSectionName, "Setup", "" ) != INI_SUCCESS )
112 {
113 sprintf( szError, "Could not find Setup property for (%s) in system information", pszDriver );
114 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, szError );
115 iniClose( hIni );
116 return ODBCINST_ERROR;
117 }
118 }
119 else
120 {
121 sprintf( szError, "Could not find driver (%s) in system information", pszDriver );
122 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, szError );
123 iniClose( hIni );
124 return ODBCINST_ERROR;
125 }
126 }
127#else
128 /* ASSUME USER FRIENDLY NAME FOR STARTERS */
129 if ( iniPropertySeek( hIni, pszDriver, "Setup", "" ) != INI_SUCCESS )
130 {
131 /* NOT USER FRIENDLY NAME I GUESS SO ASSUME DRIVER FILE NAME */
132 if ( iniPropertySeek( hIni, "", "Driver", pszDriver ) != INI_SUCCESS )
133 {
134 sprintf( szError, "Could not find driver (%s) in system information", pszDriver );
135 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, szError );
136 iniClose( hIni );
137 return ODBCINST_ERROR;
138 }
139 else
140 {
141 iniObject( hIni, szSectionName );
142 if ( iniPropertySeek( hIni, szSectionName, "Setup", "" ) != INI_SUCCESS )
143 {
144 sprintf( szError, "Could not find Setup property for (%s) in system information", pszDriver );
145 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, szError );
146 iniClose( hIni );
147 return ODBCINST_ERROR;
148 }
149 }
150 }
151#endif
152
153 iniValue( hIni, szDriverSetup );
154 iniClose( hIni );
155
156 if ( szDriverSetup[ 0 ] == '\0' )
157 {
158 sprintf( szError, "Could not find Setup property for (%s) in system information", pszDriver );
159 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, szError );
160 return ODBCINST_ERROR;
161 }
162
163 /*
164 * initialize libtool
165 */
166
167 lt_dlinit();
168
169 /* TRY GET FUNC FROM DRIVER SETUP */
170 if ( !(hDLL = lt_dlopen( szDriverSetup )) )
171 {
172 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Could not load library" );
173 return ODBCINST_ERROR;
174 }
175
176 pODBCINSTGetProperties = (int(*)(struct tODBCINSTPROPERTY*)) lt_dlsym( hDLL, "ODBCINSTGetProperties" );
177
178/* PAH - This can be true even when we found the symbol.
179 if ( lt_dlerror() != NULL )
180*/
181 if ( pODBCINSTGetProperties == NULL )
182 {
183 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Could not find ODBCINSTGetProperties()" );
184 return ODBCINST_ERROR;
185 }
186
187 /* MANDATORY PROPERTIES */
188 (*hFirstProperty) = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) );
189 memset( (*hFirstProperty), 0, sizeof(ODBCINSTPROPERTY) );
190 (*hFirstProperty)->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
191 (*hFirstProperty)->pNext = NULL;
192 (*hFirstProperty)->bRefresh = 0;
193 (*hFirstProperty)->hDLL = hDLL;
194 (*hFirstProperty)->pWidget = NULL;
195 (*hFirstProperty)->pszHelp = NULL;
196 (*hFirstProperty)->aPromptData = NULL;
197 strncpy( (*hFirstProperty)->szName, "Name", INI_MAX_PROPERTY_NAME );
198 strcpy( (*hFirstProperty)->szValue, "" );
199 hLastProperty = (*hFirstProperty);
200
201 (*hFirstProperty)->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) );
202 hLastProperty = (*hFirstProperty)->pNext;
203 memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) );
204 hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
205 hLastProperty->pNext = NULL;
206 hLastProperty->bRefresh = 0;
207 hLastProperty->hDLL = hDLL;
208 hLastProperty->pWidget = NULL;
209 (*hFirstProperty)->pszHelp = NULL;
210 (*hFirstProperty)->aPromptData = NULL;
211 strncpy( hLastProperty->szName, "Description", INI_MAX_PROPERTY_NAME );
212 strncpy( hLastProperty->szValue, pszDriver, INI_MAX_PROPERTY_VALUE );
213
214 hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) );
215 hLastProperty = hLastProperty->pNext;
216 memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) );
217 hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LABEL;
218 hLastProperty->pNext = NULL;
219 hLastProperty->bRefresh = 0;
220 hLastProperty->hDLL = hDLL;
221 hLastProperty->pWidget = NULL;
222 (*hFirstProperty)->pszHelp = NULL;
223 (*hFirstProperty)->aPromptData = NULL;
224 strncpy( hLastProperty->szName, "Driver", INI_MAX_PROPERTY_NAME );
225 strncpy( hLastProperty->szValue, pszDriver, INI_MAX_PROPERTY_VALUE );
226/*
227 hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) );
228 hLastProperty = hLastProperty->pNext;
229 memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) );
230 hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX;
231 hLastProperty->aPromptData = malloc( sizeof(aYesNo) );
232 memcpy( hLastProperty->aPromptData, aYesNo, sizeof(aYesNo) );
233 strncpy( hLastProperty->szName, "Trace", INI_MAX_PROPERTY_NAME );
234 strcpy( hLastProperty->szValue, "No" );
235
236 hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) );
237 hLastProperty = hLastProperty->pNext;
238 memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) );
239 hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_FILENAME;
240 strncpy( hLastProperty->szName, "TraceFile", INI_MAX_PROPERTY_NAME );
241 strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE );
242*/
243
244 /* APPEND OTHERS */
245 pODBCINSTGetProperties( hLastProperty );
246
247 return ODBCINST_SUCCESS;
248}
249
250
251