1/**************************************************
2 *
3 **************************************************
4 * This code was created by Peter Harvey @ CodeByDesign.
5 * Released under LGPL 28.JAN.99
6 *
7 * Contributions from...
8 * -----------------------------------------------
9 * Peter Harvey - pharvey@codebydesign.com
10 **************************************************/
11#include <config.h>
12#include <odbcinstext.h>
13
14static void GetEntries( HINI hIni,
15 LPCSTR pszSection,
16 LPSTR pRetBuffer,
17 int nRetBuffer
18 )
19{
20 char szPropertyName[INI_MAX_PROPERTY_NAME+1];
21 char szValueName[INI_MAX_PROPERTY_NAME+1];
22
23 /* COLLECT ALL ENTRIES FOR THE GIVEN SECTION */
24 iniObjectSeek( hIni, (char *)pszSection );
25 iniPropertyFirst( hIni );
26
27 *pRetBuffer = '\0';
28
29 while ( iniPropertyEOL( hIni ) != TRUE )
30 {
31 iniProperty( hIni, szPropertyName );
32 iniValue( hIni, szValueName );
33
34 if ( strlen( pRetBuffer ) + strlen( szPropertyName ) < nRetBuffer )
35 {
36 strcat( pRetBuffer, szPropertyName );
37 if ( strlen( pRetBuffer ) + 1 < nRetBuffer )
38 {
39 strcat( pRetBuffer, "=" );
40 if ( strlen( pRetBuffer ) + strlen( szValueName ) < nRetBuffer )
41 {
42 strcat( pRetBuffer, szValueName );
43 if ( strlen( pRetBuffer ) + 1 < nRetBuffer )
44 {
45 strcat( pRetBuffer, ";" );
46 }
47 }
48 }
49 }
50
51 iniPropertyNext( hIni );
52 }
53}
54
55static void GetSections( HINI hIni,
56 LPSTR pRetBuffer,
57 int nRetBuffer
58 )
59{
60 char szObjectName[INI_MAX_OBJECT_NAME+1];
61
62 *pRetBuffer = '\0';
63
64 /* JUST COLLECT SECTION NAMES */
65 iniObjectFirst( hIni );
66 while ( iniObjectEOL( hIni ) != TRUE )
67 {
68 iniObject( hIni, szObjectName );
69
70 if ( strcasecmp( szObjectName, "ODBC Data Sources" ) != 0 )
71 {
72 if ( strlen( pRetBuffer ) + strlen( szObjectName ) + 1 < nRetBuffer )
73 {
74 strcat( pRetBuffer, szObjectName );
75 strcat( pRetBuffer, ";" );
76 }
77 }
78 iniObjectNext( hIni );
79 }
80}
81
82BOOL SQLReadFileDSN( LPCSTR pszFileName,
83 LPCSTR pszAppName,
84 LPCSTR pszKeyName,
85 LPSTR pszString,
86 WORD nString,
87 WORD *pnString )
88{
89 HINI hIni;
90 int nBufPos = 0;
91 char szValue[INI_MAX_PROPERTY_VALUE+1];
92 char szFileName[ODBC_FILENAME_MAX+1];
93
94 inst_logClear();
95
96 /* SANITY CHECKS */
97 if ( pszString == NULL || nString < 1 )
98 {
99 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_BUFF_LEN, "" );
100 return FALSE;
101 }
102 if ( pszFileName == NULL && pszAppName == NULL && pszKeyName == NULL )
103 {
104 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" );
105 return FALSE;
106 }
107 if ( pszAppName == NULL && pszKeyName != NULL )
108 {
109 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_REQUEST_TYPE, "" );
110 return FALSE;
111 }
112 if ( pszFileName && strlen( pszFileName ) > ODBC_FILENAME_MAX ) {
113 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_PATH, "" );
114 return FALSE;
115 }
116
117 *pszString = '\0';
118
119 /*****************************************************
120 * GATHER ALL RELEVANT DSN INFORMATION INTO AN hIni
121 *****************************************************/
122 if ( pszFileName && pszFileName[0] == '/' )
123 {
124 strcpy( szFileName, pszFileName );
125 if ( strlen( szFileName ) < 4 || strcmp( szFileName + strlen( szFileName ) - 4, ".dsn" ))
126 {
127 strcat( szFileName, ".dsn" );
128 }
129
130/* on OS/2 the file DSN is a text file */
131#ifdef __OS2__
132 if ( iniOpen( &hIni, (char*)szFileName, "#;", '[', ']', '=', TRUE, 0L )
133 != INI_SUCCESS )
134#else
135 if ( iniOpen( &hIni, (char*)szFileName, "#;", '[', ']', '=', TRUE )
136 != INI_SUCCESS )
137#endif
138 {
139 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL,
140 ODBC_ERROR_INVALID_PATH, "" );
141
142 return FALSE;
143 }
144 }
145 else if ( pszFileName )
146 {
147 char szPath[ODBC_FILENAME_MAX+1];
148 *szPath = '\0';
149 _odbcinst_FileINI( szPath );
150 sprintf( szFileName, "%s/%s", szPath, pszFileName );
151
152 if ( strlen( szFileName ) < 4 || strcmp( szFileName + strlen( szFileName ) - 4, ".dsn" ))
153 {
154 strcat( szFileName, ".dsn" );
155 }
156
157/* on OS/2 the file DSN is a text file */
158#ifdef __OS2__
159 if ( iniOpen( &hIni, (char*) szFileName, "#;", '[', ']', '=', TRUE, 0L )
160 != INI_SUCCESS )
161#else
162 if ( iniOpen( &hIni, (char*) szFileName, "#;", '[', ']', '=', TRUE )
163 != INI_SUCCESS )
164#endif
165 {
166 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL,
167 ODBC_ERROR_INVALID_PATH, "" );
168
169 return FALSE;
170 }
171 }
172
173 if ( pszAppName == NULL && pszKeyName == NULL )
174 {
175 GetSections( hIni, pszString, nString );
176 }
177 else if ( pszAppName != NULL && pszKeyName == NULL )
178 {
179 GetEntries( hIni, pszAppName, pszString, nString );
180 }
181 else
182 {
183 /* TRY TO GET THE ONE ITEM MATCHING Section & Entry */
184 if ( iniPropertySeek( hIni, (char *)pszAppName, (char *)pszKeyName, "" ) != INI_SUCCESS )
185 {
186 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL,
187 ODBC_ERROR_REQUEST_FAILED, "" );
188
189 return FALSE;
190 }
191 else
192 {
193 iniValue( hIni, szValue );
194 strncpy( pszString, szValue, nString );
195 pszString[ nString - 1 ] = '\0';
196 nBufPos = strlen( szValue );
197 }
198 }
199
200 if ( pszFileName )
201 {
202 iniClose( hIni );
203 }
204
205 if ( pnString )
206 {
207 *pnString = strlen( pszString );
208 }
209
210 return TRUE;
211}
212
213BOOL INSTAPI SQLReadFileDSNW(LPCWSTR lpszFileName,
214 LPCWSTR lpszAppName,
215 LPCWSTR lpszKeyName,
216 LPWSTR lpszString,
217 WORD cbString,
218 WORD *pcbString)
219{
220 char *file;
221 char *app;
222 char *key;
223 char *str;
224 WORD len;
225 BOOL ret;
226
227 inst_logClear();
228
229 file = lpszFileName ? _single_string_alloc_and_copy( lpszFileName ) : (char*)NULL;
230 app = lpszAppName ? _single_string_alloc_and_copy( lpszAppName ) : (char*)NULL;
231 key = lpszKeyName ? _single_string_alloc_and_copy( lpszKeyName ) : (char*)NULL;
232
233 if ( lpszString )
234 {
235 if ( cbString > 0 )
236 {
237 str = calloc( cbString + 1, 1 );
238 }
239 else
240 {
241 str = NULL;
242 }
243 }
244 else
245 {
246 str = NULL;
247 }
248
249 ret = SQLReadFileDSN( file, app, key, str, cbString, &len );
250
251 if ( ret )
252 {
253 if ( str && lpszString )
254 {
255 _single_copy_to_wide( lpszString, str, len + 1 );
256 }
257 }
258
259 if ( file )
260 free( file );
261 if ( app )
262 free( app );
263 if ( key )
264 free( key );
265 if ( str )
266 free( str );
267
268 if ( pcbString )
269 *pcbString = len;
270
271 return ret;
272}
273