inifile.c
来自「一个可以替代windows ODBC驱动程序管理器的通用ODBC数据库引擎」· C语言 代码 · 共 1,268 行 · 第 1/2 页
C
1,268 行
/* * inifile.c * * $Id: inifile.c,v 1.1 2001/06/07 00:48:50 source Exp $ * * Configuration File Management * * The iODBC driver manager. * * Copyright (C) 2001 by OpenLink Software <iodbc@openlinksw.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#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);/*** READ MODULE ****/#ifndef O_BINARY#define O_BINARY 0#endif#ifdef _MACstatic intstrcasecmp (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/* * Initialize a configuration */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 the file does not exist, try to create it */ 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;}/* * Free all data associated with a configuration */int_iodbcdm_cfg_done (PCONFIG pconfig){ if (pconfig) { _iodbcdm_cfg_freeimage (pconfig); if (pconfig->fileName) free (pconfig->fileName); free (pconfig); } return 0;}/* * Free the content specific data of a configuration */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;}/* * This procedure reads an copy of the file into memory * caching the content based on stat */int_iodbcdm_cfg_refresh (PCONFIG pconfig){ struct stat sb; char *mem; int fd; if (pconfig == NULL || stat (pconfig->fileName, &sb) == -1) return -1; /* * If our image is dirty, ignore all local changes * and force a reread of the image, thus ignoring all mods */ if (pconfig->dirty) _iodbcdm_cfg_freeimage (pconfig); /* * Check to see if our incore image is still valid */ if (pconfig->image && sb.st_size == pconfig->size && sb.st_mtime == pconfig->mtime) return 0; /* * Now read the full image */ 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); /* * Store the new copy */ _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;}/* * Parse the in-memory copy of the configuration data */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; /* * Skip leading spaces */ if (iswhite (*lp)) { lp = __iodbcdm_cfg_skipwhite (lp); isContinue = 1; } else isContinue = 0; /* * Parse Section */ 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 != ';') { /* Try to parse * 1. Key = Value * 2. Value (iff isContinue) */ if (!isContinue) { /* Parse `<Key> = ..' */ id = lp; if ((lp = strchr (id, '=')) == NULL) continue; *lp++ = 0; rtrim (id); lp = __iodbcdm_cfg_skipwhite (lp); } /* Parse value */ 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++; } } /* * Parse Comment */ 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;}/*** COMPATIBILITY LAYER ***/int_iodbcdm_cfg_rewind (PCONFIG pconfig){ if (!_iodbcdm_cfg_valid (pconfig)) return -1; pconfig->flags = CFG_VALID; pconfig->cursor = 0; return 0;}/* * returns: * 0 success * -1 no next entry * * section id value flags meaning * !0 0 !0 SECTION [value] * !0 !0 !0 DEFINE id = value|id="value"|id='value' * !0 0 !0 0 value * 0 0 0 EOF end of file encountered */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;}/*** WRITE MODULE ****//* * Change the configuration * * section id value action * -------------------------------------------------------------------------- * value value value update '<entry>=<string>' in section <section> * value value NULL delete '<entry>' from section <section> * value NULL NULL delete section <section> */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; /* find the section */ e = pconfig->entries; i = pconfig->numEntries; eSect = 0; while (i--) { if (e->section && !strcasecmp (e->section, section)) { eSect = e; break; } e++; } /* did we find the section? */ if (!eSect) { /* check for delete operation on a nonexisting section */ if (!id || !value) return 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?