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 | /* |
16 | static 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 | */ |
51 | int 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 | |