2 Star 0 Fork 0

Chan-i / psqlodbc

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
dlg_specific.c 54.36 KB
一键复制 编辑 原始数据 按行查看 历史
foxi 提交于 2022-10-31 17:47 . modify SQLBrowseConnect
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896
/*-------
* Module: dlg_specific.c
*
* Description: This module contains any specific code for handling
* dialog boxes such as driver/datasource options. Both the
* ConfigDSN() and the SQLDriverConnect() functions use
* functions in this module. If you were to add a new option
* to any dialog box, you would most likely only have to change
* things in here rather than in 2 separate places as before.
*
* Classes: none
*
* API functions: none
*
* Comments: See "readme.txt" for copyright and license information.
*-------
*/
/* Multibyte support Eiji Tokuya 2001-03-15 */
#include <ctype.h>
#include "dlg_specific.h"
#include "misc.h"
#include "pgapifunc.h"
#define NULL_IF_NULL(a) ((a) ? ((const char *)(a)) : "(null)")
CSTR ENTRY_TEST = " @@@ ";
static void encode(const pgNAME, char *out, int outlen);
static pgNAME decode(const char *in);
static pgNAME decode_or_remove_braces(const char *in);
#define OVR_EXTRA_BITS (BIT_FORCEABBREVCONNSTR | BIT_FAKE_MSS | BIT_BDE_ENVIRONMENT | BIT_CVT_NULL_DATE | BIT_ACCESSIBLE_ONLY | BIT_IGNORE_ROUND_TRIP_TIME | BIT_DISABLE_KEEPALIVE)
UInt4 getExtraOptions(const ConnInfo *ci)
{
UInt4 flag = ci->extra_opts & (~OVR_EXTRA_BITS);
if (ci->force_abbrev_connstr > 0)
flag |= BIT_FORCEABBREVCONNSTR;
else if (ci->force_abbrev_connstr == 0)
flag &= (~BIT_FORCEABBREVCONNSTR);
if (ci->fake_mss > 0)
flag |= BIT_FAKE_MSS;
else if (ci->fake_mss == 0)
flag &= (~BIT_FAKE_MSS);
if (ci->bde_environment > 0)
flag |= BIT_BDE_ENVIRONMENT;
else if (ci->bde_environment == 0)
flag &= (~BIT_BDE_ENVIRONMENT);
if (ci->cvt_null_date_string > 0)
flag |= BIT_CVT_NULL_DATE;
else if (ci->cvt_null_date_string == 0)
flag &= (~BIT_CVT_NULL_DATE);
if (ci->accessible_only > 0)
flag |= BIT_ACCESSIBLE_ONLY;
else if (ci->accessible_only == 0)
flag &= (~BIT_ACCESSIBLE_ONLY);
if (ci->ignore_round_trip_time > 0)
flag |= BIT_IGNORE_ROUND_TRIP_TIME;
else if (ci->ignore_round_trip_time == 0)
flag &= (~BIT_IGNORE_ROUND_TRIP_TIME);
if (ci->disable_keepalive > 0)
flag |= BIT_DISABLE_KEEPALIVE;
else if (ci->disable_keepalive == 0)
flag &= (~BIT_DISABLE_KEEPALIVE);
return flag;
}
CSTR hex_format = "%x";
CSTR dec_format = "%u";
CSTR octal_format = "%o";
static UInt4 replaceExtraOptions(ConnInfo *ci, UInt4 flag, BOOL overwrite)
{
if (overwrite)
ci->extra_opts = flag;
else
ci->extra_opts |= (flag & ~(OVR_EXTRA_BITS));
if (overwrite || ci->force_abbrev_connstr < 0)
ci->force_abbrev_connstr = (0 != (flag & BIT_FORCEABBREVCONNSTR));
if (overwrite || ci->fake_mss < 0)
ci->fake_mss = (0 != (flag & BIT_FAKE_MSS));
if (overwrite || ci->bde_environment < 0)
ci->bde_environment = (0 != (flag & BIT_BDE_ENVIRONMENT));
if (overwrite || ci->cvt_null_date_string < 0)
ci->cvt_null_date_string = (0 != (flag & BIT_CVT_NULL_DATE));
if (overwrite || ci->accessible_only < 0)
ci->accessible_only = (0 != (flag & BIT_ACCESSIBLE_ONLY));
if (overwrite || ci->ignore_round_trip_time < 0)
ci->ignore_round_trip_time = (0 != (flag & BIT_IGNORE_ROUND_TRIP_TIME));
if (overwrite || ci->disable_keepalive < 0)
ci->disable_keepalive = (0 != (flag & BIT_DISABLE_KEEPALIVE));
return (ci->extra_opts = getExtraOptions(ci));
}
BOOL setExtraOptions(ConnInfo *ci, const char *optstr, const char *format)
{
UInt4 flag = 0;
if (!format)
{
if ('0' == *optstr)
{
switch (optstr[1])
{
case '\0':
format = dec_format;
break;
case 'x':
case 'X':
optstr += 2;
format = hex_format;
break;
default:
format = octal_format;
break;
}
}
else
format = dec_format;
}
if (sscanf(optstr, format, &flag) < 1)
return FALSE;
replaceExtraOptions(ci, flag, TRUE);
return TRUE;
}
UInt4 add_removeExtraOptions(ConnInfo *ci, UInt4 aflag, UInt4 dflag)
{
ci->extra_opts |= aflag;
ci->extra_opts &= (~dflag);
if (0 != (aflag & BIT_FORCEABBREVCONNSTR))
ci->force_abbrev_connstr = TRUE;
if (0 != (aflag & BIT_FAKE_MSS))
ci->fake_mss = TRUE;
if (0 != (aflag & BIT_BDE_ENVIRONMENT))
ci->bde_environment = TRUE;
if (0 != (aflag & BIT_CVT_NULL_DATE))
ci->cvt_null_date_string = TRUE;
if (0 != (aflag & BIT_ACCESSIBLE_ONLY))
ci->accessible_only = TRUE;
if (0 != (aflag & BIT_IGNORE_ROUND_TRIP_TIME))
ci->ignore_round_trip_time = TRUE;
if (0 != (aflag & BIT_DISABLE_KEEPALIVE))
ci->disable_keepalive = TRUE;
if (0 != (dflag & BIT_FORCEABBREVCONNSTR))
ci->force_abbrev_connstr = FALSE;
if (0 != (dflag & BIT_FAKE_MSS))
ci->fake_mss =FALSE;
if (0 != (dflag & BIT_CVT_NULL_DATE))
ci->cvt_null_date_string = FALSE;
if (0 != (dflag & BIT_ACCESSIBLE_ONLY))
ci->accessible_only = FALSE;
if (0 != (dflag & BIT_IGNORE_ROUND_TRIP_TIME))
ci->ignore_round_trip_time = FALSE;
if (0 != (dflag & BIT_DISABLE_KEEPALIVE))
ci->disable_keepalive = FALSE;
return (ci->extra_opts = getExtraOptions(ci));
}
static const char *
abbrev_sslmode(const char *sslmode, char *abbrevmode, size_t abbrevsize)
{
switch (sslmode[0])
{
case SSLLBYTE_DISABLE:
case SSLLBYTE_ALLOW:
case SSLLBYTE_PREFER:
case SSLLBYTE_REQUIRE:
abbrevmode[0] = sslmode[0];
abbrevmode[1] = '\0';
break;
case SSLLBYTE_VERIFY:
abbrevmode[0] = sslmode[0];
abbrevmode[2] = '\0';
switch (sslmode[1])
{
case 'f':
case 'c':
abbrevmode[1] = sslmode[1];
break;
default:
if (strnicmp(sslmode, "verify_", 7) == 0)
abbrevmode[1] = sslmode[7];
else
strncpy_null(abbrevmode, sslmode, abbrevsize);
}
break;
}
return abbrevmode;
}
static char *
makeKeepaliveConnectString(char *target, int buflen, const ConnInfo *ci, BOOL abbrev)
{
char *buf = target;
*buf = '\0';
if (ci->disable_keepalive)
return target;
if (ci->keepalive_idle >= 0)
{
if (abbrev)
snprintf(buf, buflen, ABBR_KEEPALIVETIME "=%u;", ci->keepalive_idle);
else
snprintf(buf, buflen, INI_KEEPALIVETIME "=%u;", ci->keepalive_idle);
}
if (ci->keepalive_interval >= 0)
{
if (abbrev)
snprintfcat(buf, buflen, ABBR_KEEPALIVEINTERVAL "=%u;", ci->keepalive_interval);
else
snprintfcat(buf, buflen, INI_KEEPALIVEINTERVAL "=%u;", ci->keepalive_interval);
}
return target;
}
#define OPENING_BRACKET '{'
#define CLOSING_BRACKET '}'
static const char *
makeBracketConnectString(BOOL in_str, char **target, pgNAME item, const char *optname)
{
const char *istr, *iptr;
char *buf, *optr;
int len;
if (!in_str)
return NULL_STRING;
istr = SAFE_NAME(item);
for (iptr = istr, len = 0; *iptr; iptr++)
{
if (CLOSING_BRACKET == *iptr)
len++;
len++;
}
len += 30;
if (buf = (char *) malloc(len), buf == NULL)
return NULL_STRING;
snprintf(buf, len, "%s=%c", optname, OPENING_BRACKET);
optr = strchr(buf, '\0');
for (iptr = istr; *iptr; iptr++)
{
if (CLOSING_BRACKET == *iptr)
*(optr++) = *iptr;
*(optr++) = *iptr;
}
*(optr++) = CLOSING_BRACKET;
*(optr++) = ';';
*optr = '\0';
*target = buf;
return buf;
}
#ifdef _HANDLE_ENLIST_IN_DTC_
char *
makeXaOptConnectString(char *target, int buflen, const ConnInfo *ci, BOOL abbrev)
{
char *buf = target;
*buf = '\0';
if (ci->xa_opt < 0)
return target;
if (abbrev)
{
if (DEFAULT_XAOPT != ci->xa_opt)
snprintf(buf, buflen, ABBR_XAOPT "=%u;", ci->xa_opt);
}
else
snprintf(buf, buflen, INI_XAOPT "=%u;", ci->xa_opt);
return target;
}
#endif /* _HANDLE_ENLIST_IN_DTC_ */
void
makeConnectString(char *connect_string, const ConnInfo *ci, UWORD len, int mode)
{
char got_dsn = (ci->dsn[0] != '\0');
char encoded_item[LARGE_REGISTRY_LEN];
char *connsetStr = NULL;
char *pqoptStr = NULL;
char keepaliveStr[64];
#ifdef _HANDLE_ENLIST_IN_DTC_
char xaOptStr[16];
#endif
ssize_t hlen, nlen, olen;
/*BOOL abbrev = (len <= 400);*/
BOOL abbrev = (len < 1024) || 0 < ci->force_abbrev_connstr;
UInt4 flag;
MYLOG(0, "%s row_versioning=%s\n", __FUNCTION__, ci->row_versioning);
MYLOG(DETAIL_LOG_LEVEL, "force_abbrev=%d abbrev=%d\n", ci->force_abbrev_connstr, abbrev);
if (mode == 0)
{
encode(ci->password, encoded_item, sizeof(encoded_item));
}
else
{
memset(encoded_item, 0, LARGE_REGISTRY_LEN);
if (ci->password.name != NULL)
{
memcpy(encoded_item, ci->password.name, strlen(ci->password.name));
encoded_item[strlen(ci->password.name)] = '\0';
}
}
/* fundamental info */
nlen = MAX_CONNECT_STRING;
olen = snprintf(connect_string, nlen, "%s=%s;DATABASE=%s;SERVER=%s;PORT=%s;UID=%s;PWD=%s",
got_dsn ? "DSN" : "DRIVER",
got_dsn ? ci->dsn : ci->drivername,
ci->database,
ci->server,
ci->port,
ci->username,
encoded_item);
if (olen < 0 || olen >= nlen)
{
connect_string[0] = '\0';
return;
}
/* extra info */
hlen = strlen(connect_string);
nlen = MAX_CONNECT_STRING - hlen;
MYLOG(DETAIL_LOG_LEVEL, "hlen=" FORMAT_SSIZE_T "\n", hlen);
if (!abbrev)
{
char protocol_and[16];
if (ci->rollback_on_error >= 0)
SPRINTF_FIXED(protocol_and, "7.4-%d", ci->rollback_on_error);
else
STRCPY_FIXED(protocol_and, "7.4");
olen = snprintf(&connect_string[hlen], nlen, ";"
INI_SSLMODE "=%s;"
INI_READONLY "=%s;"
INI_PROTOCOL "=%s;"
INI_FAKEOIDINDEX "=%s;"
INI_SHOWOIDCOLUMN "=%s;"
INI_ROWVERSIONING "=%s;"
INI_SHOWSYSTEMTABLES "=%s;"
"%s" /* INI_CONNSETTINGS */
INI_FETCH "=%d;"
INI_UNKNOWNSIZES "=%d;"
INI_MAXVARCHARSIZE "=%d;"
INI_MAXLONGVARCHARSIZE "=%d;"
INI_DEBUG "=%d;"
INI_COMMLOG "=%d;"
INI_USEDECLAREFETCH "=%d;"
INI_TEXTASLONGVARCHAR "=%d;"
INI_UNKNOWNSASLONGVARCHAR "=%d;"
INI_BOOLSASCHAR "=%d;"
INI_PARSE "=%d;"
INI_EXTRASYSTABLEPREFIXES "=%s;"
INI_LFCONVERSION "=%d;"
INI_UPDATABLECURSORS "=%d;"
INI_TRUEISMINUS1 "=%d;"
INI_INT8AS "=%d;"
INI_BYTEAASLONGVARBINARY "=%d;"
INI_USESERVERSIDEPREPARE "=%d;"
INI_LOWERCASEIDENTIFIER "=%d;"
"%s" /* INI_PQOPT */
"%s" /* INIKEEPALIVE TIME/INTERVAL */
ABBR_NUMERIC_AS "=%d;"
INI_OPTIONAL_ERRORS "=%d;"
#ifdef _HANDLE_ENLIST_IN_DTC_
INI_XAOPT "=%d" /* XAOPT */
#endif /* _HANDLE_ENLIST_IN_DTC_ */
,ci->sslmode
,ci->onlyread
,protocol_and
,ci->fake_oid_index
,ci->show_oid_column
,ci->row_versioning
,ci->show_system_tables
,makeBracketConnectString(ci->conn_settings_in_str, &connsetStr, ci->conn_settings, INI_CONNSETTINGS)
,ci->drivers.fetch_max
,ci->drivers.unknown_sizes
,ci->drivers.max_varchar_size
,ci->drivers.max_longvarchar_size
,ci->drivers.debug
,ci->drivers.commlog
,ci->drivers.use_declarefetch
,ci->drivers.text_as_longvarchar
,ci->drivers.unknowns_as_longvarchar
,ci->drivers.bools_as_char
,ci->drivers.parse
,ci->drivers.extra_systable_prefixes
,ci->lf_conversion
,ci->allow_keyset
,ci->true_is_minus1
,ci->int8_as
,ci->bytea_as_longvarbinary
,ci->use_server_side_prepare
,ci->lower_case_identifier
,makeBracketConnectString(ci->pqopt_in_str, &pqoptStr, ci->pqopt, INI_PQOPT)
,makeKeepaliveConnectString(keepaliveStr, sizeof(keepaliveStr), ci, FALSE)
,ci->numeric_as
,ci->optional_errors
#ifdef _HANDLE_ENLIST_IN_DTC_
,ci->xa_opt
#endif /* _HANDLE_ENLIST_IN_DTC_ */
);
}
/* Abbreviation is needed ? */
if (abbrev || olen >= nlen || olen < 0)
{
flag = 0;
if (ci->allow_keyset)
flag |= BIT_UPDATABLECURSORS;
if (ci->lf_conversion)
flag |= BIT_LFCONVERSION;
if (ci->drivers.unique_index)
flag |= BIT_UNIQUEINDEX;
switch (ci->drivers.unknown_sizes)
{
case UNKNOWNS_AS_DONTKNOW:
flag |= BIT_UNKNOWN_DONTKNOW;
break;
case UNKNOWNS_AS_MAX:
flag |= BIT_UNKNOWN_ASMAX;
break;
}
if (ci->drivers.commlog)
flag |= BIT_COMMLOG;
if (ci->drivers.debug)
flag |= BIT_DEBUG;
if (ci->drivers.parse)
flag |= BIT_PARSE;
if (ci->drivers.use_declarefetch)
flag |= BIT_USEDECLAREFETCH;
if (ci->onlyread[0] == '1')
flag |= BIT_READONLY;
if (ci->drivers.text_as_longvarchar)
flag |= BIT_TEXTASLONGVARCHAR;
if (ci->drivers.unknowns_as_longvarchar)
flag |= BIT_UNKNOWNSASLONGVARCHAR;
if (ci->drivers.bools_as_char)
flag |= BIT_BOOLSASCHAR;
if (ci->row_versioning[0] == '1')
flag |= BIT_ROWVERSIONING;
if (ci->show_system_tables[0] == '1')
flag |= BIT_SHOWSYSTEMTABLES;
if (ci->show_oid_column[0] == '1')
flag |= BIT_SHOWOIDCOLUMN;
if (ci->fake_oid_index[0] == '1')
flag |= BIT_FAKEOIDINDEX;
if (ci->true_is_minus1)
flag |= BIT_TRUEISMINUS1;
if (ci->bytea_as_longvarbinary)
flag |= BIT_BYTEAASLONGVARBINARY;
if (ci->use_server_side_prepare)
flag |= BIT_USESERVERSIDEPREPARE;
if (ci->lower_case_identifier)
flag |= BIT_LOWERCASEIDENTIFIER;
if (ci->optional_errors)
flag |= BIT_OPTIONALERRORS;
if (ci->sslmode[0])
{
char abbrevmode[sizeof(ci->sslmode)];
(void) snprintf(&connect_string[hlen], nlen, ";"
ABBR_SSLMODE "=%s", abbrev_sslmode(ci->sslmode, abbrevmode, sizeof(abbrevmode)));
}
hlen = strlen(connect_string);
nlen = MAX_CONNECT_STRING - hlen;
olen = snprintf(&connect_string[hlen], nlen, ";"
"%s" /* ABBR_CONNSETTINGS */
ABBR_FETCH "=%d;"
ABBR_MAXVARCHARSIZE "=%d;"
ABBR_MAXLONGVARCHARSIZE "=%d;"
INI_INT8AS "=%d;"
ABBR_EXTRASYSTABLEPREFIXES "=%s;"
"%s" /* ABBR_PQOPT */
"%s" /* ABBRKEEPALIVE TIME/INTERVAL */
ABBR_NUMERIC_AS "=%d;"
#ifdef _HANDLE_ENLIST_IN_DTC_
"%s"
#endif /* _HANDLE_ENLIST_IN_DTC_ */
INI_ABBREVIATE "=%02x%x",
makeBracketConnectString(ci->conn_settings_in_str, &connsetStr, ci->conn_settings, ABBR_CONNSETTINGS),
ci->drivers.fetch_max,
ci->drivers.max_varchar_size,
ci->drivers.max_longvarchar_size,
ci->int8_as,
ci->drivers.extra_systable_prefixes,
makeBracketConnectString(ci->pqopt_in_str, &pqoptStr, ci->pqopt, ABBR_PQOPT),
makeKeepaliveConnectString(keepaliveStr, sizeof(keepaliveStr), ci, TRUE),
ci->numeric_as,
#ifdef _HANDLE_ENLIST_IN_DTC_
makeXaOptConnectString(xaOptStr, sizeof(xaOptStr), ci, TRUE),
#endif /* _HANDLE_ENLIST_IN_DTC_ */
EFFECTIVE_BIT_COUNT, flag);
if (olen < nlen || ci->rollback_on_error >= 0)
{
hlen = strlen(connect_string);
nlen = MAX_CONNECT_STRING - hlen;
/*
* The PROTOCOL setting must be placed after CX flag
* so that this option can override the CX setting.
*/
if (ci->rollback_on_error >= 0)
olen = snprintf(&connect_string[hlen], nlen, ";"
ABBR_PROTOCOL "=7.4-%d",
ci->rollback_on_error);
else
olen = snprintf(&connect_string[hlen], nlen, ";"
ABBR_PROTOCOL "=7.4");
}
}
if (olen < nlen)
{
flag = getExtraOptions(ci);
if (0 != flag)
{
hlen = strlen(connect_string);
nlen = MAX_CONNECT_STRING - hlen;
olen = snprintf(&connect_string[hlen], nlen, ";"
INI_EXTRAOPTIONS "=%x;",
flag);
}
}
if (olen < 0 || olen >= nlen) /* failed */
connect_string[0] = '\0';
if (NULL != connsetStr)
free(connsetStr);
if (NULL != pqoptStr)
free(pqoptStr);
}
static void
unfoldCXAttribute(ConnInfo *ci, const char *value)
{
int count;
UInt4 flag;
if (strlen(value) < 2)
{
count = 3;
sscanf(value, "%x", &flag);
}
else
{
char cnt[8];
memcpy(cnt, value, 2);
cnt[2] = '\0';
sscanf(cnt, "%x", &count);
sscanf(value + 2, "%x", &flag);
}
ci->allow_keyset = (char)((flag & BIT_UPDATABLECURSORS) != 0);
ci->lf_conversion = (char)((flag & BIT_LFCONVERSION) != 0);
if (count < 4)
return;
ci->drivers.unique_index = (char)((flag & BIT_UNIQUEINDEX) != 0);
if ((flag & BIT_UNKNOWN_DONTKNOW) != 0)
ci->drivers.unknown_sizes = UNKNOWNS_AS_DONTKNOW;
else if ((flag & BIT_UNKNOWN_ASMAX) != 0)
ci->drivers.unknown_sizes = UNKNOWNS_AS_MAX;
else
ci->drivers.unknown_sizes = UNKNOWNS_AS_LONGEST;
ci->drivers.commlog = (char)((flag & BIT_COMMLOG) != 0);
ci->drivers.debug = (char)((flag & BIT_DEBUG) != 0);
ci->drivers.parse = (char)((flag & BIT_PARSE) != 0);
ci->drivers.use_declarefetch = (char)((flag & BIT_USEDECLAREFETCH) != 0);
ITOA_FIXED(ci->onlyread, (char)((flag & BIT_READONLY) != 0));
ci->drivers.text_as_longvarchar = (char)((flag & BIT_TEXTASLONGVARCHAR) !=0);
ci->drivers.unknowns_as_longvarchar = (char)((flag & BIT_UNKNOWNSASLONGVARCHAR) !=0);
ci->drivers.bools_as_char = (char)((flag & BIT_BOOLSASCHAR) != 0);
ITOA_FIXED(ci->row_versioning, (char)((flag & BIT_ROWVERSIONING) != 0));
ITOA_FIXED(ci->show_system_tables, (char)((flag & BIT_SHOWSYSTEMTABLES) != 0));
ITOA_FIXED(ci->show_oid_column, (char)((flag & BIT_SHOWOIDCOLUMN) != 0));
ITOA_FIXED(ci->fake_oid_index, (char)((flag & BIT_FAKEOIDINDEX) != 0));
ci->true_is_minus1 = (char)((flag & BIT_TRUEISMINUS1) != 0);
ci->bytea_as_longvarbinary = (char)((flag & BIT_BYTEAASLONGVARBINARY) != 0);
ci->use_server_side_prepare = (char)((flag & BIT_USESERVERSIDEPREPARE) != 0);
ci->lower_case_identifier = (char)((flag & BIT_LOWERCASEIDENTIFIER) != 0);
ci->optional_errors = (char)((flag & BIT_OPTIONALERRORS) != 0);
}
BOOL
get_DSN_or_Driver(ConnInfo *ci, const char *attribute, const char *value)
{
BOOL found = TRUE;
if (stricmp(attribute, "DSN") == 0)
STRCPY_FIXED(ci->dsn, value);
else if (stricmp(attribute, "driver") == 0)
STRCPY_FIXED(ci->drivername, value);
else
found = FALSE;
return found;
}
BOOL
copyConnAttributes(ConnInfo *ci, const char *attribute, const char *value)
{
BOOL found = TRUE, printed = FALSE;
if (stricmp(attribute, "DSN") == 0)
STRCPY_FIXED(ci->dsn, value);
else if (stricmp(attribute, "driver") == 0)
STRCPY_FIXED(ci->drivername, value);
else if (stricmp(attribute, INI_KDESC) == 0)
STRCPY_FIXED(ci->desc, value);
else if (stricmp(attribute, INI_DATABASE) == 0 || stricmp(attribute, ABBR_DATABASE) == 0)
STRCPY_FIXED(ci->database, value);
else if (stricmp(attribute, INI_SERVER) == 0 || stricmp(attribute, SPEC_SERVER) == 0)
STRCPY_FIXED(ci->server, value);
else if (stricmp(attribute, INI_USERNAME) == 0 || stricmp(attribute, INI_UID) == 0)
STRCPY_FIXED(ci->username, value);
else if (stricmp(attribute, INI_PASSWORD) == 0 || stricmp(attribute, "pwd") == 0)
{
ci->password = decode_or_remove_braces(value);
#ifndef FORCE_PASSWORDE_DISPLAY
MYLOG(0, "key='%s' value='xxxxxxxx'\n", attribute);
printed = TRUE;
#endif
}
else if (stricmp(attribute, INI_PORT) == 0)
STRCPY_FIXED(ci->port, value);
else if (stricmp(attribute, INI_READONLY) == 0 || stricmp(attribute, ABBR_READONLY) == 0)
STRCPY_FIXED(ci->onlyread, value);
else if (stricmp(attribute, INI_PROTOCOL) == 0 || stricmp(attribute, ABBR_PROTOCOL) == 0)
{
char *ptr;
/*
* The first part of the Protocol used to be "6.2", "6.3" or
* "7.4" to denote which protocol version to use. Nowadays we
* only support the 7.4 protocol, also known as the protocol
* version 3. So just ignore the first part of the string,
* parsing only the rollback_on_error value.
*/
ptr = strchr(value, '-');
if (ptr)
{
if ('-' != *value)
{
*ptr = '\0';
/* ignore first part */
}
ci->rollback_on_error = atoi(ptr + 1);
MYLOG(0, "key='%s' value='%s' rollback_on_error=%d\n",
attribute, value, ci->rollback_on_error);
printed = TRUE;
}
}
else if (stricmp(attribute, INI_SHOWOIDCOLUMN) == 0 || stricmp(attribute, ABBR_SHOWOIDCOLUMN) == 0)
STRCPY_FIXED(ci->show_oid_column, value);
else if (stricmp(attribute, INI_FAKEOIDINDEX) == 0 || stricmp(attribute, ABBR_FAKEOIDINDEX) == 0)
STRCPY_FIXED(ci->fake_oid_index, value);
else if (stricmp(attribute, INI_ROWVERSIONING) == 0 || stricmp(attribute, ABBR_ROWVERSIONING) == 0)
STRCPY_FIXED(ci->row_versioning, value);
else if (stricmp(attribute, INI_SHOWSYSTEMTABLES) == 0 || stricmp(attribute, ABBR_SHOWSYSTEMTABLES) == 0)
STRCPY_FIXED(ci->show_system_tables, value);
else if (stricmp(attribute, INI_CONNSETTINGS) == 0 || stricmp(attribute, ABBR_CONNSETTINGS) == 0)
{
/* We can use the conn_settings directly when they are enclosed with braces */
ci->conn_settings_in_str = TRUE;
ci->conn_settings = decode_or_remove_braces(value);
}
else if (stricmp(attribute, INI_PQOPT) == 0 || stricmp(attribute, ABBR_PQOPT) == 0)
{
ci->pqopt_in_str = TRUE;
ci->pqopt = decode_or_remove_braces(value);
}
else if (stricmp(attribute, INI_UPDATABLECURSORS) == 0 || stricmp(attribute, ABBR_UPDATABLECURSORS) == 0)
ci->allow_keyset = atoi(value);
else if (stricmp(attribute, INI_LFCONVERSION) == 0 || stricmp(attribute, ABBR_LFCONVERSION) == 0)
ci->lf_conversion = atoi(value);
else if (stricmp(attribute, INI_TRUEISMINUS1) == 0 || stricmp(attribute, ABBR_TRUEISMINUS1) == 0)
ci->true_is_minus1 = atoi(value);
else if (stricmp(attribute, INI_INT8AS) == 0)
ci->int8_as = atoi(value);
else if (stricmp(attribute, INI_NUMERIC_AS) == 0 || stricmp(attribute, ABBR_NUMERIC_AS) == 0)
ci->numeric_as = atoi(value);
else if (stricmp(attribute, INI_BYTEAASLONGVARBINARY) == 0 || stricmp(attribute, ABBR_BYTEAASLONGVARBINARY) == 0)
ci->bytea_as_longvarbinary = atoi(value);
else if (stricmp(attribute, INI_USESERVERSIDEPREPARE) == 0 || stricmp(attribute, ABBR_USESERVERSIDEPREPARE) == 0)
ci->use_server_side_prepare = atoi(value);
else if (stricmp(attribute, INI_LOWERCASEIDENTIFIER) == 0 || stricmp(attribute, ABBR_LOWERCASEIDENTIFIER) == 0)
ci->lower_case_identifier = atoi(value);
else if (stricmp(attribute, INI_KEEPALIVETIME) == 0 || stricmp(attribute, ABBR_KEEPALIVETIME) == 0)
ci->keepalive_idle = atoi(value);
else if (stricmp(attribute, INI_KEEPALIVEINTERVAL) == 0 || stricmp(attribute, ABBR_KEEPALIVEINTERVAL) == 0)
ci->keepalive_interval = atoi(value);
else if (stricmp(attribute, INI_BATCHSIZE) == 0 || stricmp(attribute, ABBR_BATCHSIZE) == 0)
ci->batch_size = atoi(value);
else if (stricmp(attribute, INI_OPTIONAL_ERRORS) == 0 || stricmp(attribute, ABBR_OPTIONAL_ERRORS) == 0)
ci->optional_errors = atoi(value);
else if (stricmp(attribute, INI_IGNORETIMEOUT) == 0 || stricmp(attribute, ABBR_IGNORETIMEOUT) == 0)
ci->ignore_timeout = atoi(value);
else if (stricmp(attribute, INI_SSLMODE) == 0 || stricmp(attribute, ABBR_SSLMODE) == 0)
{
switch (value[0])
{
case SSLLBYTE_ALLOW:
STRCPY_FIXED(ci->sslmode, SSLMODE_ALLOW);
break;
case SSLLBYTE_PREFER:
STRCPY_FIXED(ci->sslmode, SSLMODE_PREFER);
break;
case SSLLBYTE_REQUIRE:
STRCPY_FIXED(ci->sslmode, SSLMODE_REQUIRE);
break;
case SSLLBYTE_VERIFY:
switch (value[1])
{
case 'f':
STRCPY_FIXED(ci->sslmode, SSLMODE_VERIFY_FULL);
break;
case 'c':
STRCPY_FIXED(ci->sslmode, SSLMODE_VERIFY_CA);
break;
default:
STRCPY_FIXED(ci->sslmode, value);
}
break;
case SSLLBYTE_DISABLE:
default:
STRCPY_FIXED(ci->sslmode, SSLMODE_DISABLE);
break;
}
MYLOG(0, "key='%s' value='%s' set to '%s'\n",
attribute, value, ci->sslmode);
printed = TRUE;
}
else if (stricmp(attribute, INI_ABBREVIATE) == 0)
unfoldCXAttribute(ci, value);
#ifdef _HANDLE_ENLIST_IN_DTC_
else if (stricmp(attribute, INI_XAOPT) == 0)
ci->xa_opt = atoi(value);
#endif /* _HANDLE_ENLIST_IN_DTC_ */
else if (stricmp(attribute, INI_EXTRAOPTIONS) == 0)
{
UInt4 val1 = 0, val2 = 0;
if ('+' == value[0])
{
sscanf(value + 1, "%x-%x", &val1, &val2);
add_removeExtraOptions(ci, val1, val2);
}
else if ('-' == value[0])
{
sscanf(value + 1, "%x", &val2);
add_removeExtraOptions(ci, 0, val2);
}
else
{
setExtraOptions(ci, value, hex_format);
}
MYLOG(0, "key='%s' value='%s'(force_abbrev=%d bde=%d cvt_null_date=%x)\n",
attribute, value, ci->force_abbrev_connstr, ci->bde_environment, ci->cvt_null_date_string);
printed = TRUE;
}
else if (stricmp(attribute, INI_FETCH) == 0 || stricmp(attribute, ABBR_FETCH) == 0)
ci->drivers.fetch_max = atoi(value);
else if (stricmp(attribute, INI_DEBUG) == 0 || stricmp(attribute, ABBR_DEBUG) == 0)
ci->drivers.debug = atoi(value);
else if (stricmp(attribute, INI_COMMLOG) == 0 || stricmp(attribute, ABBR_COMMLOG) == 0)
ci->drivers.commlog = atoi(value);
/*
* else if (stricmp(attribute, INI_UNIQUEINDEX) == 0 ||
* stricmp(attribute, "UIX") == 0) ci->drivers.unique_index =
* atoi(value);
*/
else if (stricmp(attribute, INI_UNKNOWNSIZES) == 0 || stricmp(attribute, ABBR_UNKNOWNSIZES) == 0)
ci->drivers.unknown_sizes = atoi(value);
else if (stricmp(attribute, INI_LIE) == 0)
ci->drivers.lie = atoi(value);
else if (stricmp(attribute, INI_PARSE) == 0 || stricmp(attribute, ABBR_PARSE) == 0)
ci->drivers.parse = atoi(value);
else if (stricmp(attribute, INI_USEDECLAREFETCH) == 0 || stricmp(attribute, ABBR_USEDECLAREFETCH) == 0)
ci->drivers.use_declarefetch = atoi(value);
else if (stricmp(attribute, INI_MAXVARCHARSIZE) == 0 || stricmp(attribute, ABBR_MAXVARCHARSIZE) == 0)
ci->drivers.max_varchar_size = atoi(value);
else if (stricmp(attribute, INI_MAXLONGVARCHARSIZE) == 0 || stricmp(attribute, ABBR_MAXLONGVARCHARSIZE) == 0)
ci->drivers.max_longvarchar_size = atoi(value);
else if (stricmp(attribute, INI_TEXTASLONGVARCHAR) == 0 || stricmp(attribute, ABBR_TEXTASLONGVARCHAR) == 0)
ci->drivers.text_as_longvarchar = atoi(value);
else if (stricmp(attribute, INI_UNKNOWNSASLONGVARCHAR) == 0 || stricmp(attribute, ABBR_UNKNOWNSASLONGVARCHAR) == 0)
ci->drivers.unknowns_as_longvarchar = atoi(value);
else if (stricmp(attribute, INI_BOOLSASCHAR) == 0 || stricmp(attribute, ABBR_BOOLSASCHAR) == 0)
ci->drivers.bools_as_char = atoi(value);
else if (stricmp(attribute, INI_EXTRASYSTABLEPREFIXES) == 0 || stricmp(attribute, ABBR_EXTRASYSTABLEPREFIXES) == 0)
STRCPY_FIXED(ci->drivers.extra_systable_prefixes, value);
else
found = FALSE;
if (!printed)
MYLOG(0, "key='%s' value='%s'%s\n", attribute,
value, found ? NULL_STRING : " not found");
return found;
}
static void
getCiDefaults(ConnInfo *ci)
{
MYLOG(0, "entering\n");
ci->drivers.debug = DEFAULT_DEBUG;
ci->drivers.commlog = DEFAULT_COMMLOG;
ITOA_FIXED(ci->onlyread, DEFAULT_READONLY);
ITOA_FIXED(ci->fake_oid_index, DEFAULT_FAKEOIDINDEX);
ITOA_FIXED(ci->show_oid_column, DEFAULT_SHOWOIDCOLUMN);
ITOA_FIXED(ci->show_system_tables, DEFAULT_SHOWSYSTEMTABLES);
ITOA_FIXED(ci->row_versioning, DEFAULT_ROWVERSIONING);
ci->allow_keyset = DEFAULT_UPDATABLECURSORS;
ci->lf_conversion = DEFAULT_LFCONVERSION;
ci->true_is_minus1 = DEFAULT_TRUEISMINUS1;
ci->int8_as = DEFAULT_INT8AS;
ci->numeric_as = DEFAULT_NUMERIC_AS;
ci->optional_errors = DEFAULT_OPTIONAL_ERRORS;
ci->bytea_as_longvarbinary = DEFAULT_BYTEAASLONGVARBINARY;
ci->use_server_side_prepare = DEFAULT_USESERVERSIDEPREPARE;
ci->lower_case_identifier = DEFAULT_LOWERCASEIDENTIFIER;
STRCPY_FIXED(ci->sslmode, DEFAULT_SSLMODE);
ci->force_abbrev_connstr = 0;
ci->fake_mss = 0;
ci->bde_environment = 0;
ci->cvt_null_date_string = 0;
ci->accessible_only = 0;
ci->ignore_round_trip_time = 0;
ci->disable_keepalive = 0;
{
const char *p;
ci->wcs_debug = 0;
if (NULL != (p = getenv("PSQLODBC_WCS_DEBUG")))
if (strcmp(p, "1") == 0)
ci->wcs_debug = 1;
}
#ifdef _HANDLE_ENLIST_IN_DTC_
ci->xa_opt = DEFAULT_XAOPT;
#endif /* _HANDLE_ENLIST_IN_DTC_ */
}
int
getDriverNameFromDSN(const char *dsn, char *driver_name, int namelen)
{
#ifdef WIN32
return SQLGetPrivateProfileString(ODBC_DATASOURCES, dsn, NULL_STRING, driver_name, namelen, ODBC_INI);
#else /* WIN32 */
int cnt;
cnt = SQLGetPrivateProfileString(dsn, "Driver", NULL_STRING, driver_name, namelen, ODBC_INI);
if (!driver_name[0])
return cnt;
if (strchr(driver_name, '/') || /* path to the driver */
strchr(driver_name, '.'))
{
driver_name[0] = '\0';
return 0;
}
return cnt;
#endif /* WIN32 */
}
static void Global_defset(GLOBAL_VALUES *comval)
{
comval->fetch_max = FETCH_MAX;
comval->unique_index = DEFAULT_UNIQUEINDEX;
comval->unknown_sizes = DEFAULT_UNKNOWNSIZES;
comval->lie = DEFAULT_LIE;
comval->parse = DEFAULT_PARSE;
comval->use_declarefetch = DEFAULT_USEDECLAREFETCH;
comval->max_varchar_size = MAX_VARCHAR_SIZE;
comval->max_longvarchar_size = TEXT_FIELD_SIZE;
comval->text_as_longvarchar = DEFAULT_TEXTASLONGVARCHAR;
comval->unknowns_as_longvarchar = DEFAULT_UNKNOWNSASLONGVARCHAR;
comval->bools_as_char = DEFAULT_BOOLSASCHAR;
STRCPY_FIXED(comval->extra_systable_prefixes, DEFAULT_EXTRASYSTABLEPREFIXES);
STRCPY_FIXED(comval->protocol, DEFAULT_PROTOCOL);
}
static void
get_Ci_Drivers(const char *section, const char *filename, GLOBAL_VALUES *comval);
void getDriversDefaults(const char *drivername, GLOBAL_VALUES *comval)
{
MYLOG(0, "%p of the driver %s\n", comval, NULL_IF_NULL(drivername));
get_Ci_Drivers(drivername, ODBCINST_INI, comval);
if (NULL != drivername)
STR_TO_NAME(comval->drivername, drivername);
}
void
getCiAllDefaults(ConnInfo *ci)
{
Global_defset(&(ci->drivers));
getCiDefaults(ci);
}
void
getDSNinfo(ConnInfo *ci, const char *configDrvrname)
{
char *DSN = ci->dsn;
char temp[LARGE_REGISTRY_LEN];
const char *drivername;
/*
* If a driver keyword was present, then dont use a DSN and return.
* If DSN is null and no driver, then use the default datasource.
*/
MYLOG(0, "entering DSN=%s driver=%s&%s\n", DSN,
ci->drivername, NULL_IF_NULL(configDrvrname));
getCiDefaults(ci);
drivername = ci->drivername;
if (DSN[0] == '\0')
{
if (drivername[0] == '\0') /* adding new DSN via configDSN */
{
if (configDrvrname)
drivername = configDrvrname;
strncpy_null(DSN, INI_DSN, sizeof(ci->dsn));
}
/* else dns-less connections */
}
/* brute-force chop off trailing blanks... */
while (*(DSN + strlen(DSN) - 1) == ' ')
*(DSN + strlen(DSN) - 1) = '\0';
if (!drivername[0] && DSN[0])
getDriverNameFromDSN(DSN, (char *) drivername, sizeof(ci->drivername));
MYLOG(0, "drivername=%s\n", drivername);
if (!drivername[0])
drivername = INVALID_DRIVER;
getDriversDefaults(drivername, &(ci->drivers));
if (DSN[0] == '\0')
return;
/* Proceed with getting info for the given DSN. */
SQLGetPrivateProfileString(DSN, INI_KDESC, NULL_STRING, ci->desc, sizeof(ci->desc), ODBC_INI);
if (SQLGetPrivateProfileString(DSN, INI_SERVER, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
STRCPY_FIXED(ci->server, temp);
if (SQLGetPrivateProfileString(DSN, INI_DATABASE, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
STRCPY_FIXED(ci->database, temp);
if (SQLGetPrivateProfileString(DSN, INI_USERNAME, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
STRCPY_FIXED(ci->username, temp);
if (SQLGetPrivateProfileString(DSN, INI_PASSWORD, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
ci->password = decode(temp);
if (SQLGetPrivateProfileString(DSN, INI_PORT, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
STRCPY_FIXED(ci->port, temp);
/* It's appropriate to handle debug and commlog here */
if (SQLGetPrivateProfileString(DSN, INI_DEBUG, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
ci->drivers.debug = atoi(temp);
if (SQLGetPrivateProfileString(DSN, INI_COMMLOG, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
ci->drivers.commlog = atoi(temp);
if (SQLGetPrivateProfileString(DSN, INI_READONLY, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
STRCPY_FIXED(ci->onlyread, temp);
if (SQLGetPrivateProfileString(DSN, INI_SHOWOIDCOLUMN, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
STRCPY_FIXED(ci->show_oid_column, temp);
if (SQLGetPrivateProfileString(DSN, INI_FAKEOIDINDEX, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
STRCPY_FIXED(ci->fake_oid_index, temp);
if (SQLGetPrivateProfileString(DSN, INI_ROWVERSIONING, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
STRCPY_FIXED(ci->row_versioning, temp);
if (SQLGetPrivateProfileString(DSN, INI_SHOWSYSTEMTABLES, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
STRCPY_FIXED(ci->show_system_tables, temp);
SQLGetPrivateProfileString(DSN, INI_PROTOCOL, ENTRY_TEST, temp, sizeof(temp), ODBC_INI);
if (strcmp(temp, ENTRY_TEST)) /* entry exists */
{
char *ptr;
if (ptr = strchr(temp, '-'), NULL != ptr)
{
*ptr = '\0';
ci->rollback_on_error = atoi(ptr + 1);
MYLOG(0, "rollback_on_error=%d\n", ci->rollback_on_error);
}
}
SQLGetPrivateProfileString(DSN, INI_CONNSETTINGS, ENTRY_TEST, temp, sizeof(temp), ODBC_INI);
if (strcmp(temp, ENTRY_TEST)) /* entry exists */
{
const UCHAR *ptr;
BOOL percent_encoded = TRUE, pspace;
int nspcnt;
/*
* percent-encoding was used before.
* Note that there's no space in percent-encoding.
*/
for (ptr = (UCHAR *) temp, pspace = TRUE, nspcnt = 0; *ptr; ptr++)
{
if (isspace(*ptr))
pspace = TRUE;
else
{
if (pspace)
{
if (nspcnt++ > 1)
{
percent_encoded = FALSE;
break;
}
}
pspace = FALSE;
}
}
if (percent_encoded)
ci->conn_settings = decode(temp);
else
STRX_TO_NAME(ci->conn_settings, temp);
}
SQLGetPrivateProfileString(DSN, INI_PQOPT, ENTRY_TEST, temp, sizeof(temp), ODBC_INI);
if (strcmp(temp, ENTRY_TEST)) /* entry exists */
STRX_TO_NAME(ci->pqopt, temp);
if (SQLGetPrivateProfileString(DSN, INI_TRANSLATIONDLL, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
STRCPY_FIXED(ci->translation_dll, temp);
if (SQLGetPrivateProfileString(DSN, INI_TRANSLATIONOPTION, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
STRCPY_FIXED(ci->translation_option, temp);
if (SQLGetPrivateProfileString(DSN, INI_UPDATABLECURSORS, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
ci->allow_keyset = atoi(temp);
if (SQLGetPrivateProfileString(DSN, INI_LFCONVERSION, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
ci->lf_conversion = atoi(temp);
if (SQLGetPrivateProfileString(DSN, INI_TRUEISMINUS1, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
ci->true_is_minus1 = atoi(temp);
if (SQLGetPrivateProfileString(DSN, INI_INT8AS, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
ci->int8_as = atoi(temp);
if (SQLGetPrivateProfileString(DSN, ABBR_NUMERIC_AS, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
ci->numeric_as = atoi(temp);
if (SQLGetPrivateProfileString(DSN, INI_OPTIONAL_ERRORS, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
ci->optional_errors = atoi(temp);
if (SQLGetPrivateProfileString(DSN, INI_BYTEAASLONGVARBINARY, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
ci->bytea_as_longvarbinary = atoi(temp);
if (SQLGetPrivateProfileString(DSN, INI_USESERVERSIDEPREPARE, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
ci->use_server_side_prepare = atoi(temp);
if (SQLGetPrivateProfileString(DSN, INI_LOWERCASEIDENTIFIER, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
ci->lower_case_identifier = atoi(temp);
if (SQLGetPrivateProfileString(DSN, INI_KEEPALIVETIME, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
if (0 == (ci->keepalive_idle = atoi(temp)))
ci->keepalive_idle = -1;
if (SQLGetPrivateProfileString(DSN, INI_KEEPALIVEINTERVAL, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
if (0 == (ci->keepalive_interval = atoi(temp)))
ci->keepalive_interval = -1;
if (SQLGetPrivateProfileString(DSN, INI_BATCHSIZE, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
if (0 == (ci->batch_size = atoi(temp)))
ci->batch_size = DEFAULT_BATCH_SIZE;
if (SQLGetPrivateProfileString(DSN, INI_IGNORETIMEOUT, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
ci->ignore_timeout = atoi(temp);
if (SQLGetPrivateProfileString(DSN, INI_SSLMODE, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
STRCPY_FIXED(ci->sslmode, temp);
#ifdef _HANDLE_ENLIST_IN_DTC_
if (SQLGetPrivateProfileString(DSN, INI_XAOPT, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
ci->xa_opt = atoi(temp);
#endif /* _HANDLE_ENLIST_IN_DTC_ */
/* Force abbrev connstr or bde */
if (SQLGetPrivateProfileString(DSN, INI_EXTRAOPTIONS, NULL_STRING,
temp, sizeof(temp), ODBC_INI) > 0)
{
UInt4 val = 0;
sscanf(temp, "%x", &val);
replaceExtraOptions(ci, val, TRUE);
MYLOG(0, "force_abbrev=%d bde=%d cvt_null_date=%d\n", ci->force_abbrev_connstr, ci->bde_environment, ci->cvt_null_date_string);
}
/* Allow override of odbcinst.ini parameters here */
get_Ci_Drivers(DSN, ODBC_INI, &(ci->drivers));
STR_TO_NAME(ci->drivers.drivername, drivername);
MYLOG(DETAIL_LOG_LEVEL, "DSN info: DSN='%s',server='%s',port='%s',dbase='%s',user='%s',passwd='%s'\n",
DSN,
ci->server,
ci->port,
ci->database,
ci->username,
NAME_IS_VALID(ci->password) ? "xxxxx" : "");
MYLOG(DETAIL_LOG_LEVEL, " onlyread='%s',showoid='%s',fakeoidindex='%s',showsystable='%s'\n",
ci->onlyread,
ci->show_oid_column,
ci->fake_oid_index,
ci->show_system_tables);
{
#ifdef NOT_USED
char *enc = (char *) check_client_encoding(ci->conn_settings);
MYLOG(DETAIL_LOG_LEVEL, " conn_settings='%s', conn_encoding='%s'\n", ci->conn_settings,
NULL != enc ? enc : "(null)");
if (NULL != enc)
free(enc);
#endif /* NOT_USED */
MYLOG(DETAIL_LOG_LEVEL, " translation_dll='%s',translation_option='%s'\n",
ci->translation_dll,
ci->translation_option);
}
}
/*
* This function writes any global parameters (that can be manipulated)
* to the ODBCINST.INI portion of the registry
*/
int
write_Ci_Drivers(const char *fileName, const char *sectionName,
const GLOBAL_VALUES *comval)
{
char tmp[128];
int errc = 0;
if (stricmp(ODBCINST_INI, fileName) == 0)
{
if (NULL == sectionName)
sectionName = DBMS_NAME;
}
if (stricmp(ODBCINST_INI, fileName) == 0)
return errc;
ITOA_FIXED(tmp, comval->commlog);
if (!SQLWritePrivateProfileString(sectionName, INI_COMMLOG, tmp, fileName))
errc--;
ITOA_FIXED(tmp, comval->debug);
if (!SQLWritePrivateProfileString(sectionName, INI_DEBUG, tmp, fileName))
errc--;
ITOA_FIXED(tmp, comval->fetch_max);
if (!SQLWritePrivateProfileString(sectionName, INI_FETCH, tmp, fileName))
errc--;
ITOA_FIXED(tmp, comval->unique_index);
if (!SQLWritePrivateProfileString(sectionName, INI_UNIQUEINDEX, tmp, fileName))
errc--;
ITOA_FIXED(tmp, comval->use_declarefetch);
if (!SQLWritePrivateProfileString(sectionName, INI_USEDECLAREFETCH, tmp, fileName))
errc--;
ITOA_FIXED(tmp, comval->unknown_sizes);
if (!SQLWritePrivateProfileString(sectionName, INI_UNKNOWNSIZES, tmp, fileName))
errc--;
ITOA_FIXED(tmp, comval->text_as_longvarchar);
if (!SQLWritePrivateProfileString(sectionName, INI_TEXTASLONGVARCHAR, tmp, fileName))
errc--;
ITOA_FIXED(tmp, comval->unknowns_as_longvarchar);
if (!SQLWritePrivateProfileString(sectionName, INI_UNKNOWNSASLONGVARCHAR, tmp, fileName))
errc--;
ITOA_FIXED(tmp, comval->bools_as_char);
if (!SQLWritePrivateProfileString(sectionName, INI_BOOLSASCHAR, tmp, fileName))
errc--;
ITOA_FIXED(tmp, comval->parse);
if (!SQLWritePrivateProfileString(sectionName, INI_PARSE, tmp, fileName))
errc--;
ITOA_FIXED(tmp, comval->max_varchar_size);
if (!SQLWritePrivateProfileString(sectionName, INI_MAXVARCHARSIZE, tmp, fileName))
errc--;
ITOA_FIXED(tmp, comval->max_longvarchar_size);
if (!SQLWritePrivateProfileString(sectionName, INI_MAXLONGVARCHARSIZE, tmp, fileName))
errc--;
if (!SQLWritePrivateProfileString(sectionName, INI_EXTRASYSTABLEPREFIXES, comval->extra_systable_prefixes, fileName))
errc--;
/*
* Never update the conn_setting from this module
* SQLWritePrivateProfileString(sectionName, INI_CONNSETTINGS,
* comval->conn_settings, fileName);
*/
return errc;
}
int
writeDriversDefaults(const char *drivername, const GLOBAL_VALUES *comval)
{
return write_Ci_Drivers(ODBCINST_INI, drivername, comval);
}
/* This is for datasource based options only */
void
writeDSNinfo(const ConnInfo *ci)
{
const char *DSN = ci->dsn;
char encoded_item[MEDIUM_REGISTRY_LEN],
temp[SMALL_REGISTRY_LEN];
SQLWritePrivateProfileString(DSN,
INI_KDESC,
ci->desc,
ODBC_INI);
SQLWritePrivateProfileString(DSN,
INI_DATABASE,
ci->database,
ODBC_INI);
SQLWritePrivateProfileString(DSN,
INI_SERVER,
ci->server,
ODBC_INI);
SQLWritePrivateProfileString(DSN,
INI_PORT,
ci->port,
ODBC_INI);
SQLWritePrivateProfileString(DSN,
INI_USERNAME,
ci->username,
ODBC_INI);
SQLWritePrivateProfileString(DSN, INI_UID, ci->username, ODBC_INI);
encode(ci->password, encoded_item, sizeof(encoded_item));
SQLWritePrivateProfileString(DSN,
INI_PASSWORD,
encoded_item,
ODBC_INI);
SQLWritePrivateProfileString(DSN,
INI_READONLY,
ci->onlyread,
ODBC_INI);
SQLWritePrivateProfileString(DSN,
INI_SHOWOIDCOLUMN,
ci->show_oid_column,
ODBC_INI);
SQLWritePrivateProfileString(DSN,
INI_FAKEOIDINDEX,
ci->fake_oid_index,
ODBC_INI);
SQLWritePrivateProfileString(DSN,
INI_ROWVERSIONING,
ci->row_versioning,
ODBC_INI);
SQLWritePrivateProfileString(DSN,
INI_SHOWSYSTEMTABLES,
ci->show_system_tables,
ODBC_INI);
if (ci->rollback_on_error >= 0)
SPRINTF_FIXED(temp, "7.4-%d", ci->rollback_on_error);
else
STRCPY_FIXED(temp, NULL_STRING);
SQLWritePrivateProfileString(DSN,
INI_PROTOCOL,
temp,
ODBC_INI);
SQLWritePrivateProfileString(DSN,
INI_CONNSETTINGS,
SAFE_NAME(ci->conn_settings),
ODBC_INI);
SQLWritePrivateProfileString(DSN,
INI_PQOPT,
SAFE_NAME(ci->pqopt),
ODBC_INI);
ITOA_FIXED(temp, ci->allow_keyset);
SQLWritePrivateProfileString(DSN,
INI_UPDATABLECURSORS,
temp,
ODBC_INI);
ITOA_FIXED(temp, ci->lf_conversion);
SQLWritePrivateProfileString(DSN,
INI_LFCONVERSION,
temp,
ODBC_INI);
ITOA_FIXED(temp, ci->true_is_minus1);
SQLWritePrivateProfileString(DSN,
INI_TRUEISMINUS1,
temp,
ODBC_INI);
ITOA_FIXED(temp, ci->int8_as);
SQLWritePrivateProfileString(DSN,
INI_INT8AS,
temp,
ODBC_INI);
ITOA_FIXED(temp, ci->numeric_as);
SQLWritePrivateProfileString(DSN,
ABBR_NUMERIC_AS,
temp,
ODBC_INI);
ITOA_FIXED(temp, ci->optional_errors);
SQLWritePrivateProfileString(DSN,
INI_OPTIONAL_ERRORS,
temp,
ODBC_INI);
SPRINTF_FIXED(temp, "%x", getExtraOptions(ci));
SQLWritePrivateProfileString(DSN,
INI_EXTRAOPTIONS,
temp,
ODBC_INI);
ITOA_FIXED(temp, ci->bytea_as_longvarbinary);
SQLWritePrivateProfileString(DSN,
INI_BYTEAASLONGVARBINARY,
temp,
ODBC_INI);
ITOA_FIXED(temp, ci->use_server_side_prepare);
SQLWritePrivateProfileString(DSN,
INI_USESERVERSIDEPREPARE,
temp,
ODBC_INI);
ITOA_FIXED(temp, ci->lower_case_identifier);
SQLWritePrivateProfileString(DSN,
INI_LOWERCASEIDENTIFIER,
temp,
ODBC_INI);
SQLWritePrivateProfileString(DSN,
INI_SSLMODE,
ci->sslmode,
ODBC_INI);
ITOA_FIXED(temp, ci->keepalive_idle);
SQLWritePrivateProfileString(DSN,
INI_KEEPALIVETIME,
temp,
ODBC_INI);
ITOA_FIXED(temp, ci->keepalive_interval);
SQLWritePrivateProfileString(DSN,
INI_KEEPALIVEINTERVAL,
temp,
ODBC_INI);
ITOA_FIXED(temp, ci->batch_size);
SQLWritePrivateProfileString(DSN,
INI_BATCHSIZE,
temp,
ODBC_INI);
ITOA_FIXED(temp, ci->ignore_timeout);
SQLWritePrivateProfileString(DSN,
INI_IGNORETIMEOUT,
temp,
ODBC_INI);
#ifdef _HANDLE_ENLIST_IN_DTC_
ITOA_FIXED(temp, ci->xa_opt);
SQLWritePrivateProfileString(DSN, INI_XAOPT, temp, ODBC_INI);
#endif /* _HANDLE_ENLIST_IN_DTC_ */
}
/*
* This function reads the ODBCINST.INI portion of
* the registry and gets any driver defaults.
*/
static void
get_Ci_Drivers(const char *section, const char *filename, GLOBAL_VALUES *comval)
{
char temp[256];
BOOL inst_position = (stricmp(filename, ODBCINST_INI) == 0);
if (0 != strcmp(ODBCINST_INI, filename))
MYLOG(0, "setting %s position of %s(%p)\n", filename, section, comval);
/*
* It's not appropriate to handle debug or commlog here.
* Now they are handled in getDSNinfo().
*/
if (inst_position)
Global_defset(comval);
if (NULL == section || strcmp(section, INVALID_DRIVER) == 0)
return;
/*
* If inst_position of xxxxxx is present(usually not present),
* it is the default of ci->drivers.xxxxxx .
*/
/* Fetch Count is stored in driver section */
if (SQLGetPrivateProfileString(section, INI_FETCH, NULL_STRING,
temp, sizeof(temp), filename) > 0)
{
if (atoi(temp) > 0)
comval->fetch_max = atoi(temp);
}
/* Recognize Unique Index is stored in the driver section only */
if (SQLGetPrivateProfileString(section, INI_UNIQUEINDEX, NULL_STRING,
temp, sizeof(temp), filename) > 0)
comval->unique_index = atoi(temp);
/* Unknown Sizes is stored in the driver section only */
if (SQLGetPrivateProfileString(section, INI_UNKNOWNSIZES, NULL_STRING,
temp, sizeof(temp), filename) > 0)
comval->unknown_sizes = atoi(temp);
/* Lie about supported functions? */
if (SQLGetPrivateProfileString(section, INI_LIE, NULL_STRING,
temp, sizeof(temp), filename) > 0)
comval->lie = atoi(temp);
/* Parse statements */
if (SQLGetPrivateProfileString(section, INI_PARSE, NULL_STRING,
temp, sizeof(temp), filename) > 0)
comval->parse = atoi(temp);
/* UseDeclareFetch is stored in the driver section only */
if (SQLGetPrivateProfileString(section, INI_USEDECLAREFETCH, NULL_STRING,
temp, sizeof(temp), filename) > 0)
comval->use_declarefetch = atoi(temp);
/* Max Varchar Size */
if (SQLGetPrivateProfileString(section, INI_MAXVARCHARSIZE, NULL_STRING,
temp, sizeof(temp), filename) > 0)
comval->max_varchar_size = atoi(temp);
/* Max TextField Size */
if (SQLGetPrivateProfileString(section, INI_MAXLONGVARCHARSIZE, NULL_STRING,
temp, sizeof(temp), filename) > 0)
comval->max_longvarchar_size = atoi(temp);
/* Text As LongVarchar */
if (SQLGetPrivateProfileString(section, INI_TEXTASLONGVARCHAR, NULL_STRING,
temp, sizeof(temp), filename) > 0)
comval->text_as_longvarchar = atoi(temp);
/* Unknowns As LongVarchar */
if (SQLGetPrivateProfileString(section, INI_UNKNOWNSASLONGVARCHAR, NULL_STRING,
temp, sizeof(temp), filename) > 0)
comval->unknowns_as_longvarchar = atoi(temp);
/* Bools As Char */
if (SQLGetPrivateProfileString(section, INI_BOOLSASCHAR, NULL_STRING,
temp, sizeof(temp), filename) > 0)
comval->bools_as_char = atoi(temp);
/* Extra Systable prefixes */
/*
* Use ENTRY_TEST to distinguish between blank extra prefixes and no key
* entry
*/
SQLGetPrivateProfileString(section, INI_EXTRASYSTABLEPREFIXES, ENTRY_TEST,
temp, sizeof(temp), filename);
if (strcmp(temp, ENTRY_TEST))
STRCPY_FIXED(comval->extra_systable_prefixes, temp);
MYLOG(0, "comval=%p comval->extra_systable_prefixes = '%s'\n", comval, comval->extra_systable_prefixes);
/* Dont allow override of an override! */
if (inst_position)
{
/*
* Default state for future DSN's protocol attribute This isn't a
* real driver option YET. This is more intended for
* customization from the install.
*/
SQLGetPrivateProfileString(section, INI_PROTOCOL, ENTRY_TEST,
temp, sizeof(temp), filename);
if (strcmp(temp, ENTRY_TEST))
STRCPY_FIXED(comval->protocol, temp);
}
}
static void
encode(const pgNAME in, char *out, int outlen)
{
size_t i, ilen, o = 0;
char inc, *ins;
if (NAME_IS_NULL(in))
{
out[0] = '\0';
return;
}
ins = GET_NAME(in);
ilen = strlen(ins);
for (i = 0; i < ilen && o < outlen - 1; i++)
{
inc = ins[i];
if (inc == '+')
{
if (o + 2 >= outlen)
break;
snprintf(&out[o], outlen - o, "%%2B");
o += 3;
}
else if (isspace((unsigned char) inc))
out[o++] = '+';
else if (!isalnum((unsigned char) inc))
{
if (o + 2 >= outlen)
break;
snprintf(&out[o], outlen - o, "%%%02x", inc);
o += 3;
}
else
out[o++] = inc;
}
out[o++] = '\0';
}
static unsigned int
conv_from_hex(const char *s)
{
int i,
y = 0,
val;
for (i = 1; i <= 2; i++)
{
if (s[i] >= 'a' && s[i] <= 'f')
val = s[i] - 'a' + 10;
else if (s[i] >= 'A' && s[i] <= 'F')
val = s[i] - 'A' + 10;
else
val = s[i] - '0';
y += val << (4 * (2 - i));
}
return y;
}
static pgNAME
decode(const char *in)
{
size_t i, ilen = strlen(in), o = 0;
char inc, *outs;
pgNAME out;
INIT_NAME(out);
if (0 == ilen)
{
return out;
}
outs = (char *) malloc(ilen + 1);
if (!outs)
return out;
for (i = 0; i < ilen; i++)
{
inc = in[i];
if (inc == '+')
outs[o++] = ' ';
else if (inc == '%')
{
snprintf(&outs[o], ilen + 1 - o, "%c", conv_from_hex(&in[i]));
o++;
i += 2;
}
else
outs[o++] = inc;
}
outs[o++] = '\0';
STR_TO_NAME(out, outs);
free(outs);
return out;
}
/*
* Remove braces if the input value is enclosed by braces({}).
* Othewise decode the input value.
*/
static pgNAME
decode_or_remove_braces(const char *in)
{
if (OPENING_BRACKET == in[0])
{
size_t inlen = strlen(in);
if (CLOSING_BRACKET == in[inlen - 1]) /* enclosed with braces */
{
int i;
const char *istr, *eptr;
char *ostr;
pgNAME out;
INIT_NAME(out);
if (NULL == (ostr = (char *) malloc(inlen)))
return out;
eptr = in + inlen - 1;
for (istr = in + 1, i = 0; *istr && istr < eptr; i++)
{
if (CLOSING_BRACKET == istr[0] &&
CLOSING_BRACKET == istr[1])
istr++;
ostr[i] = *(istr++);
}
ostr[i] = '\0';
SET_NAME_DIRECTLY(out, ostr);
return out;
}
}
return decode(in);
}
/*
* extract the specified attribute from the comment part.
* attribute=[']value[']
*/
char *extract_extra_attribute_setting(const pgNAME setting, const char *attr)
{
const char *str = SAFE_NAME(setting);
const char *cptr, *sptr = NULL;
char *rptr;
BOOL allowed_cmd = FALSE, in_quote = FALSE, in_comment = FALSE;
int step = 0, step_last = 2;
size_t len = 0, attrlen = strlen(attr);
for (cptr = str; *cptr; cptr++)
{
if (in_quote)
{
if (LITERAL_QUOTE == *cptr)
{
if (step_last == step)
{
len = cptr - sptr;
step = 0;
}
in_quote = FALSE;
}
continue;
}
else if (in_comment)
{
if ('*' == *cptr &&
'/' == cptr[1])
{
if (step_last == step)
{
len = cptr - sptr;
step = 0;
}
in_comment = FALSE;
allowed_cmd = FALSE;
cptr++;
continue;
}
}
else if ('/' == *cptr &&
'*' == cptr[1])
{
in_comment = TRUE;
allowed_cmd = TRUE;
cptr++;
continue;
}
else
{
if (LITERAL_QUOTE == *cptr)
in_quote = TRUE;
continue;
}
/* now in comment */
if (';' == *cptr ||
isspace((unsigned char) *cptr))
{
if (step_last == step)
len = cptr - sptr;
allowed_cmd = TRUE;
step = 0;
continue;
}
if (!allowed_cmd)
continue;
switch (step)
{
case 0:
if (0 != strnicmp(cptr, attr, attrlen))
{
allowed_cmd = FALSE;
continue;
}
if (cptr[attrlen] != '=')
{
allowed_cmd = FALSE;
continue;
}
step++;
cptr += attrlen;
break;
case 1:
if (LITERAL_QUOTE == *cptr)
{
in_quote = TRUE;
cptr++;
sptr = cptr;
}
else
sptr = cptr;
step++;
break;
}
}
if (!sptr)
return NULL;
rptr = malloc(len + 1);
if (!rptr)
return NULL;
memcpy(rptr, sptr, len);
rptr[len] = '\0';
MYLOG(0, "extracted a %s '%s' from %s\n", attr, rptr, str);
return rptr;
}
signed char ci_updatable_cursors_set(ConnInfo *ci)
{
ci->updatable_cursors = DISALLOW_UPDATABLE_CURSORS;
if (ci->allow_keyset)
{
if (ci->drivers.lie || !ci->drivers.use_declarefetch)
ci->updatable_cursors |= (ALLOW_STATIC_CURSORS | ALLOW_KEYSET_DRIVEN_CURSORS | ALLOW_BULK_OPERATIONS | SENSE_SELF_OPERATIONS);
else
ci->updatable_cursors |= (ALLOW_STATIC_CURSORS | ALLOW_BULK_OPERATIONS | SENSE_SELF_OPERATIONS);
}
return ci->updatable_cursors;
}
void
CC_conninfo_release(ConnInfo *conninfo)
{
NULL_THE_NAME(conninfo->password);
NULL_THE_NAME(conninfo->conn_settings);
NULL_THE_NAME(conninfo->pqopt);
finalize_globals(&conninfo->drivers);
}
void
CC_conninfo_init(ConnInfo *conninfo, UInt4 option)
{
MYLOG(0, "entering opt=%d\n", option);
if (0 != (CLEANUP_FOR_REUSE & option))
CC_conninfo_release(conninfo);
memset(conninfo, 0, sizeof(ConnInfo));
conninfo->allow_keyset = -1;
conninfo->lf_conversion = -1;
conninfo->true_is_minus1 = -1;
conninfo->int8_as = -101;
conninfo->numeric_as = DEFAULT_NUMERIC_AS;
conninfo->optional_errors = -1;
conninfo->bytea_as_longvarbinary = -1;
conninfo->use_server_side_prepare = -1;
conninfo->lower_case_identifier = -1;
conninfo->rollback_on_error = -1;
conninfo->force_abbrev_connstr = -1;
conninfo->bde_environment = -1;
conninfo->fake_mss = -1;
conninfo->cvt_null_date_string = -1;
conninfo->accessible_only = -1;
conninfo->ignore_round_trip_time = -1;
conninfo->disable_keepalive = -1;
conninfo->keepalive_idle = -1;
conninfo->keepalive_interval = -1;
conninfo->batch_size = DEFAULT_BATCH_SIZE;
conninfo->ignore_timeout = DEFAULT_IGNORETIMEOUT;
conninfo->wcs_debug = -1;
#ifdef _HANDLE_ENLIST_IN_DTC_
conninfo->xa_opt = -1;
#endif /* _HANDLE_ENLIST_IN_DTC_ */
if (0 != (INIT_GLOBALS & option))
init_globals(&(conninfo->drivers));
}
void init_globals(GLOBAL_VALUES *glbv)
{
memset(glbv, 0, sizeof(*glbv));
glbv->debug = -1;
glbv->commlog = -1;
}
#define CORR_STRCPY(item) strncpy_null(to->item, from->item, sizeof(to->item))
#define CORR_VALCPY(item) (to->item = from->item)
void copy_globals(GLOBAL_VALUES *to, const GLOBAL_VALUES *from)
{
memset(to, 0, sizeof(*to));
/***
memcpy(to, from, sizeof(GLOBAL_VALUES));
SET_NAME_DIRECTLY(to->drivername, NULL);
***/
NAME_TO_NAME(to->drivername, from->drivername);
CORR_VALCPY(fetch_max);
CORR_VALCPY(unknown_sizes);
CORR_VALCPY(max_varchar_size);
CORR_VALCPY(max_longvarchar_size);
CORR_VALCPY(debug);
CORR_VALCPY(commlog);
CORR_VALCPY(unique_index);
CORR_VALCPY(use_declarefetch);
CORR_VALCPY(text_as_longvarchar);
CORR_VALCPY(unknowns_as_longvarchar);
CORR_VALCPY(bools_as_char);
CORR_VALCPY(lie);
CORR_VALCPY(parse);
CORR_STRCPY(extra_systable_prefixes);
CORR_STRCPY(protocol);
MYLOG(0, "driver=%s\n", SAFE_NAME(to->drivername));
}
void finalize_globals(GLOBAL_VALUES *glbv)
{
NULL_THE_NAME(glbv->drivername);
}
#undef CORR_STRCPY
#undef CORR_VALCPY
#define CORR_STRCPY(item) strncpy_null(ci->item, sci->item, sizeof(ci->item))
#define CORR_VALCPY(item) (ci->item = sci->item)
void
CC_copy_conninfo(ConnInfo *ci, const ConnInfo *sci)
{
memset(ci, 0,sizeof(ConnInfo));
CORR_STRCPY(dsn);
CORR_STRCPY(desc);
CORR_STRCPY(drivername);
CORR_STRCPY(server);
CORR_STRCPY(database);
CORR_STRCPY(username);
NAME_TO_NAME(ci->password, sci->password);
CORR_STRCPY(port);
CORR_STRCPY(sslmode);
CORR_STRCPY(onlyread);
CORR_STRCPY(fake_oid_index);
CORR_STRCPY(show_oid_column);
CORR_STRCPY(row_versioning);
CORR_STRCPY(show_system_tables);
CORR_STRCPY(translation_dll);
CORR_STRCPY(translation_option);
CORR_VALCPY(password_required);
NAME_TO_NAME(ci->conn_settings, sci->conn_settings);
CORR_VALCPY(allow_keyset);
CORR_VALCPY(updatable_cursors);
CORR_VALCPY(lf_conversion);
CORR_VALCPY(true_is_minus1);
CORR_VALCPY(int8_as);
CORR_VALCPY(numeric_as);
CORR_VALCPY(optional_errors);
CORR_VALCPY(bytea_as_longvarbinary);
CORR_VALCPY(use_server_side_prepare);
CORR_VALCPY(lower_case_identifier);
CORR_VALCPY(rollback_on_error);
CORR_VALCPY(force_abbrev_connstr);
CORR_VALCPY(bde_environment);
CORR_VALCPY(fake_mss);
CORR_VALCPY(cvt_null_date_string);
CORR_VALCPY(accessible_only);
CORR_VALCPY(ignore_round_trip_time);
CORR_VALCPY(disable_keepalive);
CORR_VALCPY(extra_opts);
CORR_VALCPY(keepalive_idle);
CORR_VALCPY(keepalive_interval);
CORR_VALCPY(batch_size);
CORR_VALCPY(ignore_timeout);
#ifdef _HANDLE_ENLIST_IN_DTC_
CORR_VALCPY(xa_opt);
#endif
copy_globals(&(ci->drivers), &(sci->drivers)); /* moved from driver's option */
}
#undef CORR_STRCPY
#undef CORR_VALCPY
1
https://gitee.com/Moeah/psqlodbc.git
git@gitee.com:Moeah/psqlodbc.git
Moeah
psqlodbc
psqlodbc
develop-15s-bug

搜索帮助