inifile.c
来自「一个可以替代windows ODBC驱动程序管理器的通用ODBC数据库引擎」· C语言 代码 · 共 1,268 行 · 第 1/2 页
C
1,268 行
/* add section first */ 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; } /* ok - we have found the section - let's see what we need to do */ if (id) { if (value) { /* add / update a key */ while (i--) { e++; /* break on next section */ if (e->section) { /* insert new entry before e */ 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)) { /* found key - do update */ 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; } } /* last section in file - add new entry */ if (_iodbcdm_cfg_storeentry (pconfig, NULL, id, value, NULL, 1) == -1) return -1; pconfig->dirty = 1; return 0; } else { /* delete a key */ while (i--) { e++; /* break on next section */ if (e->section) return 0; /* not found */ if (e->id && !strcasecmp (e->id, id)) { /* found key - do delete */ eSect = e; e++; goto doDelete; } } /* key not found - that' ok */ return 0; } } else { /* delete entire section */ /* find e : next section */ while (i--) { e++; /* break on next section */ if (e->section) break; } if (i < 0) e++; /* move up e while comment */ e2 = e - 1; while (e2->comment && !e2->section && !e2->id && !e2->value && (iswhite (e2->comment[0]) || e2->comment[0] == ';')) e2--; e = e2 + 1; doDelete: /* move up eSect while comment */ e2 = eSect - 1; while (e2->comment && !e2->section && !e2->id && !e2->value && (iswhite (e2->comment[0]) || e2->comment[0] == ';')) e2--; eSect = e2 + 1; /* delete everything between eSect .. e */ 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;}/* * Write a formatted copy of the configuration to a file * * This assumes that the inifile has already been parsed */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) { /* Add extra line before section, unless comment block found */ if (skip) fprintf (fd, "\n"); fprintf (fd, "[%s]", e->section); if (e->comment) fprintf (fd, "\t;%s", e->comment); /* Calculate m, which is the length of the longest key */ 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; } /* Add an extra lf next time around */ skip = 1; } /* * Key = value */ 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); } /* * Value only (continuation) */ else if (e->value) { fprintf (fd, " %s", e->value); if (e->comment) fprintf (fd, "\t;%s", e->comment); } /* * Comment only - check if we need an extra lf * * 1. Comment before section gets an extra blank line before * the comment starts. * * previousEntry = value * <<< INSERT BLANK LINE HERE >>> * ; Comment Block * ; Sticks to section below * [new section] * * 2. Exception on 1. for commented out definitions: * (Immediate nonwhitespace after ;) * [some section] * v1 = 1 * ;v2 = 2 << NO EXTRA LINE >> * v3 = 3 * * 3. Exception on 2. for ;; which certainly is a section comment * [some section] * definitions * <<< INSERT BLANK LINE HERE >>> * ;; block comment * [new section] */ 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++; }}/* * Write the changed file back */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 (access(filename, R_OK) == 0) return _iodbcdm_cfg_init (ppconf, filename, doCreate); */ 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;}BOOLdo_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;}BOOLinstall_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;}intinstall_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;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?