]> git.saurik.com Git - wxWidgets.git/blob - src/iodbc/info.c
that was a memory leak
[wxWidgets.git] / src / iodbc / info.c
1 /*
2 * info.c
3 *
4 * $Id$
5 *
6 * Information functions
7 *
8 * The iODBC driver manager.
9 *
10 * Copyright (C) 1995 by Ke Jin <kejin@empress.com>
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Library General Public
14 * License as published by the Free Software Foundation; either
15 * version 2 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with this library; if not, write to the Free
24 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27 #include "config.h"
28
29 #include "isql.h"
30 #include "isqlext.h"
31
32 #include "dlproc.h"
33
34 #include "herr.h"
35 #include "henv.h"
36 #include "hdbc.h"
37 #include "hstmt.h"
38
39 #include "itrace.h"
40
41 #include <stdio.h>
42 #include <ctype.h>
43
44 #define SECT1 "ODBC Data Sources"
45 #define SECT2 "Default"
46 #define MAX_ENTRIES 1024
47
48 extern char * _iodbcdm_getinifile (char *buf, int size);
49 extern char * _iodbcdm_getkeyvalbydsn (char *dsn, int dsnlen, char *keywd, char *value, int size);
50
51 static int
52 stricmp (const char *s1, const char *s2)
53 {
54 int cmp;
55
56 while (*s1)
57 {
58 if ((cmp = toupper (*s1) - toupper (*s2)) != 0)
59 return cmp;
60 s1++;
61 s2++;
62 }
63 return (*s2) ? -1 : 0;
64 }
65
66 static int
67 SectSorter (const void *p1, const void *p2)
68 {
69 char **s1 = (char **) p1;
70 char **s2 = (char **) p2;
71
72 return stricmp (*s1, *s2);
73 }
74
75
76 RETCODE SQL_API
77 SQLDataSources (
78 HENV henv,
79 UWORD fDir,
80 UCHAR FAR * szDSN,
81 SWORD cbDSNMax,
82 SWORD FAR * pcbDSN,
83 UCHAR FAR * szDesc,
84 SWORD cbDescMax,
85 SWORD FAR * pcbDesc)
86 {
87 GENV_t FAR *genv = (GENV_t FAR *) henv;
88 char *path;
89 char buf[1024];
90 FILE *fp;
91 int i;
92 static int cur_entry = -1;
93 static int num_entries = 0;
94 static char **sect = NULL;
95
96 if (henv == SQL_NULL_HENV)
97 {
98 return SQL_INVALID_HANDLE;
99 }
100 /* check argument */
101 if (cbDSNMax < 0 || cbDescMax < 0)
102 {
103 PUSHSQLERR (genv->herr, en_S1090);
104
105 return SQL_ERROR;
106 }
107 if (fDir != SQL_FETCH_FIRST
108 && fDir != SQL_FETCH_NEXT)
109 {
110 PUSHSQLERR (genv->herr, en_S1103);
111
112 return SQL_ERROR;
113 }
114 if (cur_entry < 0 || fDir == SQL_FETCH_FIRST)
115 {
116 cur_entry = 0;
117 num_entries = 0;
118
119
120 /*
121 * Open the odbc.ini file
122 */
123 path = (char *) _iodbcdm_getinifile (buf, sizeof (buf));
124 if ((fp = fopen (path, "r")) == NULL)
125 {
126 return SQL_NO_DATA_FOUND;
127 }
128 /*
129 * Free old section list
130 */
131 if (sect)
132 {
133 for (i = 0; i < MAX_ENTRIES; i++)
134 if (sect[i])
135 free (sect[i]);
136 free (sect);
137 }
138 if ((sect = (char **) calloc (MAX_ENTRIES, sizeof (char *))) == NULL)
139 {
140 PUSHSQLERR (genv->herr, en_S1011);
141
142 return SQL_ERROR;
143 }
144 /*
145 * Build a dynamic list of sections
146 */
147 while (1)
148 {
149 char *str, *p;
150
151 str = fgets (buf, sizeof (buf), fp);
152
153 if (str == NULL)
154 break;
155
156 if (*str == '[')
157 {
158 str++;
159 for (p = str; *p; p++)
160 if (*p == ']')
161 *p = '\0';
162
163 if (!strcmp (str, SECT1))
164 continue;
165 if (!strcmp (str, SECT2))
166 continue;
167
168 /*
169 * Add this section to the comma separated list
170 */
171 if (num_entries >= MAX_ENTRIES)
172 break; /* Skip the rest */
173
174 sect[num_entries++] = (char *) strdup (str);
175 }
176 }
177
178 /*
179 * Sort all entries so we can present a nice list
180 */
181 if (num_entries > 1)
182 qsort (sect, num_entries, sizeof (char *), SectSorter);
183 }
184 /*
185 * Try to get to the next item
186 */
187 if (cur_entry >= num_entries)
188 {
189 cur_entry = 0; /* Next time, start all over again */
190 return SQL_NO_DATA_FOUND;
191 }
192 /*
193 * Copy DSN information
194 */
195 STRNCPY (szDSN, sect[cur_entry], cbDSNMax);
196 /*
197 glt??? pcbDSN = strlen(szDSN);
198 */
199 /*
200 * And find the description that goes with this entry
201 */
202 _iodbcdm_getkeyvalbydsn (sect[cur_entry], strlen (sect[cur_entry]),
203 "Description", (char*) szDesc, cbDescMax);
204 /*
205 glt??? pcbDesc = strlen(szDesc);
206 */
207 /*
208 * Next record
209 */
210 cur_entry++;
211
212 return SQL_SUCCESS;
213 }
214
215
216 RETCODE SQL_API
217 SQLDrivers (
218 HENV henv,
219 UWORD fDir,
220 UCHAR FAR * szDrvDesc,
221 SWORD cbDrvDescMax,
222 SWORD FAR * pcbDrvDesc,
223 UCHAR FAR * szDrvAttr,
224 SWORD cbDrvAttrMax,
225 SWORD FAR * pcbDrvAttr)
226 {
227 GENV_t FAR *genv = (GENV_t FAR *) henv;
228
229 if (henv == SQL_NULL_HENV)
230 {
231 return SQL_INVALID_HANDLE;
232 }
233
234 if (cbDrvDescMax < 0 || cbDrvAttrMax < 0 || cbDrvAttrMax == 1)
235 {
236 PUSHSQLERR (genv->herr, en_S1090);
237
238 return SQL_ERROR;
239 }
240
241 if (fDir != SQL_FETCH_FIRST || fDir != SQL_FETCH_NEXT)
242 {
243 PUSHSQLERR (genv->herr, en_S1103);
244
245 return SQL_ERROR;
246 }
247
248 /*********************/
249 return SQL_NO_DATA_FOUND;
250 }
251
252
253 RETCODE SQL_API
254 SQLGetInfo (
255 HDBC hdbc,
256 UWORD fInfoType,
257 PTR rgbInfoValue,
258 SWORD cbInfoValueMax,
259 SWORD FAR * pcbInfoValue)
260 {
261 DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
262 ENV_t FAR *penv;
263 STMT_t FAR *pstmt = NULL;
264 STMT_t FAR *tpstmt;
265 HPROC hproc;
266 RETCODE retcode = SQL_SUCCESS;
267
268 DWORD dword;
269 int size = 0, len = 0;
270 char buf[16] = {'\0'};
271
272 if (hdbc == SQL_NULL_HDBC || pdbc->henv == SQL_NULL_HENV)
273 {
274 return SQL_INVALID_HANDLE;
275 }
276
277 if (cbInfoValueMax < 0)
278 {
279 PUSHSQLERR (pdbc->herr, en_S1090);
280
281 return SQL_ERROR;
282 }
283
284 if ( /* fInfoType < SQL_INFO_FIRST || */
285 (fInfoType > SQL_INFO_LAST
286 && fInfoType < SQL_INFO_DRIVER_START))
287 {
288 PUSHSQLERR (pdbc->herr, en_S1096);
289
290 return SQL_ERROR;
291 }
292
293 if (fInfoType == SQL_ODBC_VER)
294 {
295 sprintf (buf, "%02d.%02d",
296 (ODBCVER) >> 8, 0x00FF & (ODBCVER));
297
298
299 if (rgbInfoValue != NULL
300 && cbInfoValueMax > 0)
301 {
302 len = STRLEN (buf);
303
304 if (len < cbInfoValueMax - 1)
305 {
306 len = cbInfoValueMax - 1;
307 PUSHSQLERR (pdbc->herr, en_01004);
308
309 retcode = SQL_SUCCESS_WITH_INFO;
310 }
311
312 STRNCPY (rgbInfoValue, buf, len);
313 ((char FAR *) rgbInfoValue)[len] = '\0';
314 }
315
316 if (pcbInfoValue != NULL)
317 {
318 *pcbInfoValue = (SWORD) len;
319 }
320
321 return retcode;
322 }
323
324 if (pdbc->state == en_dbc_allocated || pdbc->state == en_dbc_needdata)
325 {
326 PUSHSQLERR (pdbc->herr, en_08003);
327
328 return SQL_ERROR;
329 }
330
331 switch (fInfoType)
332 {
333 case SQL_DRIVER_HDBC:
334 dword = (DWORD) (pdbc->dhdbc);
335 size = sizeof (dword);
336 break;
337
338 case SQL_DRIVER_HENV:
339 penv = (ENV_t FAR *) (pdbc->henv);
340 dword = (DWORD) (penv->dhenv);
341 size = sizeof (dword);
342 break;
343
344 case SQL_DRIVER_HLIB:
345 penv = (ENV_t FAR *) (pdbc->henv);
346 dword = (DWORD) (penv->hdll);
347 size = sizeof (dword);
348 break;
349
350 case SQL_DRIVER_HSTMT:
351 if (rgbInfoValue != NULL)
352 {
353 pstmt = *((STMT_t FAR **) rgbInfoValue);
354 }
355
356 for (tpstmt = (STMT_t FAR *) (pdbc->hstmt);
357 tpstmt != NULL;
358 tpstmt = tpstmt->next)
359 {
360 if (tpstmt == pstmt)
361 {
362 break;
363 }
364 }
365
366 if (tpstmt == NULL)
367 {
368 PUSHSQLERR (pdbc->herr, en_S1009);
369
370 return SQL_ERROR;
371 }
372
373 dword = (DWORD) (pstmt->dhstmt);
374 size = sizeof (dword);
375 break;
376
377 default:
378 break;
379 }
380
381 if (size)
382 {
383 if (rgbInfoValue != NULL)
384 {
385 *((DWORD *) rgbInfoValue) = dword;
386 }
387
388 if (pcbInfoValue != NULL)
389 {
390 *(pcbInfoValue) = (SWORD) size;
391 }
392
393 return SQL_SUCCESS;
394 }
395
396 hproc = _iodbcdm_getproc (hdbc, en_GetInfo);
397
398 if (hproc == SQL_NULL_HPROC)
399 {
400 PUSHSQLERR (pdbc->herr, en_IM001);
401
402 return SQL_ERROR;
403 }
404
405 CALL_DRIVER (hdbc, retcode, hproc, en_GetInfo,
406 (pdbc->dhdbc, fInfoType, rgbInfoValue, cbInfoValueMax, pcbInfoValue))
407
408 if (retcode == SQL_ERROR
409 && fInfoType == SQL_DRIVER_ODBC_VER)
410 {
411 STRCPY (buf, "01.00");
412
413 if (rgbInfoValue != NULL
414 && cbInfoValueMax > 0)
415 {
416 len = STRLEN (buf);
417
418 if (len < cbInfoValueMax - 1)
419 {
420 len = cbInfoValueMax - 1;
421 PUSHSQLERR (pdbc->herr, en_01004);
422 }
423
424 STRNCPY (rgbInfoValue, buf, len);
425 ((char FAR *) rgbInfoValue)[len] = '\0';
426 }
427
428 if (pcbInfoValue != NULL)
429 {
430 *pcbInfoValue = (SWORD) len;
431 }
432
433 /* what should we return in this case ???? */
434 }
435
436 return retcode;
437 }
438
439
440 RETCODE SQL_API
441 SQLGetFunctions (
442 HDBC hdbc,
443 UWORD fFunc,
444 UWORD FAR * pfExists)
445 {
446 DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
447 HPROC hproc;
448 RETCODE retcode;
449
450 if (hdbc == SQL_NULL_HDBC)
451 {
452 return SQL_INVALID_HANDLE;
453 }
454
455 if (fFunc > SQL_EXT_API_LAST)
456 {
457 PUSHSQLERR (pdbc->herr, en_S1095);
458
459 return SQL_ERROR;
460 }
461
462 if (pdbc->state == en_dbc_allocated
463 || pdbc->state == en_dbc_needdata)
464 {
465 PUSHSQLERR (pdbc->herr, en_S1010);
466
467 return SQL_ERROR;
468 }
469
470 if (pfExists == NULL)
471 {
472 return SQL_SUCCESS;
473 }
474
475 hproc = _iodbcdm_getproc (hdbc, en_GetFunctions);
476
477 if (hproc != SQL_NULL_HPROC)
478 {
479 CALL_DRIVER (hdbc, retcode, hproc, en_GetFunctions,
480 (pdbc->dhdbc, fFunc, pfExists))
481
482 return retcode;
483 }
484
485 if (fFunc == SQL_API_SQLSETPARAM)
486 {
487 fFunc = SQL_API_SQLBINDPARAMETER;
488 }
489
490 if (fFunc != SQL_API_ALL_FUNCTIONS)
491 {
492 hproc = _iodbcdm_getproc (hdbc, fFunc);
493
494 if (hproc == SQL_NULL_HPROC)
495 {
496 *pfExists = (UWORD) 0;
497 }
498 else
499 {
500 *pfExists = (UWORD) 1;
501 }
502
503 return SQL_SUCCESS;
504 }
505
506 for (fFunc = 0; fFunc < 100; fFunc++)
507 {
508 hproc = _iodbcdm_getproc (hdbc, fFunc);
509
510 if (hproc == SQL_NULL_HPROC)
511 {
512 pfExists[fFunc] = (UWORD) 0;
513 }
514 else
515 {
516 pfExists[fFunc] = (UWORD) 1;
517 }
518 }
519
520 return SQL_SUCCESS;
521 }