OSDN Git Service

Fix bit rot in pg_dump's ability to dump from 7.2 and 7.1 servers.
[pg-rex/syncrep.git] / src / interfaces / odbc / dlg_specific.c
1 /*-------
2  * Module:                      dlg_specific.c
3  *
4  * Description:         This module contains any specific code for handling
5  *                                      dialog boxes such as driver/datasource options.  Both the
6  *                                      ConfigDSN() and the SQLDriverConnect() functions use
7  *                                      functions in this module.  If you were to add a new option
8  *                                      to any dialog box, you would most likely only have to change
9  *                                      things in here rather than in 2 separate places as before.
10  *
11  * Classes:                     none
12  *
13  * API functions:       none
14  *
15  * Comments:            See "notice.txt" for copyright and license information.
16  *-------
17  */
18 /* Multibyte support    Eiji Tokuya 2001-03-15 */
19
20 #include "dlg_specific.h"
21
22 #include "convert.h"
23
24 #ifdef MULTIBYTE
25 #include "multibyte.h"
26 #endif
27 #include "pgapifunc.h"
28
29 #ifndef BOOL
30 #define BOOL    int
31 #endif
32 #ifndef FALSE
33 #define FALSE   (BOOL)0
34 #endif
35 #ifndef TRUE
36 #define TRUE    (BOOL)1
37 #endif
38
39 extern GLOBAL_VALUES globals;
40
41 void
42 makeConnectString(char *connect_string, const ConnInfo *ci, UWORD len)
43 {
44         char            got_dsn = (ci->dsn[0] != '\0');
45         char            encoded_conn_settings[LARGE_REGISTRY_LEN];
46         UWORD           hlen;
47         /*BOOL          abbrev = (len <= 400);*/
48         BOOL            abbrev = (len < 1024);
49
50         /* fundamental info */
51         sprintf(connect_string, "%s=%s;DATABASE=%s;SERVER=%s;PORT=%s;UID=%s;PWD=%s",
52                         got_dsn ? "DSN" : "DRIVER",
53                         got_dsn ? ci->dsn : ci->driver,
54                         ci->database,
55                         ci->server,
56                         ci->port,
57                         ci->username,
58                         ci->password);
59
60         encode(ci->conn_settings, encoded_conn_settings);
61
62         /* extra info */
63         hlen = strlen(connect_string);
64         if (!abbrev)
65                 sprintf(&connect_string[hlen],
66                                 ";%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%s;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d",
67                                 INI_READONLY,
68                                 ci->onlyread,
69                                 INI_PROTOCOL,
70                                 ci->protocol,
71                                 INI_FAKEOIDINDEX,
72                                 ci->fake_oid_index,
73                                 INI_SHOWOIDCOLUMN,
74                                 ci->show_oid_column,
75                                 INI_ROWVERSIONING,
76                                 ci->row_versioning,
77                                 INI_SHOWSYSTEMTABLES,
78                                 ci->show_system_tables,
79                                 INI_CONNSETTINGS,
80                                 encoded_conn_settings,
81                                 INI_FETCH,
82                                 ci->drivers.fetch_max,
83                                 INI_SOCKET,
84                                 ci->drivers.socket_buffersize,
85                                 INI_UNKNOWNSIZES,
86                                 ci->drivers.unknown_sizes,
87                                 INI_MAXVARCHARSIZE,
88                                 ci->drivers.max_varchar_size,
89                                 INI_MAXLONGVARCHARSIZE,
90                                 ci->drivers.max_longvarchar_size,
91                                 INI_DEBUG,
92                                 ci->drivers.debug,
93                                 INI_COMMLOG,
94                                 ci->drivers.commlog,
95                                 INI_OPTIMIZER,
96                                 ci->drivers.disable_optimizer,
97                                 INI_KSQO,
98                                 ci->drivers.ksqo,
99                                 INI_USEDECLAREFETCH,
100                                 ci->drivers.use_declarefetch,
101                                 INI_TEXTASLONGVARCHAR,
102                                 ci->drivers.text_as_longvarchar,
103                                 INI_UNKNOWNSASLONGVARCHAR,
104                                 ci->drivers.unknowns_as_longvarchar,
105                                 INI_BOOLSASCHAR,
106                                 ci->drivers.bools_as_char,
107                                 INI_PARSE,
108                                 ci->drivers.parse,
109                                 INI_CANCELASFREESTMT,
110                                 ci->drivers.cancel_as_freestmt,
111                                 INI_EXTRASYSTABLEPREFIXES,
112                                 ci->drivers.extra_systable_prefixes,
113                                 INI_LFCONVERSION,
114                                 ci->lf_conversion,
115                                 INI_UPDATABLECURSORS,
116                                 ci->allow_keyset,
117                                 INI_DISALLOWPREMATURE,
118                                 ci->disallow_premature,
119                                 INI_TRUEISMINUS1,
120                                 ci->true_is_minus1,
121                                 INI_INT8AS,
122                                 ci->true_is_minus1);
123         /* Abbrebiation is needed ? */
124         if (abbrev || strlen(connect_string) >= len)
125         {
126                 unsigned long flag = 0;
127                 if (ci->disallow_premature)
128                         flag |= BIT_DISALLOWPREMATURE;
129                 if (ci->allow_keyset)
130                         flag |= BIT_UPDATABLECURSORS;
131                 if (ci->lf_conversion)
132                         flag |= BIT_LFCONVERSION;
133                 if (ci->drivers.unique_index)
134                         flag |= BIT_UNIQUEINDEX;
135                 if (strncmp(ci->protocol, PG64, strlen(PG64)) == 0)
136                         flag |= BIT_PROTOCOL_64;
137                 else if (strncmp(ci->protocol, PG63, strlen(PG63)) == 0)
138                         flag |= BIT_PROTOCOL_63;
139                 switch (ci->drivers.unknown_sizes)
140                 {
141                         case UNKNOWNS_AS_DONTKNOW:
142                                 flag |= BIT_UNKNOWN_DONTKNOW;
143                                 break;
144                         case UNKNOWNS_AS_MAX:
145                                 flag |= BIT_UNKNOWN_ASMAX;
146                                 break;
147                 }
148                 if (ci->drivers.disable_optimizer)
149                         flag |= BIT_OPTIMIZER;
150                 if (ci->drivers.ksqo)
151                         flag |= BIT_KSQO;
152                 if (ci->drivers.commlog)
153                         flag |= BIT_COMMLOG;
154                 if (ci->drivers.debug)
155                         flag |= BIT_DEBUG;
156                 if (ci->drivers.parse)
157                         flag |= BIT_PARSE;
158                 if (ci->drivers.cancel_as_freestmt)
159                         flag |= BIT_CANCELASFREESTMT;
160                 if (ci->drivers.use_declarefetch)
161                         flag |= BIT_USEDECLAREFETCH;
162                 if (ci->onlyread[0] == '1')
163                         flag |= BIT_READONLY;
164                 if (ci->drivers.text_as_longvarchar)
165                         flag |= BIT_TEXTASLONGVARCHAR;
166                 if (ci->drivers.unknowns_as_longvarchar)
167                         flag |= BIT_UNKNOWNSASLONGVARCHAR;
168                 if (ci->drivers.bools_as_char)
169                         flag |= BIT_BOOLSASCHAR;
170                 if (ci->row_versioning[0] == '1')
171                         flag |= BIT_ROWVERSIONING;
172                 if (ci->show_system_tables[0] == '1')
173                         flag |= BIT_SHOWSYSTEMTABLES;
174                 if (ci->show_oid_column[0] == '1')
175                         flag |= BIT_SHOWOIDCOLUMN;
176                 if (ci->fake_oid_index[0] == '1')
177                         flag |= BIT_FAKEOIDINDEX;
178                 if (ci->true_is_minus1)
179                         flag |= BIT_TRUEISMINUS1;
180
181                 sprintf(&connect_string[hlen],
182                                 ";A6=%s;A7=%d;A8=%d;B0=%d;B1=%d;%s=%d;C2=%s;CX=%02x%lx",
183                                 encoded_conn_settings,
184                                 ci->drivers.fetch_max,
185                                 ci->drivers.socket_buffersize,
186                                 ci->drivers.max_varchar_size,
187                                 ci->drivers.max_longvarchar_size,
188                                 INI_INT8AS,
189                                 ci->int8_as,
190                                 ci->drivers.extra_systable_prefixes,
191                                 EFFECTIVE_BIT_COUNT,
192                                 flag);
193         }
194 }
195
196 static void
197 unfoldCXAttribute(ConnInfo *ci, const char *value)
198 {
199         int             count;
200         unsigned long   flag;
201
202         if (strlen(value) < 2)
203         {
204                 count = 3;
205                 sscanf(value, "%lx", &flag);
206         }
207         else
208         {
209                 char    cnt[8];
210                 memcpy(cnt, value, 2);
211                 cnt[2] = '\0';
212                 sscanf(cnt, "%x", &count);
213                 sscanf(value + 2, "%lx", &flag);
214         }
215         ci->disallow_premature = (char)((flag & BIT_DISALLOWPREMATURE) != 0);
216         ci->allow_keyset = (char)((flag & BIT_UPDATABLECURSORS) != 0);
217         ci->lf_conversion = (char)((flag & BIT_LFCONVERSION) != 0);
218         if (count < 4)
219                 return;
220         ci->drivers.unique_index = (char)((flag & BIT_UNIQUEINDEX) != 0);
221         if ((flag & BIT_PROTOCOL_64) != 0)
222                 strcpy(ci->protocol, PG64);
223         else if ((flag & BIT_PROTOCOL_63) != 0)
224                 strcpy(ci->protocol, PG63);
225         else
226                 strcpy(ci->protocol, PG62);
227         if ((flag & BIT_UNKNOWN_DONTKNOW) != 0)
228                 ci->drivers.unknown_sizes = UNKNOWNS_AS_DONTKNOW;
229         else if ((flag & BIT_UNKNOWN_ASMAX) != 0)
230                 ci->drivers.unknown_sizes = UNKNOWNS_AS_MAX;
231         else 
232                 ci->drivers.unknown_sizes = UNKNOWNS_AS_LONGEST;
233         ci->drivers.disable_optimizer = (char)((flag & BIT_OPTIMIZER) != 0);
234         ci->drivers.ksqo = (char)((flag & BIT_KSQO) != 0);
235         ci->drivers.commlog = (char)((flag & BIT_COMMLOG) != 0);
236         ci->drivers.debug = (char)((flag & BIT_DEBUG) != 0);
237         ci->drivers.parse = (char)((flag & BIT_PARSE) != 0);
238         ci->drivers.cancel_as_freestmt = (char)((flag & BIT_CANCELASFREESTMT) != 0);
239         ci->drivers.use_declarefetch = (char)((flag & BIT_USEDECLAREFETCH) != 0);
240         sprintf(ci->onlyread, "%d", (char)((flag & BIT_READONLY) != 0));
241         ci->drivers.text_as_longvarchar = (char)((flag & BIT_TEXTASLONGVARCHAR) !=0);
242         ci->drivers.unknowns_as_longvarchar = (char)((flag & BIT_UNKNOWNSASLONGVARCHAR) !=0);
243         ci->drivers.bools_as_char = (char)((flag & BIT_BOOLSASCHAR) != 0);
244         sprintf(ci->row_versioning, "%d", (char)((flag & BIT_ROWVERSIONING) != 0));
245         sprintf(ci->show_system_tables, "%d", (char)((flag & BIT_SHOWSYSTEMTABLES) != 0));
246         sprintf(ci->show_oid_column, "%d", (char)((flag & BIT_SHOWOIDCOLUMN) != 0));
247         sprintf(ci->fake_oid_index, "%d", (char)((flag & BIT_FAKEOIDINDEX) != 0));
248         ci->true_is_minus1 = (char)((flag & BIT_TRUEISMINUS1) != 0);
249 }
250 void
251 copyAttributes(ConnInfo *ci, const char *attribute, const char *value)
252 {
253         if (stricmp(attribute, "DSN") == 0)
254                 strcpy(ci->dsn, value);
255
256         else if (stricmp(attribute, "driver") == 0)
257                 strcpy(ci->driver, value);
258
259         else if (stricmp(attribute, INI_DATABASE) == 0)
260                 strcpy(ci->database, value);
261
262         else if (stricmp(attribute, INI_SERVER) == 0 || stricmp(attribute, "server") == 0)
263                 strcpy(ci->server, value);
264
265         else if (stricmp(attribute, INI_USER) == 0 || stricmp(attribute, "uid") == 0)
266                 strcpy(ci->username, value);
267
268         else if (stricmp(attribute, INI_PASSWORD) == 0 || stricmp(attribute, "pwd") == 0)
269                 strcpy(ci->password, value);
270
271         else if (stricmp(attribute, INI_PORT) == 0)
272                 strcpy(ci->port, value);
273
274         else if (stricmp(attribute, INI_READONLY) == 0 || stricmp(attribute, "A0") == 0)
275                 strcpy(ci->onlyread, value);
276
277         else if (stricmp(attribute, INI_PROTOCOL) == 0 || stricmp(attribute, "A1") == 0)
278                 strcpy(ci->protocol, value);
279
280         else if (stricmp(attribute, INI_SHOWOIDCOLUMN) == 0 || stricmp(attribute, "A3") == 0)
281                 strcpy(ci->show_oid_column, value);
282
283         else if (stricmp(attribute, INI_FAKEOIDINDEX) == 0 || stricmp(attribute, "A2") == 0)
284                 strcpy(ci->fake_oid_index, value);
285
286         else if (stricmp(attribute, INI_ROWVERSIONING) == 0 || stricmp(attribute, "A4") == 0)
287                 strcpy(ci->row_versioning, value);
288
289         else if (stricmp(attribute, INI_SHOWSYSTEMTABLES) == 0 || stricmp(attribute, "A5") == 0)
290                 strcpy(ci->show_system_tables, value);
291
292         else if (stricmp(attribute, INI_CONNSETTINGS) == 0 || stricmp(attribute, "A6") == 0)
293         {
294                 decode(value, ci->conn_settings);
295                 /* strcpy(ci->conn_settings, value); */
296         }
297         else if (stricmp(attribute, INI_DISALLOWPREMATURE) == 0 || stricmp(attribute, "C3") == 0)
298                 ci->disallow_premature = atoi(value);
299         else if (stricmp(attribute, INI_UPDATABLECURSORS) == 0 || stricmp(attribute, "C4") == 0)
300                 ci->allow_keyset = atoi(value);
301         else if (stricmp(attribute, INI_LFCONVERSION) == 0)
302                 ci->lf_conversion = atoi(value);
303         else if (stricmp(attribute, INI_TRUEISMINUS1) == 0)
304                 ci->true_is_minus1 = atoi(value);
305         else if (stricmp(attribute, INI_INT8AS) == 0)
306                 ci->int8_as = atoi(value);
307         else if (stricmp(attribute, "CX") == 0)
308                 unfoldCXAttribute(ci, value);
309
310         mylog("copyAttributes: DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s',conn_settings='%s',disallow_premature=%d)\n", ci->dsn, ci->server, ci->database, ci->username, ci->password, ci->port, ci->onlyread, ci->protocol, ci->conn_settings, ci->disallow_premature);
311 }
312
313 void
314 copyCommonAttributes(ConnInfo *ci, const char *attribute, const char *value)
315 {
316         if (stricmp(attribute, INI_FETCH) == 0 || stricmp(attribute, "A7") == 0)
317                 ci->drivers.fetch_max = atoi(value);
318         else if (stricmp(attribute, INI_SOCKET) == 0 || stricmp(attribute, "A8") == 0)
319                 ci->drivers.socket_buffersize = atoi(value);
320         else if (stricmp(attribute, INI_DEBUG) == 0 || stricmp(attribute, "B2") == 0)
321                 ci->drivers.debug = atoi(value);
322         else if (stricmp(attribute, INI_COMMLOG) == 0 || stricmp(attribute, "B3") == 0)
323                 ci->drivers.commlog = atoi(value);
324         else if (stricmp(attribute, INI_OPTIMIZER) == 0 || stricmp(attribute, "B4") == 0)
325                 ci->drivers.disable_optimizer = atoi(value);
326         else if (stricmp(attribute, INI_KSQO) == 0 || stricmp(attribute, "B5") == 0)
327                 ci->drivers.ksqo = atoi(value);
328
329         /*
330          * else if (stricmp(attribute, INI_UNIQUEINDEX) == 0 ||
331          * stricmp(attribute, "UIX") == 0) ci->drivers.unique_index =
332          * atoi(value);
333          */
334         else if (stricmp(attribute, INI_UNKNOWNSIZES) == 0 || stricmp(attribute, "A9") == 0)
335                 ci->drivers.unknown_sizes = atoi(value);
336         else if (stricmp(attribute, INI_LIE) == 0)
337                 ci->drivers.lie = atoi(value);
338         else if (stricmp(attribute, INI_PARSE) == 0 || stricmp(attribute, "C0") == 0)
339                 ci->drivers.parse = atoi(value);
340         else if (stricmp(attribute, INI_CANCELASFREESTMT) == 0 || stricmp(attribute, "C1") == 0)
341                 ci->drivers.cancel_as_freestmt = atoi(value);
342         else if (stricmp(attribute, INI_USEDECLAREFETCH) == 0 || stricmp(attribute, "B6") == 0)
343                 ci->drivers.use_declarefetch = atoi(value);
344         else if (stricmp(attribute, INI_MAXVARCHARSIZE) == 0 || stricmp(attribute, "B0") == 0)
345                 ci->drivers.max_varchar_size = atoi(value);
346         else if (stricmp(attribute, INI_MAXLONGVARCHARSIZE) == 0 || stricmp(attribute, "B1") == 0)
347                 ci->drivers.max_longvarchar_size = atoi(value);
348         else if (stricmp(attribute, INI_TEXTASLONGVARCHAR) == 0 || stricmp(attribute, "B7") == 0)
349                 ci->drivers.text_as_longvarchar = atoi(value);
350         else if (stricmp(attribute, INI_UNKNOWNSASLONGVARCHAR) == 0 || stricmp(attribute, "B8") == 0)
351                 ci->drivers.unknowns_as_longvarchar = atoi(value);
352         else if (stricmp(attribute, INI_BOOLSASCHAR) == 0 || stricmp(attribute, "B9") == 0)
353                 ci->drivers.bools_as_char = atoi(value);
354         else if (stricmp(attribute, INI_EXTRASYSTABLEPREFIXES) == 0 || stricmp(attribute, "C2") == 0)
355                 strcpy(ci->drivers.extra_systable_prefixes, value);
356         mylog("CopyCommonAttributes: A7=%d;A8=%d;A9=%d;B0=%d;B1=%d;B2=%d;B3=%d;B4=%d;B5=%d;B6=%d;B7=%d;B8=%d;B9=%d;C0=%d;C1=%d;C2=%s",
357                   ci->drivers.fetch_max,
358                   ci->drivers.socket_buffersize,
359                   ci->drivers.unknown_sizes,
360                   ci->drivers.max_varchar_size,
361                   ci->drivers.max_longvarchar_size,
362                   ci->drivers.debug,
363                   ci->drivers.commlog,
364                   ci->drivers.disable_optimizer,
365                   ci->drivers.ksqo,
366                   ci->drivers.use_declarefetch,
367                   ci->drivers.text_as_longvarchar,
368                   ci->drivers.unknowns_as_longvarchar,
369                   ci->drivers.bools_as_char,
370                   ci->drivers.parse,
371                   ci->drivers.cancel_as_freestmt,
372                   ci->drivers.extra_systable_prefixes);
373 }
374
375
376 void
377 getDSNdefaults(ConnInfo *ci)
378 {
379         if (ci->port[0] == '\0')
380                 strcpy(ci->port, DEFAULT_PORT);
381
382         if (ci->onlyread[0] == '\0')
383                 sprintf(ci->onlyread, "%d", globals.onlyread);
384
385         if (ci->protocol[0] == '\0')
386                 strcpy(ci->protocol, globals.protocol);
387
388         if (ci->fake_oid_index[0] == '\0')
389                 sprintf(ci->fake_oid_index, "%d", DEFAULT_FAKEOIDINDEX);
390
391         if (ci->show_oid_column[0] == '\0')
392                 sprintf(ci->show_oid_column, "%d", DEFAULT_SHOWOIDCOLUMN);
393
394         if (ci->show_system_tables[0] == '\0')
395                 sprintf(ci->show_system_tables, "%d", DEFAULT_SHOWSYSTEMTABLES);
396
397         if (ci->row_versioning[0] == '\0')
398                 sprintf(ci->row_versioning, "%d", DEFAULT_ROWVERSIONING);
399
400         if (ci->disallow_premature < 0)
401                 ci->disallow_premature = DEFAULT_DISALLOWPREMATURE;
402         if (ci->allow_keyset < 0)
403                 ci->allow_keyset = DEFAULT_UPDATABLECURSORS;
404         if (ci->lf_conversion < 0)
405                 ci->lf_conversion = DEFAULT_LFCONVERSION;
406         if (ci->true_is_minus1 < 0)
407                 ci->true_is_minus1 = DEFAULT_TRUEISMINUS1;
408         if (ci->int8_as < -100)
409                 ci->int8_as = DEFAULT_INT8AS;
410 }
411
412
413 void
414 getDSNinfo(ConnInfo *ci, char overwrite)
415 {
416         char       *DSN = ci->dsn;
417         char            encoded_conn_settings[LARGE_REGISTRY_LEN],
418                                 temp[SMALL_REGISTRY_LEN];
419
420 /*
421  *      If a driver keyword was present, then dont use a DSN and return.
422  *      If DSN is null and no driver, then use the default datasource.
423  */
424         if (DSN[0] == '\0')
425         {
426                 if (ci->driver[0] != '\0')
427                         return;
428                 else
429                         strcpy(DSN, INI_DSN);
430         }
431
432         /* brute-force chop off trailing blanks... */
433         while (*(DSN + strlen(DSN) - 1) == ' ')
434                 *(DSN + strlen(DSN) - 1) = '\0';
435
436         /* Proceed with getting info for the given DSN. */
437
438         if (ci->desc[0] == '\0' || overwrite)
439                 SQLGetPrivateProfileString(DSN, INI_KDESC, "", ci->desc, sizeof(ci->desc), ODBC_INI);
440
441         if (ci->server[0] == '\0' || overwrite)
442                 SQLGetPrivateProfileString(DSN, INI_SERVER, "", ci->server, sizeof(ci->server), ODBC_INI);
443
444         if (ci->database[0] == '\0' || overwrite)
445                 SQLGetPrivateProfileString(DSN, INI_DATABASE, "", ci->database, sizeof(ci->database), ODBC_INI);
446
447         if (ci->username[0] == '\0' || overwrite)
448                 SQLGetPrivateProfileString(DSN, INI_USER, "", ci->username, sizeof(ci->username), ODBC_INI);
449
450         if (ci->password[0] == '\0' || overwrite)
451                 SQLGetPrivateProfileString(DSN, INI_PASSWORD, "", ci->password, sizeof(ci->password), ODBC_INI);
452
453         if (ci->port[0] == '\0' || overwrite)
454                 SQLGetPrivateProfileString(DSN, INI_PORT, "", ci->port, sizeof(ci->port), ODBC_INI);
455
456         if (ci->onlyread[0] == '\0' || overwrite)
457                 SQLGetPrivateProfileString(DSN, INI_READONLY, "", ci->onlyread, sizeof(ci->onlyread), ODBC_INI);
458
459         if (ci->show_oid_column[0] == '\0' || overwrite)
460                 SQLGetPrivateProfileString(DSN, INI_SHOWOIDCOLUMN, "", ci->show_oid_column, sizeof(ci->show_oid_column), ODBC_INI);
461
462         if (ci->fake_oid_index[0] == '\0' || overwrite)
463                 SQLGetPrivateProfileString(DSN, INI_FAKEOIDINDEX, "", ci->fake_oid_index, sizeof(ci->fake_oid_index), ODBC_INI);
464
465         if (ci->row_versioning[0] == '\0' || overwrite)
466                 SQLGetPrivateProfileString(DSN, INI_ROWVERSIONING, "", ci->row_versioning, sizeof(ci->row_versioning), ODBC_INI);
467
468         if (ci->show_system_tables[0] == '\0' || overwrite)
469                 SQLGetPrivateProfileString(DSN, INI_SHOWSYSTEMTABLES, "", ci->show_system_tables, sizeof(ci->show_system_tables), ODBC_INI);
470
471         if (ci->protocol[0] == '\0' || overwrite)
472                 SQLGetPrivateProfileString(DSN, INI_PROTOCOL, "", ci->protocol, sizeof(ci->protocol), ODBC_INI);
473
474         if (ci->conn_settings[0] == '\0' || overwrite)
475         {
476                 SQLGetPrivateProfileString(DSN, INI_CONNSETTINGS, "", encoded_conn_settings, sizeof(encoded_conn_settings), ODBC_INI);
477                 decode(encoded_conn_settings, ci->conn_settings);
478         }
479
480         if (ci->translation_dll[0] == '\0' || overwrite)
481                 SQLGetPrivateProfileString(DSN, INI_TRANSLATIONDLL, "", ci->translation_dll, sizeof(ci->translation_dll), ODBC_INI);
482
483         if (ci->translation_option[0] == '\0' || overwrite)
484                 SQLGetPrivateProfileString(DSN, INI_TRANSLATIONOPTION, "", ci->translation_option, sizeof(ci->translation_option), ODBC_INI);
485
486         if (ci->disallow_premature < 0 || overwrite)
487         {
488                 SQLGetPrivateProfileString(DSN, INI_DISALLOWPREMATURE, "", temp, sizeof(temp), ODBC_INI);
489                 if (temp[0])
490                         ci->disallow_premature = atoi(temp);
491         }
492
493         if (ci->allow_keyset < 0 || overwrite)
494         {
495                 SQLGetPrivateProfileString(DSN, INI_UPDATABLECURSORS, "", temp, sizeof(temp), ODBC_INI);
496                 if (temp[0])
497                         ci->allow_keyset = atoi(temp);
498         }
499
500         if (ci->lf_conversion < 0 || overwrite)
501         {
502                 SQLGetPrivateProfileString(DSN, INI_LFCONVERSION, "", temp, sizeof(temp), ODBC_INI);
503                 if (temp[0])
504                         ci->lf_conversion = atoi(temp);
505         }
506
507         if (ci->true_is_minus1 < 0 || overwrite)
508         {
509                 SQLGetPrivateProfileString(DSN, INI_TRUEISMINUS1, "", temp, sizeof(temp), ODBC_INI);
510                 if (temp[0])
511                         ci->true_is_minus1 = atoi(temp);
512         }
513
514         if (ci->int8_as < -100 || overwrite)
515         {
516                 SQLGetPrivateProfileString(DSN, INI_INT8AS, "", temp, sizeof(temp), ODBC_INI);
517                 if (temp[0])
518                         ci->int8_as = atoi(temp);
519         }
520
521         /* Allow override of odbcinst.ini parameters here */
522         getCommonDefaults(DSN, ODBC_INI, ci);
523
524         qlog("DSN info: DSN='%s',server='%s',port='%s',dbase='%s',user='%s',passwd='%s'\n",
525                  DSN,
526                  ci->server,
527                  ci->port,
528                  ci->database,
529                  ci->username,
530                  ci->password);
531         qlog("          onlyread='%s',protocol='%s',showoid='%s',fakeoidindex='%s',showsystable='%s'\n",
532                  ci->onlyread,
533                  ci->protocol,
534                  ci->show_oid_column,
535                  ci->fake_oid_index,
536                  ci->show_system_tables);
537
538 #ifdef MULTIBYTE
539         check_client_encoding(ci->conn_settings);
540         qlog("          conn_settings='%s',conn_encoding='%s'\n",
541                  ci->conn_settings,
542                  check_client_encoding(ci->conn_settings));
543 #else
544         qlog("          conn_settings='%s'\n",
545                  ci->conn_settings);
546 #endif
547
548         qlog("          translation_dll='%s',translation_option='%s'\n",
549                  ci->translation_dll,
550                  ci->translation_option);
551 }
552
553 /*
554  *      This function writes any global parameters (that can be manipulated)
555  *      to the ODBCINST.INI portion of the registry
556  */
557 void
558 writeDriverCommoninfo(const ConnInfo *ci)
559 {
560         const char *sectionName;
561         const char *fileName;
562         const GLOBAL_VALUES *comval;
563         char            tmp[128];
564
565         if (ci)
566                 if (ci->dsn && ci->dsn[0])
567                 {
568                         mylog("DSN=%s updating\n", ci->dsn);
569                         comval = &(ci->drivers);
570                         sectionName = ci->dsn;
571                         fileName = ODBC_INI;
572                 }
573                 else
574                 {
575                         mylog("ci but dsn==NULL\n");
576                         return;
577                 }
578         else
579         {
580                 mylog("drivers updating\n");
581                 comval = &globals;
582                 sectionName = DBMS_NAME;
583                 fileName = ODBCINST_INI;
584         }
585         sprintf(tmp, "%d", comval->fetch_max);
586         SQLWritePrivateProfileString(sectionName,
587                                                                  INI_FETCH, tmp, fileName);
588
589         sprintf(tmp, "%d", comval->commlog);
590         SQLWritePrivateProfileString(sectionName,
591                                                                  INI_COMMLOG, tmp, fileName);
592
593         sprintf(tmp, "%d", comval->debug);
594         SQLWritePrivateProfileString(sectionName,
595                                                                  INI_DEBUG, tmp, fileName);
596
597         sprintf(tmp, "%d", comval->disable_optimizer);
598         SQLWritePrivateProfileString(sectionName,
599                                                                  INI_OPTIMIZER, tmp, fileName);
600
601         sprintf(tmp, "%d", comval->ksqo);
602         SQLWritePrivateProfileString(sectionName,
603                                                                  INI_KSQO, tmp, fileName);
604
605         sprintf(tmp, "%d", comval->unique_index);
606         SQLWritePrivateProfileString(sectionName, INI_UNIQUEINDEX, tmp, fileName);
607         /*
608          * Never update the onlyread from this module.
609          */
610         if (!ci)
611         {
612                 sprintf(tmp, "%d", comval->onlyread);
613                 SQLWritePrivateProfileString(sectionName, INI_READONLY, tmp,
614                                                                          fileName);
615         }
616
617         sprintf(tmp, "%d", comval->use_declarefetch);
618         SQLWritePrivateProfileString(sectionName,
619                                                                  INI_USEDECLAREFETCH, tmp, fileName);
620
621         sprintf(tmp, "%d", comval->unknown_sizes);
622         SQLWritePrivateProfileString(sectionName,
623                                                                  INI_UNKNOWNSIZES, tmp, fileName);
624
625         sprintf(tmp, "%d", comval->text_as_longvarchar);
626         SQLWritePrivateProfileString(sectionName,
627                                                                  INI_TEXTASLONGVARCHAR, tmp, fileName);
628
629         sprintf(tmp, "%d", comval->unknowns_as_longvarchar);
630         SQLWritePrivateProfileString(sectionName,
631                                                            INI_UNKNOWNSASLONGVARCHAR, tmp, fileName);
632
633         sprintf(tmp, "%d", comval->bools_as_char);
634         SQLWritePrivateProfileString(sectionName,
635                                                                  INI_BOOLSASCHAR, tmp, fileName);
636
637         sprintf(tmp, "%d", comval->parse);
638         SQLWritePrivateProfileString(sectionName,
639                                                                  INI_PARSE, tmp, fileName);
640
641         sprintf(tmp, "%d", comval->cancel_as_freestmt);
642         SQLWritePrivateProfileString(sectionName,
643                                                                  INI_CANCELASFREESTMT, tmp, fileName);
644
645         sprintf(tmp, "%d", comval->max_varchar_size);
646         SQLWritePrivateProfileString(sectionName,
647                                                                  INI_MAXVARCHARSIZE, tmp, fileName);
648
649         sprintf(tmp, "%d", comval->max_longvarchar_size);
650         SQLWritePrivateProfileString(sectionName,
651                                                                  INI_MAXLONGVARCHARSIZE, tmp, fileName);
652
653         SQLWritePrivateProfileString(sectionName,
654         INI_EXTRASYSTABLEPREFIXES, comval->extra_systable_prefixes, fileName);
655
656         /*
657          * Never update the conn_setting from this module
658          * SQLWritePrivateProfileString(sectionName, INI_CONNSETTINGS,
659          * comval->conn_settings, fileName);
660          */
661 }
662
663 /*      This is for datasource based options only */
664 void
665 writeDSNinfo(const ConnInfo *ci)
666 {
667         const char *DSN = ci->dsn;
668         char            encoded_conn_settings[LARGE_REGISTRY_LEN],
669                                 temp[SMALL_REGISTRY_LEN];
670
671         encode(ci->conn_settings, encoded_conn_settings);
672
673         SQLWritePrivateProfileString(DSN,
674                                                                  INI_KDESC,
675                                                                  ci->desc,
676                                                                  ODBC_INI);
677
678         SQLWritePrivateProfileString(DSN,
679                                                                  INI_DATABASE,
680                                                                  ci->database,
681                                                                  ODBC_INI);
682
683         SQLWritePrivateProfileString(DSN,
684                                                                  INI_SERVER,
685                                                                  ci->server,
686                                                                  ODBC_INI);
687
688         SQLWritePrivateProfileString(DSN,
689                                                                  INI_PORT,
690                                                                  ci->port,
691                                                                  ODBC_INI);
692
693         SQLWritePrivateProfileString(DSN,
694                                                                  INI_USER,
695                                                                  ci->username,
696                                                                  ODBC_INI);
697
698         SQLWritePrivateProfileString(DSN,
699                                                                  INI_PASSWORD,
700                                                                  ci->password,
701                                                                  ODBC_INI);
702
703         SQLWritePrivateProfileString(DSN,
704                                                                  INI_READONLY,
705                                                                  ci->onlyread,
706                                                                  ODBC_INI);
707
708         SQLWritePrivateProfileString(DSN,
709                                                                  INI_SHOWOIDCOLUMN,
710                                                                  ci->show_oid_column,
711                                                                  ODBC_INI);
712
713         SQLWritePrivateProfileString(DSN,
714                                                                  INI_FAKEOIDINDEX,
715                                                                  ci->fake_oid_index,
716                                                                  ODBC_INI);
717
718         SQLWritePrivateProfileString(DSN,
719                                                                  INI_ROWVERSIONING,
720                                                                  ci->row_versioning,
721                                                                  ODBC_INI);
722
723         SQLWritePrivateProfileString(DSN,
724                                                                  INI_SHOWSYSTEMTABLES,
725                                                                  ci->show_system_tables,
726                                                                  ODBC_INI);
727
728         SQLWritePrivateProfileString(DSN,
729                                                                  INI_PROTOCOL,
730                                                                  ci->protocol,
731                                                                  ODBC_INI);
732
733         SQLWritePrivateProfileString(DSN,
734                                                                  INI_CONNSETTINGS,
735                                                                  encoded_conn_settings,
736                                                                  ODBC_INI);
737
738         sprintf(temp, "%d", ci->disallow_premature);
739         SQLWritePrivateProfileString(DSN,
740                                                                  INI_DISALLOWPREMATURE,
741                                                                  temp,
742                                                                  ODBC_INI);
743         sprintf(temp, "%d", ci->allow_keyset);
744         SQLWritePrivateProfileString(DSN,
745                                                                  INI_UPDATABLECURSORS,
746                                                                  temp,
747                                                                  ODBC_INI);
748         sprintf(temp, "%d", ci->lf_conversion);
749         SQLWritePrivateProfileString(DSN,
750                                                                  INI_LFCONVERSION,
751                                                                  temp,
752                                                                  ODBC_INI);
753         sprintf(temp, "%d", ci->true_is_minus1);
754         SQLWritePrivateProfileString(DSN,
755                                                                  INI_TRUEISMINUS1,
756                                                                  temp,
757                                                                  ODBC_INI);
758         sprintf(temp, "%d", ci->int8_as);
759         SQLWritePrivateProfileString(DSN,
760                                                                  INI_INT8AS,
761                                                                  temp,
762                                                                  ODBC_INI);
763 }
764
765
766 /*
767  *      This function reads the ODBCINST.INI portion of
768  *      the registry and gets any driver defaults.
769  */
770 void
771 getCommonDefaults(const char *section, const char *filename, ConnInfo *ci)
772 {
773         char            temp[256];
774         GLOBAL_VALUES *comval;
775
776         if (ci)
777                 comval = &(ci->drivers);
778         else
779                 comval = &globals;
780         /* Fetch Count is stored in driver section */
781         SQLGetPrivateProfileString(section, INI_FETCH, "",
782                                                            temp, sizeof(temp), filename);
783         if (temp[0])
784         {
785                 comval->fetch_max = atoi(temp);
786                 /* sanity check if using cursors */
787                 if (comval->fetch_max <= 0)
788                         comval->fetch_max = FETCH_MAX;
789         }
790         else if (!ci)
791                 comval->fetch_max = FETCH_MAX;
792
793         /* Socket Buffersize is stored in driver section */
794         SQLGetPrivateProfileString(section, INI_SOCKET, "",
795                                                            temp, sizeof(temp), filename);
796         if (temp[0])
797                 comval->socket_buffersize = atoi(temp);
798         else if (!ci)
799                 comval->socket_buffersize = SOCK_BUFFER_SIZE;
800
801         /* Debug is stored in the driver section */
802         SQLGetPrivateProfileString(section, INI_DEBUG, "",
803                                                            temp, sizeof(temp), filename);
804         if (temp[0])
805                 comval->debug = atoi(temp);
806         else if (!ci)
807                 comval->debug = DEFAULT_DEBUG;
808
809         /* CommLog is stored in the driver section */
810         SQLGetPrivateProfileString(section, INI_COMMLOG, "",
811                                                            temp, sizeof(temp), filename);
812         if (temp[0])
813                 comval->commlog = atoi(temp);
814         else if (!ci)
815                 comval->commlog = DEFAULT_COMMLOG;
816
817         if (!ci)
818                 logs_on_off(0, 0, 0);
819         /* Optimizer is stored in the driver section only */
820         SQLGetPrivateProfileString(section, INI_OPTIMIZER, "",
821                                                            temp, sizeof(temp), filename);
822         if (temp[0])
823                 comval->disable_optimizer = atoi(temp);
824         else if (!ci)
825                 comval->disable_optimizer = DEFAULT_OPTIMIZER;
826
827         /* KSQO is stored in the driver section only */
828         SQLGetPrivateProfileString(section, INI_KSQO, "",
829                                                            temp, sizeof(temp), filename);
830         if (temp[0])
831                 comval->ksqo = atoi(temp);
832         else if (!ci)
833                 comval->ksqo = DEFAULT_KSQO;
834
835         /* Recognize Unique Index is stored in the driver section only */
836         SQLGetPrivateProfileString(section, INI_UNIQUEINDEX, "",
837                                                            temp, sizeof(temp), filename);
838         if (temp[0])
839                 comval->unique_index = atoi(temp);
840         else if (!ci)
841                 comval->unique_index = DEFAULT_UNIQUEINDEX;
842
843
844         /* Unknown Sizes is stored in the driver section only */
845         SQLGetPrivateProfileString(section, INI_UNKNOWNSIZES, "",
846                                                            temp, sizeof(temp), filename);
847         if (temp[0])
848                 comval->unknown_sizes = atoi(temp);
849         else if (!ci)
850                 comval->unknown_sizes = DEFAULT_UNKNOWNSIZES;
851
852
853         /* Lie about supported functions? */
854         SQLGetPrivateProfileString(section, INI_LIE, "",
855                                                            temp, sizeof(temp), filename);
856         if (temp[0])
857                 comval->lie = atoi(temp);
858         else if (!ci)
859                 comval->lie = DEFAULT_LIE;
860
861         /* Parse statements */
862         SQLGetPrivateProfileString(section, INI_PARSE, "",
863                                                            temp, sizeof(temp), filename);
864         if (temp[0])
865                 comval->parse = atoi(temp);
866         else if (!ci)
867                 comval->parse = DEFAULT_PARSE;
868
869         /* SQLCancel calls SQLFreeStmt in Driver Manager */
870         SQLGetPrivateProfileString(section, INI_CANCELASFREESTMT, "",
871                                                            temp, sizeof(temp), filename);
872         if (temp[0])
873                 comval->cancel_as_freestmt = atoi(temp);
874         else if (!ci)
875                 comval->cancel_as_freestmt = DEFAULT_CANCELASFREESTMT;
876
877         /* UseDeclareFetch is stored in the driver section only */
878         SQLGetPrivateProfileString(section, INI_USEDECLAREFETCH, "",
879                                                            temp, sizeof(temp), filename);
880         if (temp[0])
881                 comval->use_declarefetch = atoi(temp);
882         else if (!ci)
883                 comval->use_declarefetch = DEFAULT_USEDECLAREFETCH;
884
885         /* Max Varchar Size */
886         SQLGetPrivateProfileString(section, INI_MAXVARCHARSIZE, "",
887                                                            temp, sizeof(temp), filename);
888         if (temp[0])
889                 comval->max_varchar_size = atoi(temp);
890         else if (!ci)
891                 comval->max_varchar_size = MAX_VARCHAR_SIZE;
892
893         /* Max TextField Size */
894         SQLGetPrivateProfileString(section, INI_MAXLONGVARCHARSIZE, "",
895                                                            temp, sizeof(temp), filename);
896         if (temp[0])
897                 comval->max_longvarchar_size = atoi(temp);
898         else if (!ci)
899                 comval->max_longvarchar_size = TEXT_FIELD_SIZE;
900
901         /* Text As LongVarchar  */
902         SQLGetPrivateProfileString(section, INI_TEXTASLONGVARCHAR, "",
903                                                            temp, sizeof(temp), filename);
904         if (temp[0])
905                 comval->text_as_longvarchar = atoi(temp);
906         else if (!ci)
907                 comval->text_as_longvarchar = DEFAULT_TEXTASLONGVARCHAR;
908
909         /* Unknowns As LongVarchar      */
910         SQLGetPrivateProfileString(section, INI_UNKNOWNSASLONGVARCHAR, "",
911                                                            temp, sizeof(temp), filename);
912         if (temp[0])
913                 comval->unknowns_as_longvarchar = atoi(temp);
914         else if (!ci)
915                 comval->unknowns_as_longvarchar = DEFAULT_UNKNOWNSASLONGVARCHAR;
916
917         /* Bools As Char */
918         SQLGetPrivateProfileString(section, INI_BOOLSASCHAR, "",
919                                                            temp, sizeof(temp), filename);
920         if (temp[0])
921                 comval->bools_as_char = atoi(temp);
922         else if (!ci)
923                 comval->bools_as_char = DEFAULT_BOOLSASCHAR;
924
925         /* Extra Systable prefixes */
926
927         /*
928          * Use @@@ to distinguish between blank extra prefixes and no key
929          * entry
930          */
931         SQLGetPrivateProfileString(section, INI_EXTRASYSTABLEPREFIXES, "@@@",
932                                                            temp, sizeof(temp), filename);
933         if (strcmp(temp, "@@@"))
934                 strcpy(comval->extra_systable_prefixes, temp);
935         else if (!ci)
936                 strcpy(comval->extra_systable_prefixes, DEFAULT_EXTRASYSTABLEPREFIXES);
937
938         mylog("globals.extra_systable_prefixes = '%s'\n", comval->extra_systable_prefixes);
939
940
941         /* Dont allow override of an override! */
942         if (!ci)
943         {
944                 /*
945                  * ConnSettings is stored in the driver section and per datasource
946                  * for override
947                  */
948                 SQLGetPrivateProfileString(section, INI_CONNSETTINGS, "",
949                  comval->conn_settings, sizeof(comval->conn_settings), filename);
950
951                 /* Default state for future DSN's Readonly attribute */
952                 SQLGetPrivateProfileString(section, INI_READONLY, "",
953                                                                    temp, sizeof(temp), filename);
954                 if (temp[0])
955                         comval->onlyread = atoi(temp);
956                 else
957                         comval->onlyread = DEFAULT_READONLY;
958
959                 /*
960                  * Default state for future DSN's protocol attribute This isn't a
961                  * real driver option YET.      This is more intended for
962                  * customization from the install.
963                  */
964                 SQLGetPrivateProfileString(section, INI_PROTOCOL, "@@@",
965                                                                    temp, sizeof(temp), filename);
966                 if (strcmp(temp, "@@@"))
967                         strcpy(comval->protocol, temp);
968                 else
969                         strcpy(comval->protocol, DEFAULT_PROTOCOL);
970         }
971 }