⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 config.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 2 页
字号:
/*     This file is part of GNUnet.     (C) 2006, 2007 Christian Grothoff (and other contributing authors)     GNUnet is free software; you can redistribute it and/or modify     it under the terms of the GNU General Public License as published     by the Free Software Foundation; either version 2, or (at your     option) any later version.     GNUnet 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     General Public License for more details.     You should have received a copy of the GNU General Public License     along with GNUnet; see the file COPYING.  If not, write to the     Free Software Foundation, Inc., 59 Temple Place - Suite 330,     Boston, MA 02111-1307, USA.*//** * @file src/util/config/config.c * @brief configuration management * * @author Christian Grothoff */#include "platform.h"#include "gnunet_util.h"/** * @brief configuration entry */typedef struct GNUNET_GC_Entry{  /**   * key for this entry   */  char *key;  /**   * current, commited value   */  char *val;  /**   * non-null during uncommited update   */  char *dirty_val;} GNUNET_GC_Entry;/** * @brief configuration section */typedef struct GNUNET_GC_Section{  /**   * name of the section   */  char *name;  /**   * number of entries in section   */  unsigned int size;  /**   * entries in the section   */  GNUNET_GC_Entry *entries;} GNUNET_GC_Section;/** * @brief GNUNET_GC_ChangeListener and context */typedef struct GNUNET_GC_Listener{  /**   * Callback.   */  GNUNET_GC_ChangeListener listener;  /**   * Context for callback.   */  void *ctx;} GNUNET_GC_Listener;/** * @brief configuration data */typedef struct GNUNET_GC_Configuration{  /**   * Lock to access the data.   */  struct GNUNET_Mutex *lock;  /**   * Context for logging errors, maybe NULL.   */  struct GNUNET_GE_Context *ectx;  /**   * Modification indication since last save   * 0 if clean, 1 if dirty, -1 on error (i.e. last save failed)   */  int dirty;  /**   * How many sections do we have?   */  unsigned int ssize;  /**   * Array with "ssize" entries.   */  GNUNET_GC_Section *sections;  /**   * How many listeners do we have?   */  unsigned int lsize;  /**   * Array with "lsize" entries.   */  GNUNET_GC_Listener *listeners;} GNUNET_GC_Configuration;voidGNUNET_GC_free (struct GNUNET_GC_Configuration *cfg){  GNUNET_GC_Section *sec;  GNUNET_GC_Entry *e;  int i;  int j;  for (i = 0; i < cfg->ssize; i++)    {      sec = &cfg->sections[i];      for (j = 0; j < sec->size; j++)        {          e = &sec->entries[j];          GNUNET_free (e->key);          GNUNET_free_non_null (e->val);          GNUNET_GE_ASSERT (cfg->ectx, e->dirty_val == NULL);        }      GNUNET_array_grow (sec->entries, sec->size, 0);      GNUNET_free (sec->name);    }  GNUNET_array_grow (cfg->sections, cfg->ssize, 0);  GNUNET_GE_ASSERT (cfg->ectx, cfg->listeners == 0);  GNUNET_mutex_destroy (cfg->lock);  GNUNET_free (cfg);}voidGNUNET_GC_set_error_context (struct GNUNET_GC_Configuration *cfg,                             struct GNUNET_GE_Context *ectx){  cfg->ectx = ectx;}intGNUNET_GC_parse_configuration (struct GNUNET_GC_Configuration *cfg,                               const char *filename){  int dirty;  char line[256];  char tag[64];  char value[192];  FILE *fp;  int nr;  int i;  int emptyline;  int ret;  char *section;  char *fn;  fn = GNUNET_expand_file_name (NULL, filename);  GNUNET_mutex_lock (cfg->lock);  dirty = cfg->dirty;           /* back up value! */  if (NULL == (fp = FOPEN (fn, "r")))    {      GNUNET_GE_LOG_STRERROR_FILE (cfg->ectx,                                   GNUNET_GE_ERROR | GNUNET_GE_USER |                                   GNUNET_GE_IMMEDIATE | GNUNET_GE_BULK |                                   GNUNET_GE_REQUEST, "fopen", fn);      GNUNET_mutex_unlock (cfg->lock);      GNUNET_free (fn);      return -1;    }  GNUNET_free (fn);  ret = 0;  section = GNUNET_strdup ("");  memset (line, 0, 256);  nr = 0;  while (NULL != fgets (line, 255, fp))    {      nr++;      for (i = 0; i < 255; i++)        if (line[i] == '\t')          line[i] = ' ';      if (line[0] == '\n' || line[0] == '#' || line[0] == '%' ||          line[0] == '\r')        continue;      emptyline = 1;      for (i = 0; (i < 255 && line[i] != 0); i++)        if (line[i] != ' ' && line[i] != '\n' && line[i] != '\r')          emptyline = 0;      if (emptyline == 1)        continue;      /* remove tailing whitespace */      for (i = strlen (line) - 1; (i >= 0) && (isspace (line[i])); i--)        line[i] = '\0';      if (1 == sscanf (line, "@INLINE@ %191[^\n]", value))        {          /* @INLINE@ value */          char *expanded = GNUNET_expand_file_name (cfg->ectx,                                                    value);          if (0 != GNUNET_GC_parse_configuration (cfg, expanded))            ret = -1;           /* failed to parse included config */        }      else if (1 == sscanf (line, "[%99[^]]]", value))        {          /* [value] */          GNUNET_free (section);          section = GNUNET_strdup (value);        }      else if (2 == sscanf (line, " %63[^= ] = %191[^\n]", tag, value))        {          /* tag = value */          /* Strip LF */          i = strlen (value) - 1;          while ((i >= 0) && (isspace (value[i])))            value[i--] = '\0';          /* remove quotes */          i = 0;          if (value[0] == '"')            {              i = 1;              while ((value[i] != '\0') && (value[i] != '"'))                i++;              if (value[i] == '"')                {                  value[i] = '\0';                  i = 1;                }              else                i = 0;            }          /* first check if we have this value already;             this could happen if the value was changed             using a command-line option; only set it             if we do not have a value already... */          if ((GNUNET_NO == GNUNET_GC_have_configuration_value (cfg,                                                                section,                                                                tag)) &&              (0 != GNUNET_GC_set_configuration_value_string (cfg,                                                              cfg->ectx,                                                              section,                                                              tag,                                                              &value[i])))            ret = -1;           /* could not set value */        }      else if (1 == sscanf (line, " %63[^= ] =[^\n]", tag))        {          /* tag = */          /* first check if we have this value already;             this could happen if the value was changed             using a command-line option; only set it             if we do not have a value already... */          if ((GNUNET_NO == GNUNET_GC_have_configuration_value (cfg,                                                                section,                                                                tag)) &&              (0 != GNUNET_GC_set_configuration_value_string (cfg,                                                              cfg->ectx,                                                              section, tag,                                                              "")))            ret = -1;           /* could not set value */        }      else        {          /* parse error */          GNUNET_GE_LOG (cfg->ectx,                         GNUNET_GE_ERROR | GNUNET_GE_USER |                         GNUNET_GE_IMMEDIATE | GNUNET_GE_BULK,                         _                         ("Syntax error in configuration file `%s' at line %d.\n"),                         filename, nr);          ret = -1;          break;        }    }  if (0 != fclose (fp))    {      GNUNET_GE_LOG_STRERROR_FILE (cfg->ectx,                                   GNUNET_GE_ERROR | GNUNET_GE_USER |                                   GNUNET_GE_ADMIN | GNUNET_GE_IMMEDIATE |                                   GNUNET_GE_BULK | GNUNET_GE_REQUEST,                                   "fclose", filename);      ret = -1;    }  /* restore dirty flag - anything we set in the meantime     came from disk */  cfg->dirty = dirty;  GNUNET_mutex_unlock (cfg->lock);  GNUNET_free (section);  return ret;}intGNUNET_GC_test_dirty (struct GNUNET_GC_Configuration *cfg){  return cfg->dirty;}intGNUNET_GC_write_configuration (struct GNUNET_GC_Configuration *data,                               const char *filename){  GNUNET_GC_Section *sec;  GNUNET_GC_Entry *e;  int i;  int j;  FILE *fp;  int error;  int ret;  char *fn;  char *val;  char *pos;  fn = GNUNET_expand_file_name (NULL, filename);  GNUNET_disk_directory_create_for_file (NULL, fn);  if (NULL == (fp = FOPEN (fn, "w")))    {      GNUNET_GE_LOG_STRERROR_FILE (data->ectx,                                   GNUNET_GE_ERROR | GNUNET_GE_USER |                                   GNUNET_GE_IMMEDIATE, "fopen", fn);      GNUNET_free (fn);      return -1;    }  GNUNET_free (fn);  error = 0;  ret = 0;  GNUNET_mutex_lock (data->lock);  for (i = 0; i < data->ssize; i++)    {      sec = &data->sections[i];      if (0 > fprintf (fp, "[%s]\n", sec->name))        {          error = 1;          break;        }      for (j = 0; j < sec->size; j++)        {          e = &sec->entries[j];          GNUNET_GE_ASSERT (data->ectx, e->dirty_val == NULL);          if (e->val != NULL)            {              val = GNUNET_malloc (strlen (e->val) * 2 + 1);              strcpy (val, e->val);              while (NULL != (pos = strstr (val, "\n")))                {                  memmove (&pos[2], &pos[1], strlen (&pos[1]));                  pos[0] = '\\';                  pos[1] = 'n';                }              if (0 > fprintf (fp, "%s = %s\n", e->key, val))                {                  error = 1;                  GNUNET_free (val);                  break;                }              GNUNET_free (val);            }        }      if (error != 0)        break;      if (0 > fprintf (fp, "\n"))        {          error = 1;          break;        }    }  if (error != 0)    GNUNET_GE_LOG_STRERROR_FILE (data->ectx,                                 GNUNET_GE_ERROR | GNUNET_GE_USER |                                 GNUNET_GE_IMMEDIATE | GNUNET_GE_BULK |                                 GNUNET_GE_REQUEST, "fprintf", filename);  if (0 != fclose (fp))    {      GNUNET_GE_LOG_STRERROR_FILE (data->ectx,                                   GNUNET_GE_ERROR | GNUNET_GE_USER |                                   GNUNET_GE_ADMIN | GNUNET_GE_IMMEDIATE |                                   GNUNET_GE_BULK | GNUNET_GE_REQUEST,                                   "fclose", filename);      error = 1;    }  if (error == 0)    {      ret = 0;      data->dirty = 0;          /* last write succeeded */    }  else    {      ret = -1;      data->dirty = -1;         /* last write failed */    }  GNUNET_mutex_unlock (data->lock);  return ret;}/** * Call only with lock held! */static GNUNET_GC_Section *findSection (GNUNET_GC_Configuration * data, const char *section){  int i;  for (i = data->ssize - 1; i >= 0; i--)    if (0 == strcmp (section, data->sections[i].name))      return &data->sections[i];  return NULL;}/** * Call only with lock held! */static GNUNET_GC_Entry *findEntry (GNUNET_GC_Configuration * data, const char *section,           const char *key){  int i;  GNUNET_GC_Section *sec;  sec = findSection (data, section);  if (sec == NULL)    return NULL;  for (i = sec->size - 1; i >= 0; i--)    if (0 == strcmp (key, sec->entries[i].key))      return &sec->entries[i];  return NULL;}intGNUNET_GC_set_configuration_value_string (struct GNUNET_GC_Configuration                                          *data,                                          struct GNUNET_GE_Context *ectx,                                          const char *section,                                          const char *option,                                          const char *value){  GNUNET_GC_Section *sec;  GNUNET_GC_Section nsec;  GNUNET_GC_Entry *e;  GNUNET_GC_Entry ne;  int ret;  int i;  GNUNET_mutex_lock (data->lock);  e = findEntry (data, section, option);  if (e == NULL)    {      sec = findSection (data, section);      if (sec == NULL)        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -