1/**************************************************
2 * _SQLGetInstalledDrivers
3 *
4 * Added to allow ODBC Config programs and the ODBC
5 * driver manager to access system information without
6 * having to worry about where it is... just like accessing
7 * Data Source information. So no surprise... its just
8 * like SQLGetPrivateProfileString()!
9 *
10 * see SQLGetPrivateProfileString to see how this is called.
11 *
12 **************************************************
13 * This code was created by Peter Harvey @ CodeByDesign.
14 * Released under LGPL 28.JAN.99
15 *
16 * Contributions from...
17 * -----------------------------------------------
18 * Peter Harvey - pharvey@codebydesign.com
19 **************************************************/
20#include <config.h>
21#include <odbcinstext.h>
22
23int _SQLGetInstalledDrivers( LPCSTR pszSection,
24 LPCSTR pszEntry,
25 LPCSTR pszDefault,
26 LPCSTR pRetBuffer,
27 int nRetBuffer )
28{
29 HINI hIni;
30 int nBufPos = 0;
31 int nStrToCopy;
32 char szObjectName[INI_MAX_OBJECT_NAME+1];
33 char szPropertyName[INI_MAX_PROPERTY_NAME+1];
34 char szValue[INI_MAX_PROPERTY_VALUE+1];
35 char szIniName[ ODBC_FILENAME_MAX * 2 + 3 ];
36 char *ptr;
37 char b1[ ODBC_FILENAME_MAX + 1 ], b2[ ODBC_FILENAME_MAX + 1 ];
38
39 /* SANITY CHECKS */
40 if ( pRetBuffer == NULL || nRetBuffer < 2 )
41 {
42 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" );
43 return -1;
44 }
45
46 /*
47 * first try in the system odbcinst.ini
48 */
49
50#ifdef VMS
51 sprintf( szIniName, "%s:%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ));
52#else
53 sprintf( szIniName, "%s/%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ));
54#endif
55
56 /* PROCESS ODBC INI FILE */
57#ifdef __OS2__
58 if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', 1, 1L ) != INI_SUCCESS )
59#else
60 if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', 1 ) != INI_SUCCESS )
61#endif
62 {
63 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_COMPONENT_NOT_FOUND, "" );
64 return -1;
65 }
66
67 /*
68 * now try the user odbcinst.ini if it exists
69 */
70
71#ifdef VMS
72 sprintf( szIniName, "%s:%s", odbcinst_user_file_path( b1 ), odbcinst_user_file_name( b2 ));
73#else
74 sprintf( szIniName, "%s/%s", odbcinst_user_file_path( b1 ), odbcinst_user_file_name( b2 ));
75#endif
76
77 /* PROCESS .ODBCINST INI FILE */
78 iniAppend( hIni, szIniName );
79
80 nBufPos = 0;
81 if ( pszSection == NULL )
82 {
83 ptr = (char*) pRetBuffer;
84 *ptr = '\0';
85
86 /* JUST COLLECT SECTION NAMES */
87
88 for( iniObjectFirst( hIni ); iniObjectEOL( hIni ) != TRUE; iniObjectNext( hIni ))
89 {
90 iniObject( hIni, szObjectName );
91
92 if ( strcasecmp( szObjectName, "ODBC" ) == 0 )
93 {
94 continue;
95 }
96 else if ( nBufPos + 1 + strlen( szObjectName ) >= nRetBuffer )
97 {
98 break;
99 }
100 else
101 {
102 strcpy( ptr, szObjectName );
103 ptr += strlen( ptr ) + 1;
104 nBufPos += strlen( szObjectName ) + 1;
105 }
106 }
107
108 /*
109 * Add final NULL
110 */
111
112 if ( nBufPos == 0 )
113 {
114 ptr ++;
115 }
116
117 *ptr = '\0';
118 }
119 else if ( pszEntry == NULL )
120 {
121 ptr = (char*) pRetBuffer;
122 *ptr = '\0';
123
124 iniObjectSeek( hIni, (char *)pszSection );
125
126 /* COLLECT ALL ENTRIES FOR THE GIVEN SECTION */
127
128 for( iniPropertyFirst( hIni ); iniPropertyEOL( hIni ) != TRUE; iniPropertyNext( hIni ))
129 {
130 iniProperty( hIni, szPropertyName );
131
132 if ( nBufPos + 1 + strlen( szPropertyName ) >= nRetBuffer )
133 {
134 break;
135 }
136 else
137 {
138 strcpy( ptr, szPropertyName );
139 ptr += strlen( ptr ) + 1;
140 nBufPos += strlen( szPropertyName ) + 1;
141 }
142 }
143
144 /*
145 * Add final NULL
146 */
147
148 if ( nBufPos == 0 )
149 {
150 ptr ++;
151 }
152 }
153 else
154 {
155 /* TRY TO GET THE ONE ITEM MATCHING Section & Entry */
156 if ( iniPropertySeek( hIni, (char *)pszSection, (char *)pszEntry, "" ) != INI_SUCCESS )
157 {
158 /* try to use any default provided */
159 if ( pRetBuffer && nRetBuffer > 0 )
160 {
161 if ( pszDefault )
162 {
163 strncpy( (char *)pRetBuffer, pszDefault, nRetBuffer );
164 ((char*)pRetBuffer)[ nRetBuffer - 1 ] = '\0';
165 }
166 }
167 }
168 else
169 {
170 iniValue( hIni, szValue );
171 nStrToCopy = strlen( szValue ) + 1; /* factor NULL terminator for string */
172 if ( nBufPos + nStrToCopy + 1 > nRetBuffer ) /* factor NULL terminator for buffer */
173 nStrToCopy = nRetBuffer - nBufPos - 2;
174 strncpy( (char *)&(pRetBuffer[nBufPos]), szValue, nStrToCopy );
175 nBufPos += nStrToCopy;
176 /*
177 * length doesn't include NULL
178 */
179 nBufPos--;
180 }
181 }
182
183 /* CLOSE */
184 iniClose( hIni );
185
186 return nBufPos;
187}
188
189
190