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 + -
显示快捷键?