#include <iodbc.h>
#include <iodbcinst.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifndef _MAC
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include <unistd.h>
#include <ctype.h>
#include "inifile.h"
#include "misc.h"
extern BOOL ValidDSN (LPCSTR lpszDSN);
static PCFGENTRY __iodbcdm_cfg_poolalloc (PCONFIG p, u_int count);
static int __iodbcdm_cfg_parse (PCONFIG pconfig);
#ifndef O_BINARY
#define O_BINARY 0
#endif
#ifdef _MAC
static int
strcasecmp (const char *s1, const char *s2)
{
int cmp;
while (*s1)
{
if ((cmp = toupper (*s1) - toupper (*s2)) != 0)
return cmp;
s1++;
s2++;
}
return (*s2) ? -1 : 0;
}
#endif
int
_iodbcdm_cfg_init (PCONFIG *ppconf, const char *filename, int doCreate)
{
PCONFIG pconfig;
*ppconf = NULL;
if (!filename)
return -1;
if ((pconfig = (PCONFIG) calloc (1, sizeof (TCONFIG))) == NULL)
return -1;
pconfig->fileName = strdup (filename);
if (pconfig->fileName == NULL)
{
_iodbcdm_cfg_done (pconfig);
return -1;
}
if (doCreate && access (pconfig->fileName, 0) == -1)
{
int fd;
fd = creat (filename, 0644);
if (fd)
close (fd);
}
if (_iodbcdm_cfg_refresh (pconfig) == -1)
{
_iodbcdm_cfg_done (pconfig);
return -1;
}
*ppconf = pconfig;
return 0;
}
int
_iodbcdm_cfg_done (PCONFIG pconfig)
{
if (pconfig)
{
_iodbcdm_cfg_freeimage (pconfig);
if (pconfig->fileName)
free (pconfig->fileName);
free (pconfig);
}
return 0;
}
int
_iodbcdm_cfg_freeimage (PCONFIG pconfig)
{
char *saveName;
PCFGENTRY e;
u_int i;
if (pconfig->image)
free (pconfig->image);
if (pconfig->entries)
{
e = pconfig->entries;
for (i = 0; i < pconfig->numEntries; i++, e++)
{
if (e->flags & CFE_MUST_FREE_SECTION)
free (e->section);
if (e->flags & CFE_MUST_FREE_ID)
free (e->id);
if (e->flags & CFE_MUST_FREE_VALUE)
free (e->value);
if (e->flags & CFE_MUST_FREE_COMMENT)
free (e->comment);
}
free (pconfig->entries);
}
saveName = pconfig->fileName;
memset (pconfig, 0, sizeof (TCONFIG));
pconfig->fileName = saveName;
return 0;
}
int
_iodbcdm_cfg_refresh (PCONFIG pconfig)
{
struct stat sb;
char *mem;
int fd;
if (pconfig == NULL || stat (pconfig->fileName, &sb) == -1)
return -1;
if (pconfig->dirty)
_iodbcdm_cfg_freeimage (pconfig);
if (pconfig->image && sb.st_size == pconfig->size
&& sb.st_mtime == pconfig->mtime)
return 0;
if ((fd = open (pconfig->fileName, O_RDONLY | O_BINARY)) == -1)
return -1;
mem = (char *) malloc (sb.st_size + 1);
if (mem == NULL || read (fd, mem, sb.st_size) != sb.st_size)
{
free (mem);
close (fd);
return -1;
}
mem[sb.st_size] = 0;
close (fd);
_iodbcdm_cfg_freeimage (pconfig);
pconfig->image = mem;
pconfig->size = sb.st_size;
pconfig->mtime = sb.st_mtime;
if (__iodbcdm_cfg_parse (pconfig) == -1)
{
_iodbcdm_cfg_freeimage (pconfig);
return -1;
}
return 1;
}
#define iseolchar(C) (strchr ("\n\r\x1a", C) != NULL)
#define iswhite(C) (strchr ("\f\t ", C) != NULL)
static char *
__iodbcdm_cfg_skipwhite (char *s)
{
while (*s && iswhite (*s))
s++;
return s;
}
static int
__iodbcdm_cfg_getline (char **pCp, char **pLinePtr)
{
char *start;
char *cp = *pCp;
while (*cp && iseolchar (*cp))
cp++;
start = cp;
if (pLinePtr)
*pLinePtr = cp;
while (*cp && !iseolchar (*cp))
cp++;
if (*cp)
{
*cp++ = 0;
*pCp = cp;
while (--cp >= start && iswhite (*cp));
cp[1] = 0;
}
else
*pCp = cp;
return *start ? 1 : 0;
}
static char *
rtrim (char *str)
{
char *endPtr;
if (str == NULL || *str == '\0')
return NULL;
for (endPtr = &str[strlen (str) - 1]; endPtr >= str && isspace (*endPtr);
endPtr--);
endPtr[1] = 0;
return endPtr >= str ? endPtr : NULL;
}
static int
__iodbcdm_cfg_parse (PCONFIG pconfig)
{
int isContinue, inString;
char *imgPtr;
char *endPtr;
char *lp;
char *section;
char *id;
char *value;
char *comment;
if (_iodbcdm_cfg_valid (pconfig))
return 0;
endPtr = pconfig->image + pconfig->size;
for (imgPtr = pconfig->image; imgPtr < endPtr;)
{
if (!__iodbcdm_cfg_getline (&imgPtr, &lp))
continue;
section = id = value = comment = NULL;
if (iswhite (*lp))
{
lp = __iodbcdm_cfg_skipwhite (lp);
isContinue = 1;
}
else
isContinue = 0;
if (*lp == '[')
{
section = __iodbcdm_cfg_skipwhite (lp + 1);
if ((lp = strchr (section, ']')) == NULL)
continue;
*lp++ = 0;
if (rtrim (section) == NULL)
{
section = NULL;
continue;
}
lp = __iodbcdm_cfg_skipwhite (lp);
}
else if (*lp != ';')
{
if (!isContinue)
{
id = lp;
if ((lp = strchr (id, '=')) == NULL)
continue;
*lp++ = 0;
rtrim (id);
lp = __iodbcdm_cfg_skipwhite (lp);
}
inString = 0;
value = lp;
while (*lp)
{
if (inString)
{
if (*lp == inString)
inString = 0;
}
else if (*lp == '"' || *lp == '\'')
inString = *lp;
else if (*lp == ';' && iswhite (lp[-1]))
{
*lp = 0;
comment = lp + 1;
rtrim (value);
break;
}
lp++;
}
}
if (*lp == ';')
comment = lp + 1;
if (_iodbcdm_cfg_storeentry (pconfig, section, id, value, comment,
0) == -1)
{
pconfig->dirty = 1;
return -1;
}
}
pconfig->flags |= CFG_VALID;
return 0;
}
int
_iodbcdm_cfg_storeentry (
PCONFIG pconfig,
char *section,
char *id,
char *value,
char *comment,
int dynamic)
{
PCFGENTRY data;
if ((data = __iodbcdm_cfg_poolalloc (pconfig, 1)) == NULL)
return -1;
data->flags = 0;
if (dynamic)
{
if (section)
section = strdup (section);
if (id)
id = strdup (id);
if (value)
value = strdup (value);
if (comment)
comment = strdup (value);
if (section)
data->flags |= CFE_MUST_FREE_SECTION;
if (id)
data->flags |= CFE_MUST_FREE_ID;
if (value)
data->flags |= CFE_MUST_FREE_VALUE;
if (comment)
data->flags |= CFE_MUST_FREE_COMMENT;
}
data->section = section;
data->id = id;
data->value = value;
data->comment = comment;
return 0;
}
static PCFGENTRY
__iodbcdm_cfg_poolalloc (PCONFIG p, u_int count)
{
PCFGENTRY newBase;
u_int newMax;
if (p->numEntries + count > p->maxEntries)
{
newMax =
p->maxEntries ? count + p->maxEntries + p->maxEntries / 2 : count +
4096 / sizeof (TCFGENTRY);
newBase = (PCFGENTRY) malloc (newMax * sizeof (TCFGENTRY));
if (newBase == NULL)
return NULL;
if (p->entries)
{
memcpy (newBase, p->entries, p->numEntries * sizeof (TCFGENTRY));
free (p->entries);
}
p->entries = newBase;
p->maxEntries = newMax;
}
newBase = &p->entries[p->numEntries];
p->numEntries += count;
return newBase;
}
int
_iodbcdm_cfg_rewind (PCONFIG pconfig)
{
if (!_iodbcdm_cfg_valid (pconfig))
return -1;
pconfig->flags = CFG_VALID;
pconfig->cursor = 0;
return 0;
}
int
_iodbcdm_cfg_nextentry (PCONFIG pconfig)
{
PCFGENTRY e;
if (!_iodbcdm_cfg_valid (pconfig) || _iodbcdm_cfg_eof (pconfig))
return -1;
pconfig->flags &= ~(CFG_TYPEMASK);
pconfig->id = pconfig->value = NULL;
while (1)
{
if (pconfig->cursor >= pconfig->numEntries)
{
pconfig->flags |= CFG_EOF;
return -1;
}
e = &pconfig->entries[pconfig->cursor++];
if (e->section)
{
pconfig->section = e->section;
pconfig->flags |= CFG_SECTION;
return 0;
}
if (e->value)
{
pconfig->value = e->value;
if (e->id)
{
pconfig->id = e->id;
pconfig->flags |= CFG_DEFINE;
}
else
pconfig->flags |= CFG_CONTINUE;
return 0;
}
}
}
int
_iodbcdm_cfg_find (PCONFIG pconfig, char *section, char *id)
{
int atsection;
if (!_iodbcdm_cfg_valid (pconfig) || _iodbcdm_cfg_rewind (pconfig))
return -1;
atsection = 0;
while (_iodbcdm_cfg_nextentry (pconfig) == 0)
{
if (atsection)
{
if (_iodbcdm_cfg_section (pconfig))
return -1;
else if (_iodbcdm_cfg_define (pconfig))
{
char *szId = _iodbcdm_remove_quotes (pconfig->id);
int bSame;
if (szId)
{
bSame = !strcasecmp (szId, id);
free (szId);
if (bSame)
return 0;
}
}
}
else if (_iodbcdm_cfg_section (pconfig)
&& !strcasecmp (pconfig->section, section))
{
if (id == NULL)
return 0;
atsection = 1;
}
}
return -1;
}
int
_iodbcdm_cfg_write (
PCONFIG pconfig,
char *section,
char *id,
char *value)
{
PCFGENTRY e, e2, eSect;
int idx;
int i;
if (!_iodbcdm_cfg_valid (pconfig) || section == NULL)
return -1;
e = pconfig->entries;
i = pconfig->numEntries;
eSect = 0;
while (i--)
{
if (e->section && !strcasecmp (e->section, section))
{
eSect = e;
break;
}
e++;
}
if (!eSect)
{
if (!id || !value)
return 0;
if (_iodbcdm_cfg_storeentry (pconfig, section, NULL, NULL, NULL,
1) == -1
|| _iodbcdm_cfg_storeentry (pconfig, NULL, id, value, NULL,
1) == -1)
return -1;
pconfig->dirty = 1;
return 0;
}
if (id)
{
if (value)
{
while (i--)
{
e++;
if (e->section)
{
idx = e - pconfig->entries;
if (__iodbcdm_cfg_poolalloc (pconfig, 1) == NULL)
return -1;
memmove (e + 1, e,
(pconfig->numEntries - idx) * sizeof (TCFGENTRY));
e->section = NULL;
e->id = strdup (id);
e->value = strdup (value);
e->comment = NULL;
if (e->id == NULL || e->value == NULL)
return -1;
e->flags |= CFE_MUST_FREE_ID | CFE_MUST_FREE_VALUE;
pconfig->dirty = 1;
return 0;
}
if (e->id && !strcasecmp (e->id, id))
{
if (e->value && (e->flags & CFE_MUST_FREE_VALUE))
{
e->flags &= ~CFE_MUST_FREE_VALUE;
free (e->value);
}
pconfig->dirty = 1;
if ((e->value = strdup (value)) == NULL)
return -1;
e->flags |= CFE_MUST_FREE_VALUE;
return 0;
}
}
if (_iodbcdm_cfg_storeentry (pconfig, NULL, id, value, NULL,
1) == -1)
return -1;
pconfig->dirty = 1;
return 0;
}
else
{
while (i--)
{
e++;
if (e->section)
return 0;
if (e->id && !strcasecmp (e->id, id))
{
eSect = e;
e++;
goto doDelete;
}
}
return 0;
}
}
else
{
while (i--)
{
e++;
if (e->section)
break;
}
if (i < 0)
e++;
e2 = e - 1;
while (e2->comment && !e2->section && !e2->id && !e2->value
&& (iswhite (e2->comment[0]) || e2->comment[0] == ';'))
e2--;
e = e2 + 1;
doDelete:
e2 = eSect - 1;
while (e2->comment && !e2->section && !e2->id && !e2->value
&& (iswhite (e2->comment[0]) || e2->comment[0] == ';'))
e2--;
eSect = e2 + 1;
for (e2 = eSect; e2 < e; e2++)
{
if (e2->flags & CFE_MUST_FREE_SECTION)
free (e2->section);
if (e2->flags & CFE_MUST_FREE_ID)
free (e2->id);
if (e2->flags & CFE_MUST_FREE_VALUE)
free (e2->value);
if (e2->flags & CFE_MUST_FREE_COMMENT)
free (e2->comment);
}
idx = e - pconfig->entries;
memmove (eSect, e, (pconfig->numEntries - idx) * sizeof (TCFGENTRY));
pconfig->numEntries -= e - eSect;
pconfig->dirty = 1;
}
return 0;
}
static void
__iodbcdm_cfg_outputformatted (PCONFIG pconfig, FILE *fd)
{
PCFGENTRY e = pconfig->entries;
int i = pconfig->numEntries;
int m = 0;
int j, l;
int skip = 0;
while (i--)
{
if (e->section)
{
if (skip)
fprintf (fd, "\n");
fprintf (fd, "[%s]", e->section);
if (e->comment)
fprintf (fd, "\t;%s", e->comment);
m = 0;
for (j = 1; j <= i; j++)
{
if (e[j].section)
break;
if (e[j].id && (l = strlen (e[j].id)) > m)
m = l;
}
skip = 1;
}
else if (e->id && e->value)
{
if (m)
fprintf (fd, "%-*.*s = %s", m, m, e->id, e->value);
else
fprintf (fd, "%s = %s", e->id, e->value);
if (e->comment)
fprintf (fd, "\t;%s", e->comment);
}
else if (e->value)
{
fprintf (fd, " %s", e->value);
if (e->comment)
fprintf (fd, "\t;%s", e->comment);
}
else if (e->comment)
{
if (skip && (iswhite (e->comment[0]) || e->comment[0] == ';'))
{
for (j = 1; j <= i; j++)
{
if (e[j].section)
{
fprintf (fd, "\n");
skip = 0;
break;
}
if (e[j].id || e[j].value)
break;
}
}
fprintf (fd, ";%s", e->comment);
}
fprintf (fd, "\n");
e++;
}
}
int
_iodbcdm_cfg_commit (PCONFIG pconfig)
{
FILE *fp;
if (!_iodbcdm_cfg_valid (pconfig))
return -1;
if (pconfig->dirty)
{
if ((fp = fopen (pconfig->fileName, "w")) == NULL)
return -1;
__iodbcdm_cfg_outputformatted (pconfig, fp);
fclose (fp);
pconfig->dirty = 0;
}
return 0;
}
int
_iodbcdm_cfg_next_section(PCONFIG pconfig)
{
PCFGENTRY e;
do
if (0 != _iodbcdm_cfg_nextentry (pconfig))
return -1;
while (!_iodbcdm_cfg_section (pconfig));
return 0;
}
int
_iodbcdm_cfg_search_init(PCONFIG *ppconf, const char *filename, int doCreate)
{
char pathbuf[1024];
if (strstr (filename, "odbc.ini") || strstr (filename, "ODBC.INI"))
return _iodbcdm_cfg_init (ppconf, _iodbcadm_getinifile (pathbuf,
sizeof (pathbuf), FALSE, doCreate), doCreate);
else if (strstr (filename, "odbcinst.ini")
|| strstr (filename, "ODBCINST.INI"))
return _iodbcdm_cfg_init (ppconf, _iodbcadm_getinifile (pathbuf,
sizeof (pathbuf), TRUE, doCreate), doCreate);
else
return -1;
}
int
_iodbcdm_list_sections (PCONFIG pCfg, LPSTR lpszRetBuffer, int cbRetBuffer)
{
int curr = 0, sect_len = 0;
lpszRetBuffer[0] = 0;
if (0 == _iodbcdm_cfg_rewind (pCfg))
{
while (curr < cbRetBuffer && 0 == _iodbcdm_cfg_next_section (pCfg)
&& pCfg->section)
{
sect_len = strlen (pCfg->section) + 1;
sect_len =
sect_len > cbRetBuffer - curr ? cbRetBuffer - curr : sect_len;
memmove (lpszRetBuffer + curr, pCfg->section, sect_len);
curr += sect_len;
}
if (curr < cbRetBuffer)
lpszRetBuffer[curr] = 0;
return curr;
}
return 0;
}
int
_iodbcdm_list_entries (PCONFIG pCfg, LPCSTR lpszSection, LPSTR lpszRetBuffer, int cbRetBuffer)
{
int curr = 0, sect_len = 0;
lpszRetBuffer[0] = 0;
if (0 == _iodbcdm_cfg_rewind (pCfg))
{
while (curr < cbRetBuffer && 0 == _iodbcdm_cfg_nextentry (pCfg))
{
if (_iodbcdm_cfg_define (pCfg)
&& !strcmp (pCfg->section, lpszSection) && pCfg->id)
{
sect_len = strlen (pCfg->id) + 1;
sect_len =
sect_len >
cbRetBuffer - curr ? cbRetBuffer - curr : sect_len;
memmove (lpszRetBuffer + curr, pCfg->id, sect_len);
curr += sect_len;
}
}
if (curr < cbRetBuffer)
lpszRetBuffer[curr] = 0;
return curr;
}
return 0;
}
BOOL
do_create_dsns (PCONFIG pCfg, PCONFIG pInfCfg, LPSTR szDriver, LPSTR szDSNS, LPSTR szDiz)
{
char *szValue = strdup (szDSNS), *szCurr = szValue, *szComma;
int hasMore = FALSE;
BOOL retcode = FALSE;
do
{
szComma = strchr (szCurr, ',');
if (szComma)
{
*szComma = 0;
hasMore = TRUE;
}
else
hasMore = FALSE;
#ifdef WIN32
if (_iodbcdm_cfg_write (pCfg, "ODBC 32 bit Data Sources", szCurr,
szDiz))
#else
if (_iodbcdm_cfg_write (pCfg, "ODBC Data Sources", szCurr, szDiz))
#endif
goto error;
if (!ValidDSN (szCurr) || _iodbcdm_cfg_write (pCfg, szCurr, NULL, NULL))
goto error;
if (_iodbcdm_cfg_find (pInfCfg, szCurr, NULL)
&& !_iodbcdm_cfg_write (pCfg, szCurr, NULL, NULL))
{
if (_iodbcdm_cfg_write (pCfg, szCurr, "Driver", szDriver))
goto error;
while (!_iodbcdm_cfg_nextentry (pInfCfg)
&& _iodbcdm_cfg_define (pInfCfg))
{
if (_iodbcdm_cfg_write (pCfg, szCurr, pInfCfg->id,
pInfCfg->value))
goto error;
}
}
szCurr = szComma + 1;
}
while (hasMore);
retcode = TRUE;
error:
free (szValue);
return retcode;
}
BOOL
install_from_ini (PCONFIG pCfg, PCONFIG pOdbcCfg, LPSTR szInfFile, LPSTR szDriver, BOOL drivers)
{
PCONFIG pInfCfg;
char *szKeysSection = NULL, *szDriverFile = NULL, *szSetupFile = NULL,
*szValue = NULL, *szId = NULL, *szComma, *szComma1;
BOOL ret = FALSE;
if (_iodbcdm_cfg_write (pCfg, szDriver, NULL, NULL))
return ret;
if (_iodbcdm_cfg_init (&pInfCfg, szInfFile, FALSE))
return ret;
if (_iodbcdm_cfg_find (pInfCfg,
drivers ? "ODBC Drivers" : "ODBC Translators", szDriver))
goto error;
#ifdef WIN32
if (_iodbcdm_cfg_write (pCfg,
drivers ? "ODBC 32 bit Drivers" : "ODBC 32 bit Translators",
szDriver, "Installed"))
#else
if (_iodbcdm_cfg_write (pCfg, drivers ? "ODBC Drivers" : "ODBC Translators",
szDriver, "Installed"))
#endif
goto error;
if (_iodbcdm_cfg_find (pInfCfg, szDriver,
drivers ? "Driver" : "Translator"))
goto error;
szComma = strchr (pInfCfg->value, ',');
szComma1 = strchr (szComma + 1, ',');
if (!szComma || !szComma1 || szComma + 1 == szComma1)
goto error;
*szComma1 = 0;
szDriverFile = strdup (szComma + 1);
if (_iodbcdm_cfg_write (pCfg, szDriver, drivers ? "Driver" : "Translator",
szDriverFile))
goto error;
if (!_iodbcdm_cfg_find (pInfCfg, szDriver, "Setup"))
{
szComma = strchr (pInfCfg->value, ',');
szComma1 = strchr (szComma + 1, ',');
if (!szComma || !szComma1 || szComma + 1 == szComma1)
goto error;
*szComma1 = 0;
szSetupFile = strdup (szComma + 1);
if (_iodbcdm_cfg_write (pCfg, szDriver, "Setup", szSetupFile))
goto error;
}
if (!_iodbcdm_cfg_find (pInfCfg, szDriver, NULL))
{
while (!_iodbcdm_cfg_nextentry (pInfCfg)
&& _iodbcdm_cfg_define (pInfCfg))
if (strcmp (pInfCfg->id, drivers ? "\"Driver\"" : "\"Translator\"")
&& strcmp (pInfCfg->id, "\"Setup\""))
{
szComma = strchr (pInfCfg->value, ',');
szComma1 = strchr (szComma + 1, ',');
if (!szComma || !szComma1 || szComma + 1 == szComma1)
szValue = strdup ("");
else
{
*szComma1 = 0;
szValue = strdup (szComma + 1);
}
szComma = strchr (pInfCfg->id, '"');
szComma1 = strchr (szComma + 1, '"');
if (!szComma || !szComma1 || szComma + 1 == szComma1)
goto loop_cont;
else
{
*szComma1 = 0;
szId = strdup (szComma + 1);
}
if (_iodbcdm_cfg_write (pCfg, szDriver, szId, szValue))
goto error;
loop_cont:
if (szValue)
{
free (szValue);
szValue = NULL;
}
if (szId)
{
free (szId);
szId = NULL;
}
}
}
if (!drivers)
goto quit;
szKeysSection = (char *) calloc (strlen (szDriver) + 6, sizeof (char));
strcpy (szKeysSection, szDriver);
strcat (szKeysSection, "-Keys");
if (!_iodbcdm_cfg_find (pInfCfg, szKeysSection, NULL))
{
while (!_iodbcdm_cfg_nextentry (pInfCfg)
&& _iodbcdm_cfg_define (pInfCfg))
{
if (strcmp (pInfCfg->id, "CreateDSN"))
{
if (_iodbcdm_cfg_write (pCfg, szDriver, pInfCfg->id,
pInfCfg->value))
goto error;
}
else if (!do_create_dsns (pOdbcCfg, pCfg, szDriverFile,
pInfCfg->value, szDriver))
goto error;
}
}
quit:
ret = TRUE;
error:
if (szKeysSection)
free (szKeysSection);
if (szDriverFile)
free (szDriverFile);
if (szSetupFile)
free (szSetupFile);
if (szValue)
free (szValue);
if (szId)
free (szId);
_iodbcdm_cfg_done (pInfCfg);
return ret;
}
int
install_from_string (PCONFIG pCfg, PCONFIG pOdbcCfg, LPSTR lpszDriver, BOOL drivers)
{
char *szCurr = (char *) lpszDriver, *szDiz = lpszDriver;
char *szAsignment, *szEqual, *szValue, *szDriver = NULL;
if (_iodbcdm_cfg_write (pCfg, lpszDriver, NULL, NULL))
return FALSE;
#ifdef WIN32
if (_iodbcdm_cfg_write (pCfg,
drivers ? "ODBC 32 bit Drivers" : "ODBC 32 bit Translators",
lpszDriver, "Installed"))
#else
if (_iodbcdm_cfg_write (pCfg, drivers ? "ODBC Drivers" : "ODBC Translators",
lpszDriver, "Installed"))
#endif
return FALSE;
for (szCurr = lpszDriver + strlen (lpszDriver) + 1; *szCurr;
szCurr += strlen (szCurr) + 1)
{
szAsignment = strdup (szCurr);
szEqual = strchr (szAsignment, '=');
szValue = szEqual + 1;
if (szEqual)
*szEqual = 0;
else
goto loop_error;
if ((drivers && !strcmp (szAsignment, "Driver")) || (!drivers
&& !strcmp (szAsignment, "Translator")))
{
if (szDriver)
free (szDriver);
szDriver = strdup (szValue);
}
if (drivers)
{
if (strcmp (szAsignment, "CreateDSN"))
{
if (_iodbcdm_cfg_write (pCfg, lpszDriver, szAsignment, szValue))
goto loop_error;
}
else if (!do_create_dsns (pOdbcCfg, pCfg, szDriver, szValue, szDiz))
goto loop_error;
}
else if (_iodbcdm_cfg_write (pCfg, lpszDriver, szAsignment, szValue))
goto loop_error;
free (szAsignment);
continue;
loop_error:
if (szDriver)
free (szDriver);
free (szAsignment);
return FALSE;
}
if (szDriver)
free (szDriver);
else
return FALSE;
return TRUE;
}