Beispiel #1
0
//
// E_ProcessFontFilter
//
// Patch fonts can specify any number of filter objects (at least one is
// required), which have two methods for specifying the lump that belongs
// to a given character or range of characters. The filters use mask strings
// that are C format strings, but the validity of these are checked at load
// by the routine above.
//
static void E_ProcessFontFilter(cfg_t *sec, vfontfilter_t *f)
{
   unsigned int numchars;
   const char *tempstr;
   char *pos = nullptr;
   int tempnum = 0;

   // the filter works in one of two ways:
   // 1. specifies a list of characters to which it applies
   // 2. specifies a range of characters from start to end

   // is it a list?
   if((numchars = cfg_size(sec, ITEM_FILTER_CHARS)) > 0)
   {
      f->chars    = ecalloc(unsigned int *, numchars, sizeof(unsigned int));
      f->numchars = numchars;

      for(unsigned int i = 0; i < numchars; i++)
      {
         pos = nullptr;
         tempstr = cfg_getnstr(sec, ITEM_FILTER_CHARS, i);

         if(strlen(tempstr) > 1)
            tempnum = strtol(tempstr, &pos, 0);

         if(pos && *pos == '\0')
            f->chars[i] = tempnum;
         else
            f->chars[i] = *tempstr;
      }
   }
Beispiel #2
0
int main(int argc, char **argv)
{
    int i;
    cfg_t *cfg = parse_conf(argc > 1 ? argv[1] : "ftp.conf");

    /* print the parsed configuration options */
    if(cfg)
    {
        printf("reverse-dns = %s\n", cfg_getbool(cfg, "reverse-dns") ? "true" : "false");
        printf("passive-mode = %s\n", cfg_getbool(cfg, "passive-mode") ? "true" : "false");
        printf("remote-completion = %s\n", cfg_getbool(cfg, "remote-completion") ? "true" : "false");

        printf("number of bookmarks: %d\n", cfg_size(cfg, "bookmark"));
        for(i = 0; i < cfg_size(cfg, "bookmark"); i++)
        {
            cfg_t *bookmark = cfg_getnsec(cfg, "bookmark", i);
            printf("  bookmark #%d: %s:%s@%s:%ld%s\n", i+1,
                    cfg_getstr(bookmark, "login"),
                    cfg_getstr(bookmark, "password"),
                    cfg_getstr(bookmark, "host"),
                    cfg_getint(bookmark, "port"),
                    cfg_getstr(bookmark, "directory"));
        }

        for(i = 0; i < cfg_size(cfg, "xterm-terminals"); i++)
            printf("xterm-terminal #%d: %s\n", i+1, cfg_getnstr(cfg, "xterm-terminals", i));

        printf("auto-create-bookmark = %ld\n", cfg_getint(cfg, "auto-create-bookmark"));
        cfg_free(cfg);
    }

    return 0;
}
Beispiel #3
0
static void add_div(struct unit *unit, int type, cfg_t *variant)
{
	int ndiv, n, ntxt;

	if (!(ndiv = cfg_size(variant, "div")))
		return;

	ntxt = cfg_size(variant, "txt");
	if (ntxt != ndiv)
		quit("Number of elements for div and txt not equal\n");

	if (!list_empty(&unit->u_div[type])) {
		struct fraction *f, *n;

		list_for_each_entry_safe(f, n, &unit->u_div[type], f_list)
			fraction_free(f);
	}

	for (n = 0; n < ndiv; n++) {
		char *txt;
		float div;

		div = cfg_getnfloat(variant, "div", n);
		txt = cfg_getnstr(variant, "txt", n);

		unit_add_div(unit, type, txt, div);
	}
}
Beispiel #4
0
/* Checks if the file path is configured to be ignored */
static int
file_path_ignore(const char *path)
{
  cfg_t *lib;
  regex_t regex;
  int n;
  int i;
  int ret;

  lib = cfg_getsec(cfg, "library");
  n = cfg_size(lib, "filepath_ignore");

  for (i = 0; i < n; i++)
    {
      ret = regcomp(&regex, cfg_getnstr(lib, "filepath_ignore", i), 0);
      if (ret != 0)
	{
	  DPRINTF(E_LOG, L_SCAN, "Could not compile regex for matching with file path\n");
	  return 0;
	}

      ret = regexec(&regex, path, 0, NULL, 0);
      regfree(&regex);

      if (ret == 0)
	{
	  DPRINTF(E_DBG, L_SCAN, "Regex match: %s\n", path);
	  return 1;
	}
    }

  return 0;
}
Beispiel #5
0
void read_cfg_section(section_t *section, cfg_t *cfg_sec, std::stringstream &errors)
{
   static const char *funcname = "conf::read_cfg_section";

   for (auto &entry : *section)
   {
      char *name = const_cast<char *>(entry.first.c_str());
      bool required = entry.second.is_required();

      switch (entry.second.what_type())
      {
         case val_type::integer:
         {
            integer_t val;
            if (0 == (val = cfg_getint(cfg_sec, name))) {
               if (required) errors << "Required int-option '" << name << "' is not set." << std::endl; }
            else entry.second.set(val);
            break;
         }

         case val_type::string:
         {
            char *val;
            if (nullptr == (val = cfg_getstr(cfg_sec, name))) {
               if (required) errors << "Required str-option '" << name << "' is not set." << std::endl; }
            else entry.second.set(val);
            break;
         }

         case val_type::multistring:
         {
            if (nullptr == cfg_getstr(cfg_sec, name)) {
               if (required) errors << "Required multistr-option '" << name << "' is not set." << std::endl; }
            else
            {
               int count = cfg_size(cfg_sec, name);
               multistring_t strs;

               for (int i = 0; i < count; i++) 
                  strs.push_back(std::move(string_t(cfg_getnstr(cfg_sec, name, i))));
               entry.second.set(strs);
            }
            break;
         }

         case val_type::section:
            read_cfg_section(entry.second.get<conf::section_t *>(), cfg_getsec(cfg_sec, name), errors);
            break;

         case val_type::unknown:
            throw logging::error(funcname, "Val with unknown type in section: %s", name);   
      }
   }
}
Beispiel #6
0
model_access_list * get_model_access_list(const char * filename){

  int i;
  cfg_opt_t * opts = get_opt();
  cfg_t *cfg;

  cfg = cfg_init(opts, CFGF_NONE);
  cfg_parse(cfg, filename);
  
  model_access_list * ma_list = (model_access_list*)malloc(sizeof(model_access_list));

  char *path, *model_list_item, *query_list_item, *model_label;

  path = cfg_getstr(cfg,"model_list_path");

  ma_list->path = (char *)malloc(sizeof(char)*strlen(path));
  strcpy(ma_list->path,path);
  

  for(i=0;i< cfg_size(cfg,"model_list");i++){

    model_list_item = cfg_getnstr(cfg,"model_list",i);
    ma_list->model_access_info[i].model_filename =(char*)malloc(sizeof(char)*strlen(model_list_item));
    strcpy(ma_list->model_access_info[i].model_filename,model_list_item);

    model_label = cfg_getnstr(cfg,"model_label_list",i);
    ma_list->model_access_info[i].model_label =(char*)malloc(sizeof(char)*strlen(model_label));
    strcpy(ma_list->model_access_info[i].model_label,model_label);

    query_list_item=cfg_getnstr(cfg,"query_list",i);
    ma_list->model_access_info[i].query =(char*)malloc(sizeof(char)*strlen(query_list_item));
    strcpy(ma_list->model_access_info[i].query,query_list_item);
  }
  ma_list->size=i;
  
  free(cfg);
  return ma_list;

}
Beispiel #7
0
/* Thread: scan */
static void
bulk_scan(void)
{
  cfg_t *lib;
  int ndirs;
  char *path;
  char *deref;
  time_t start;
  int i;

  start = time(NULL);

  playlists = NULL;
  dirstack = NULL;

  lib = cfg_getsec(cfg, "library");

  ndirs = cfg_size(lib, "directories");
  for (i = 0; i < ndirs; i++)
    {
      path = cfg_getnstr(lib, "directories", i);

      deref = m_realpath(path);
      if (!deref)
	{
	  DPRINTF(E_LOG, L_SCAN, "Skipping library directory %s, could not dereference: %s\n", path, strerror(errno));

	  continue;
	}

      process_directories(deref, F_SCAN_BULK);

      free(deref);

      if (scan_exit)
	return;
    }

  if (playlists)
    process_deferred_playlists();

  if (scan_exit)
    return;

  if (dirstack)
    DPRINTF(E_LOG, L_SCAN, "WARNING: unhandled leftover directories\n");

  DPRINTF(E_DBG, L_SCAN, "Purging old database content\n");
  db_purge_cruft(start);
}
Beispiel #8
0
char* turnserver_cfg_listen_addressv6(void)
{
  size_t nb = cfg_size(g_cfg, "listen_addressv6");

  if(nb)
  {
    size_t l = (size_t)(rand() % nb);
    return cfg_getnstr(g_cfg, "listen_addressv6", l);
  }
  else
  {
    return NULL;
  }
}
/* Thread: scan */
static int
check_speciallib(char *path, const char *libtype)
{
  cfg_t *lib;
  int ndirs;
  int i;

  lib = cfg_getsec(cfg, "library");
  ndirs = cfg_size(lib, libtype);
  for (i = 0; i < ndirs; i++)
    {
      if (strstr(path, cfg_getnstr(lib, libtype, i)))
	return 1;
    }

  return 0;
}
Beispiel #10
0
int
parse_proxy_itrs(cfg_t *cfg, lisp_xtr_t *xtr)
{
    int n,i;
    char *proxy_itr;
    n = cfg_size(cfg, "proxy-itrs");
    for(i = 0; i < n; i++) {
        if ((proxy_itr = cfg_getnstr(cfg, "proxy-itrs", i)) != NULL) {
            if (add_server(proxy_itr, xtr->pitrs)==GOOD){
                OOR_LOG(LDBG_1, "Added %s to proxy-itr list", proxy_itr);
            }else {
                OOR_LOG(LERR, "Can't add %s to proxy-itr list. Discarded ...", proxy_itr);
            }
        }
    }
    return (GOOD);
}
/* Checks if the file extension is in the ignore list */
static int
file_type_ignore(const char *ext)
{
  cfg_t *lib;
  int n;
  int i;

  lib = cfg_getsec(cfg, "library");
  n = cfg_size(lib, "filetypes_ignore");

  for (i = 0; i < n; i++)
    {
      if (strcasecmp(ext, cfg_getnstr(lib, "filetypes_ignore", i)) == 0)
	return 1;
    }

  return 0;
}
Beispiel #12
0
//
// E_CfgListToCommaString
//
// Concatenates all values in a CFGF_LIST CFG_STR option into a single
// string of comma-delimited values.
//
void E_CfgListToCommaString(cfg_t *sec, const char *optname, qstring &output)
{
   unsigned int numopts = cfg_size(sec, optname);
   
   output.clear();

   for(unsigned int i = 0; i < numopts; i++)
   {
      const char *str = cfg_getnstr(sec, optname, i);

      if(str)
         output += str;

      size_t len = output.length();
      if(i != numopts - 1 && len && output[len - 1] != ',')
         output += ',';
   }
}
Beispiel #13
0
/* Thread: scan */
static int
check_compilation(char *path)
{
  cfg_t *lib;
  int ndirs;
  int i;

  lib = cfg_getsec(cfg, "library");
  ndirs = cfg_size(lib, "compilations");

  for (i = 0; i < ndirs; i++)
    {
      if (strstr(path, cfg_getnstr(lib, "compilations", i)))
	return 1;
    }

  return 0;
}
Beispiel #14
0
static void print_system(cfg_t *provider)
{
	size_t i;

	printf("\n");
	printf("system %s\n", cfg_title(provider));
	print_string(provider, "username", 1);
	print_string(provider, "password", 1);

	if (cfg_size(provider, "alias")) {
		printf("  alias ");

		for (i = 0; i < cfg_size(provider, "alias"); i++)
			printf("%s%s", i != 0 ? ", " : "",
			       cfg_getnstr(provider, "alias", i));

		printf("\n");
	}
}
Beispiel #15
0
int main(void)
{
    cfg_opt_t greet_opts[] =
    {
        CFG_STR_LIST("targets", "{World}", CFGF_NONE),
        CFG_INT("repeat", 1, CFGF_NONE),
        CFG_END()
    };
    cfg_opt_t opts[] =
    {
        CFG_SEC("greeting", greet_opts, CFGF_TITLE | CFGF_MULTI),
        CFG_END()
    };
    cfg_t *cfg, *cfg_greet;
    int repeat;
    int i, j;

    cfg = cfg_init(opts, CFGF_NONE);
    cfg_set_validate_func(cfg, "greeting|repeat", validate_unsigned_int);
    if(cfg_parse(cfg, "hello.conf") == CFG_PARSE_ERROR)
        return 1;

    for(j = 0; j < cfg_size(cfg, "greeting"); j++)
    {
        cfg_greet = cfg_getnsec(cfg, "greeting", j);

        repeat = cfg_getint(cfg_greet, "repeat");
        while(repeat--)
        {
            printf("%s", cfg_title(cfg_greet));
            for(i = 0; i < cfg_size(cfg_greet, "targets"); i++)
                printf(", %s", cfg_getnstr(cfg_greet, "targets", i));
            printf("!\n");
        }
    }

    cfg_free(cfg);
    return 0;
}
Beispiel #16
0
/** Load all the plugins given in the configuration file */
void
plugin_load_all(void)
{
  const unsigned int plugins_nb = cfg_size(globalconf.cfg, "plugins");
  if(!plugins_nb)
    return;

  plugin_t *plugin = globalconf.plugins;
  for(unsigned int plugin_n = 0; plugin_n < plugins_nb; plugin_n++)
    {
      plugin_t *new_plugin = plugin_load(cfg_getnstr(globalconf.cfg, "plugins", plugin_n));
      if(!new_plugin)
	continue;

      if(!globalconf.plugins)
	globalconf.plugins = plugin = new_plugin;
      else
	{
	  plugin->next = new_plugin;
	  plugin->next->prev = plugin;
	  plugin = plugin->next;
	}
    }
}
/* Thread: scan */
static void
bulk_scan(int flags)
{
  cfg_t *lib;
  int ndirs;
  char *path;
  char *deref;
  time_t start;
  time_t end;
  int i;

  start = time(NULL);

  playlists = NULL;
  dirstack = NULL;

  lib = cfg_getsec(cfg, "library");

  ndirs = cfg_size(lib, "directories");
  for (i = 0; i < ndirs; i++)
    {
      path = cfg_getnstr(lib, "directories", i);

      deref = m_realpath(path);
      if (!deref)
	{
	  DPRINTF(E_LOG, L_SCAN, "Skipping library directory %s, could not dereference: %s\n", path, strerror(errno));

	  /* Assume dir is mistakenly not mounted, so just disable everything and update timestamps */
	  db_file_disable_bymatch(path, "", 0);
	  db_pl_disable_bymatch(path, "", 0);

	  db_file_ping_bymatch(path, 1);
	  db_pl_ping_bymatch(path, 1);

	  continue;
	}

      counter = 0;
      db_transaction_begin();
      process_directories(deref, flags);
      db_transaction_end();

      free(deref);

      if (scan_exit)
	return;
    }

  if (!(flags & F_SCAN_FAST) && playlists)
    process_deferred_playlists();

  if (scan_exit)
    return;

  if (dirstack)
    DPRINTF(E_LOG, L_SCAN, "WARNING: unhandled leftover directories\n");

  end = time(NULL);

  if (flags & F_SCAN_FAST)
    {
      DPRINTF(E_LOG, L_SCAN, "Bulk library scan completed in %.f sec (with file scan disabled)\n", difftime(end, start));
    }
  else
    {
      /* Protect spotify from the imminent purge if rescanning */
      if (flags & F_SCAN_RESCAN)
	{
	  db_file_ping_bymatch("spotify:", 0);
	  db_pl_ping_bymatch("spotify:", 0);
	}

      DPRINTF(E_DBG, L_SCAN, "Purging old database content\n");
      db_purge_cruft(start);

      DPRINTF(E_LOG, L_SCAN, "Bulk library scan completed in %.f sec\n", difftime(end, start));

      DPRINTF(E_DBG, L_SCAN, "Running post library scan jobs\n");
      db_hook_post_scan();
    }
}
Beispiel #18
0
int turnserver_cfg_parse(const char* file, struct list_head* denied_address_list)
{
  int ret = 0;
  size_t i = 0;
  size_t nb = 0;
  g_cfg = cfg_init(opts, CFGF_NONE);

  ret = cfg_parse(g_cfg, file);

  if(ret == CFG_FILE_ERROR)
  {
    fprintf(stderr, "Cannot find configuration file %s\n", file);
    return -1;
  }
  else if(ret == CFG_PARSE_ERROR)
  {
    fprintf(stderr, "Parse error in configuration file %s\n", file);
    return -2;
  }

  /* check IPv4 listen addresses to be valid IPv4 ones */
  nb = cfg_size(g_cfg, "listen_address");
  for(i = 0 ; i < nb ; i++)
  {
    struct sockaddr_storage addr;
    char* str = cfg_getnstr(g_cfg, "listen_address", i);
    if(inet_pton(AF_INET, str, &addr) != 1)
    {
      return -2;
    }
  }

  /* check IPv6 listen addresses to be valid IPv6 ones */
  nb = cfg_size(g_cfg, "listen_addressv6");
  for(i = 0 ; i < nb ; i++)
  {
    struct sockaddr_storage addr;
    char* str = cfg_getnstr(g_cfg, "listen_addressv6", i);
    if(inet_pton(AF_INET6, str, &addr) != 1)
    {
      return -2;
    }
  }

  /* add the denied address */
  nb = cfg_size(g_cfg, "denied_address");
  for(i = 0 ; i < nb ; i++)
  {
    cfg_t* ad = cfg_getnsec(g_cfg, "denied_address", i);
    char* addr = cfg_getstr(ad, "address");
    uint8_t mask = cfg_getint(ad, "mask");
    uint16_t port = cfg_getint(ad, "port");
    struct denied_address* denied = NULL;

    if(!(denied = malloc(sizeof(struct denied_address))))
    {
      return -3;
    }

    memset(denied, 0x00, sizeof(struct denied_address));
    denied->mask = mask;
    denied->port = port;

    if(inet_pton(AF_INET, addr, denied->addr) != 1)
    {
      /* try IPv6 */
      if(inet_pton(AF_INET6, addr, denied->addr) != 1)
      {
        free(denied);
        return -2;
      }
      else
      {
        /* check mask */
        if(mask > 128)
        {
          free(denied);
          return -2;
        }
        denied->family = AF_INET6;
      }
    }
    else
    {
      /* mask check */
      if(mask > 24)
      {
        free(denied);
        return -2;
      }
      denied->family = AF_INET;
    }

    /* add to the list */
    LIST_ADD(&denied->list, denied_address_list);
  }

  return 0;
}
Beispiel #19
0
/**
 * @brief parses and creates a new ssl_cfg_t resource
 *
 * @param cfg the libconfuse structure for the ssl opts
 *
 * @return evhtp_ssl_cfg_t * on success, NULL on error.
 */
evhtp_ssl_cfg_t *
ssl_cfg_parse(cfg_t * cfg) {
    evhtp_ssl_cfg_t * scfg;
    long              ssl_opts        = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1;
    int               ssl_verify_mode = 0;
    int               proto_on_count;
    int               proto_off_count;
    int               i;
    struct stat       file_stat;

    if (cfg == NULL) {
        return NULL;
    }

    if (cfg_getbool(cfg, "enabled") == cfg_false) {
        return NULL;
    }

    if (!(scfg = ssl_cfg_new())) {
        return NULL;
    }

    if (cfg_getstr(cfg, "cert")) {
        scfg->pemfile = strdup(cfg_getstr(cfg, "cert"));
        if (stat(scfg->pemfile, &file_stat) != 0) {
            fprintf(stderr, "Cannot find SSL cert file '%s'\n", scfg->pemfile);
            exit(EXIT_FAILURE);
        }
    }

    if (cfg_getstr(cfg, "key")) {
        scfg->privfile = strdup(cfg_getstr(cfg, "key"));
        if (stat(scfg->privfile, &file_stat) != 0) {
            fprintf(stderr, "Cannot find SSL key file '%s'\n", scfg->privfile);
            exit(EXIT_FAILURE);
        }
    }

    if (cfg_getstr(cfg, "ca")) {
        scfg->cafile = strdup(cfg_getstr(cfg, "ca"));
        if (stat(scfg->cafile, &file_stat) != 0) {
            fprintf(stderr, "Cannot find SSL ca file '%s'\n", scfg->cafile);
            exit(EXIT_FAILURE);
        }
    }

    if (cfg_getstr(cfg, "capath")) {
        scfg->capath = strdup(cfg_getstr(cfg, "capath"));
        if (stat(scfg->capath, &file_stat) != 0) {
            fprintf(stderr, "Cannot find SSL capath file '%s'\n", scfg->capath);
            exit(EXIT_FAILURE);
        }
    }

    if (cfg_getstr(cfg, "ciphers")) {
        scfg->ciphers = strdup(cfg_getstr(cfg, "ciphers"));
    }

    if (cfg_getbool(cfg, "verify-peer") == cfg_true) {
        ssl_verify_mode |= SSL_VERIFY_PEER;
    }

    if (cfg_getbool(cfg, "enforce-peer-cert") == cfg_true) {
        ssl_verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
    }

    if (ssl_verify_mode != 0) {
        scfg->verify_peer        = ssl_verify_mode;
        scfg->verify_depth       = cfg_getint(cfg, "verify-depth");
        scfg->x509_verify_cb     = ssl_x509_verifyfn;
        scfg->x509_chk_issued_cb = NULL;
    }

    if (cfg_getbool(cfg, "cache-enabled") == cfg_true) {
        scfg->scache_type    = evhtp_ssl_scache_type_internal;
        scfg->scache_size    = cfg_getint(cfg, "cache-size");
        scfg->scache_timeout = cfg_getint(cfg, "cache-timeout");
    }

    proto_on_count  = cfg_size(cfg, "protocols-on");
    proto_off_count = cfg_size(cfg, "protocols-off");

    for (i = 0; i < proto_on_count; i++) {
        const char * proto_str = cfg_getnstr(cfg, "protocols-on", i);

        if (!strcasecmp(proto_str, "SSLv2")) {
            ssl_opts &= ~SSL_OP_NO_SSLv2;
        } else if (!strcasecmp(proto_str, "SSLv3")) {
            ssl_opts &= ~SSL_OP_NO_SSLv3;
        } else if (!strcasecmp(proto_str, "TLSv1")) {
            ssl_opts &= ~SSL_OP_NO_TLSv1;
        } else if (!strcasecmp(proto_str, "ALL")) {
            ssl_opts = 0;
        }
    }

    for (i = 0; i < proto_off_count; i++) {
        const char * proto_str = cfg_getnstr(cfg, "protocols-off", i);

        if (!strcasecmp(proto_str, "SSLv2")) {
            ssl_opts |= SSL_OP_NO_SSLv2;
        } else if (!strcasecmp(proto_str, "SSLv3")) {
            ssl_opts |= SSL_OP_NO_SSLv3;
        } else if (!strcasecmp(proto_str, "TLSv1")) {
            ssl_opts |= SSL_OP_NO_TLSv1;
        } else if (!strcasecmp(proto_str, "ALL")) {
            ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1;
        }
    }

    scfg->ssl_ctx_timeout = cfg_getint(cfg, "context-timeout");
    scfg->ssl_opts        = ssl_opts;

    if (cfg_getsec(cfg, "crl")) {
        ssl_crl_cfg_t * crl_config;
        cfg_t         * crl_cfg;

        crl_cfg = cfg_getsec(cfg, "crl");
        assert(crl_cfg != NULL);

        if (!(crl_config = calloc(sizeof(ssl_crl_cfg_t), 1))) {
            fprintf(stderr, "Could not allocate crl cfg %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }

        if (cfg_getstr(crl_cfg, "file")) {
            crl_config->filename = strdup(cfg_getstr(crl_cfg, "file"));

            if (stat(crl_config->filename, &file_stat) == -1 || !S_ISREG(file_stat.st_mode)) {
                fprintf(stderr, "Cannot find CRL file '%s'\n", crl_config->filename);
                exit(EXIT_FAILURE);
            }
        }

        if (cfg_getstr(crl_cfg, "dir")) {
            crl_config->dirname = strdup(cfg_getstr(crl_cfg, "dir"));

            if (stat(crl_config->dirname, &file_stat) != 0 || !S_ISDIR(file_stat.st_mode)) {
                fprintf(stderr, "Cannot find CRL directory '%s'\n", crl_config->dirname);
                exit(EXIT_FAILURE);
            }
        }

        crl_config->reload_timer.tv_sec  = cfg_getnint(crl_cfg, "reload", 0);
        crl_config->reload_timer.tv_usec = cfg_getnint(crl_cfg, "reload", 1);

        /* at the moment evhtp does not give us an area where we can store this
         * type of information without breaking the configuration structure. But
         * it does have an optional user-supplied arguments, which we use here
         * to store our CRL configuration.
         */
        scfg->args = (void *)crl_config;
    }

    return scfg;
} /* ssl_cfg_parse */
Beispiel #20
0
DLLIMPORT char *cfg_getstr(cfg_t *cfg, const char *name)
{
    return cfg_getnstr(cfg, name, 0);
}
Beispiel #21
0
int
configure_tunnel_router(cfg_t *cfg, lisp_xtr_t *xtr, shash_t *lcaf_ht)
{
    int i,n,ret;
    char *map_resolver;
    char *encap;
    mapping_t *mapping;

    /* FWD POLICY STRUCTURES */
    xtr->fwd_policy = fwd_policy_class_find("flow_balancing");
    xtr->fwd_policy_dev_parm = xtr->fwd_policy->new_dev_policy_inf(ctrl_dev,NULL);

    if ((encap = cfg_getstr(cfg, "encapsulation")) != NULL) {
        if (strcmp(encap, "LISP") == 0) {
            xtr->encap_type = ENCP_LISP;
        }else if (strcmp(encap, "VXLAN-GPE") == 0){
            xtr->encap_type = ENCP_VXLAN_GPE;
        }else{
            OOR_LOG(LERR, "Unknown encapsulation type: %s",encap);
            return (BAD);
        }
    }

    /* RETRIES */
    ret = cfg_getint(cfg, "map-request-retries");
    xtr->map_request_retries = (ret != 0) ? ret : DEFAULT_MAP_REQUEST_RETRIES;


    /* RLOC PROBING CONFIG */
    cfg_t *dm = cfg_getnsec(cfg, "rloc-probing", 0);
    if (dm != NULL) {
        xtr->probe_interval = cfg_getint(dm, "rloc-probe-interval");
        xtr->probe_retries = cfg_getint(dm, "rloc-probe-retries");
        xtr->probe_retries_interval = cfg_getint(dm,
                "rloc-probe-retries-interval");

        validate_rloc_probing_parameters(&xtr->probe_interval,
                &xtr->probe_retries, &xtr->probe_retries_interval);
    } else {
        OOR_LOG(LDBG_1, "Configuration file: RLOC probing not defined. "
                "Setting default values: RLOC Probing Interval: %d sec.",
                RLOC_PROBING_INTERVAL);
        xtr->probe_interval = RLOC_PROBING_INTERVAL;
        xtr->probe_retries = DEFAULT_RLOC_PROBING_RETRIES;
        xtr->probe_retries_interval = DEFAULT_RLOC_PROBING_RETRIES_INTERVAL;

    }


    /* MAP-RESOLVER CONFIG  */
    n = cfg_size(cfg, "map-resolver");
    for(i = 0; i < n; i++) {
        if ((map_resolver = cfg_getnstr(cfg, "map-resolver", i)) != NULL) {
            if (add_server(map_resolver, xtr->map_resolvers) == GOOD){
                OOR_LOG(LDBG_1, "Added %s to map-resolver list", map_resolver);
            }else{
                OOR_LOG(LCRIT,"Can't add %s Map Resolver.",map_resolver);
            }
        }
    }

    /* STATIC MAP-CACHE CONFIG */
    n = cfg_size(cfg, "static-map-cache");
    for (i = 0; i < n; i++) {
        cfg_t *smc = cfg_getnsec(cfg, "static-map-cache", i);
        mapping = parse_mapping(smc,&(xtr->super),lcaf_ht,FALSE);

        if (mapping == NULL){
            OOR_LOG(LERR, "Can't add static Map Cache entry with EID prefix %s. Discarded ...",
                    cfg_getstr(smc, "eid-prefix"));
            continue;
        }
        if (mcache_lookup_exact(xtr->map_cache, mapping_eid(mapping)) == NULL){
            if (tr_mcache_add_static_mapping(xtr, mapping) == GOOD){
                OOR_LOG(LDBG_1, "Added static Map Cache entry with EID prefix %s in the database.",
                        lisp_addr_to_char(mapping_eid(mapping)));
            }else{
                OOR_LOG(LERR, "Can't add static Map Cache entry with EID prefix %s. Discarded ...",
                        mapping_eid(mapping));
                mapping_del(mapping);
            }
        }else{
            OOR_LOG(LERR, "Configuration file: Duplicated static Map Cache entry with EID prefix %s."
                    "Discarded ...",cfg_getstr(smc, "eid-prefix"));
            mapping_del(mapping);
            continue;
        }
        continue;
    }
    return (GOOD);
}
Beispiel #22
0
/**
 * @brief parses a single rule from a server { vhost { rules { } } } config
 *
 * @param cfg
 *
 * @return
 */
rule_cfg_t *
rule_cfg_parse(cfg_t * cfg) {
    rule_cfg_t * rcfg;
    const char * rname;
    int          i;

    assert(cfg != NULL);

    rname      = cfg_title(cfg);
    assert(rname != NULL);

    rcfg       = rule_cfg_new();
    assert(cfg != NULL);

    rcfg->name = strdup(rname);
    assert(rcfg->name != NULL);

    if (cfg_getstr(cfg, "uri-match")) {
        rcfg->type     = rule_type_exact;
        rcfg->matchstr = strdup(cfg_getstr(cfg, "uri-match"));
    } else if (cfg_getstr(cfg, "uri-gmatch")) {
        rcfg->type     = rule_type_glob;
        rcfg->matchstr = strdup(cfg_getstr(cfg, "uri-gmatch"));
    } else if (cfg_getstr(cfg, "uri-rmatch")) {
        rcfg->type     = rule_type_regex;
        rcfg->matchstr = strdup(cfg_getstr(cfg, "uri-rmatch"));
    } else {
        fprintf(stderr, "Rule %s has no match statement!\n", rname);
        exit(EXIT_FAILURE);
    }

    rcfg->lb_method      = lbstr_to_lbtype(cfg_getstr(cfg, "lb-method"));
    rcfg->headers        = headers_cfg_parse(cfg_getsec(cfg, "headers"));
    rcfg->passthrough    = cfg_getbool(cfg, "passthrough");
    rcfg->allow_redirect = cfg_getbool(cfg, "allow-redirect");

    if (cfg_getopt(cfg, "upstream-read-timeout")) {
        rcfg->up_read_timeout.tv_sec  = cfg_getnint(cfg, "upstream-read-timeout", 0);
        rcfg->up_read_timeout.tv_usec = cfg_getnint(cfg, "upstream-read-timeout", 1);
        rcfg->has_up_read_timeout     = 1;
    }

    if (cfg_getopt(cfg, "upstream-write-timeout")) {
        rcfg->up_write_timeout.tv_sec  = cfg_getnint(cfg, "upstream-write-timeout", 0);
        rcfg->up_write_timeout.tv_usec = cfg_getnint(cfg, "upstream-write-timeout", 1);
        rcfg->has_up_write_timeout     = 1;
    }

    for (i = 0; i < cfg_size(cfg, "downstreams"); i++) {
        lztq_elem * elem;
        char      * ds_name;

        ds_name = strdup(cfg_getnstr(cfg, "downstreams", i));
        assert(ds_name != NULL);

        elem    = lztq_append(rcfg->downstreams, ds_name, strlen(ds_name), free);
        assert(elem != NULL);
    }

    if (rcfg->allow_redirect != 0 && cfg_size(cfg, "redirect-filter")) {
        /*
         * if the redirect option is enabled, optionally an administrator can
         * add a list of allowed hosts it may communicate with.
         */
        int n_filters;

        n_filters = cfg_size(cfg, "redirect-filter");
        assert(n_filters > 0);

        rcfg->redirect_filter = lztq_new();
        assert(rcfg->redirect_filter != NULL);

        for (i = 0; i < n_filters; i++) {
            lztq_elem * elem;
            char      * host_ent;

            host_ent = strdup(cfg_getnstr(cfg, "redirect-filter", i));
            assert(host_ent != NULL);

            elem     = lztq_append(rcfg->redirect_filter, host_ent,
                                   strlen(host_ent), free);
            assert(elem != NULL);
        }
    }

    return rcfg;
} /* rule_cfg_parse */
Beispiel #23
0
gfs_t *G_LoadGFS(const char *filename)
{
   static bool loaded = false;
   int i;
   cfg_t *cfg;

   // only one GFS can be loaded per session
   if(loaded)
      return NULL;

   cfg = cfg_init(gfs_opts, CFGF_NOCASE);

   cfg_set_error_function(cfg, E_ErrorCB);

   if(cfg_parse(cfg, filename))
      I_Error("G_LoadGFS: failed to parse GFS file\n");

   // count number of options
   gfs.numwads = cfg_size(cfg, SEC_WADFILE);
   gfs.numdehs = cfg_size(cfg, SEC_DEHFILE);
   gfs.numcsc  = cfg_size(cfg, SEC_CSCFILE);

   if(gfs.numwads)
      gfs.wadnames = ecalloc(char **, gfs.numwads, sizeof(char *));

   if(gfs.numdehs)
      gfs.dehnames = ecalloc(char **, gfs.numdehs, sizeof(char *));

   if(gfs.numcsc)
      gfs.cscnames = ecalloc(char **, gfs.numcsc,  sizeof(char *));

   // load wads, dehs, csc
   for(i = 0; i < gfs.numwads; i++)
   {
      const char *str = cfg_getnstr(cfg, SEC_WADFILE, i);

      gfs.wadnames[i] = estrdup(str);
   }
   for(i = 0; i < gfs.numdehs; i++)
   {
      const char *str = cfg_getnstr(cfg, SEC_DEHFILE, i);
      
      gfs.dehnames[i] = estrdup(str);
   }
   for(i = 0; i < gfs.numcsc; i++)
   {
      const char *str = cfg_getnstr(cfg, SEC_CSCFILE, i);

      gfs.cscnames[i] = estrdup(str);
   }

   // haleyjd 07/05/03: support root EDF specification
   if(cfg_size(cfg, SEC_EDFFILE) >= 1)
   {
      const char *str = cfg_getstr(cfg, SEC_EDFFILE);

      gfs.edf = estrdup(str);

      gfs.hasEDF = true;
   }

   // haleyjd 04/16/03: support iwad specification for end-users
   // (this is not useful to mod authors, UNLESS their mod happens
   // to be an IWAD file ;)
   if(cfg_size(cfg, SEC_IWAD) >= 1)
   {
      const char *str = cfg_getstr(cfg, SEC_IWAD);

      gfs.iwad = estrdup(str);

      gfs.hasIWAD = true;
   }

   // haleyjd 04/16/03: basepath support
   if(cfg_size(cfg, SEC_BASEPATH) >= 1)
   {
      const char *str = cfg_getstr(cfg, SEC_BASEPATH);

      gfs.filepath = estrdup(str);
   }
   else
   {
      gfs.filepath = emalloc(char *, strlen(filename) + 1);
      M_GetFilePath(filename, gfs.filepath, strlen(filename));
   }

   cfg_free(cfg);

   loaded = true;

   return &gfs;
}
Beispiel #24
0
/**
* Main function of the user app that parses configuration file and sends it to
* NAT64 kernel module.
*
* @param argc	Qty of arguments in command line call.
* @param argv	Array of arguments in command line call.
*/
int main(int argc, char *argv[])
{
	struct stat sb; // To check if config file exist.
	struct in_addr iaddrn, iaddrf, iaddrl;      // To validate IP addresses
    struct in6_addr i6addrf;   			// also
    cfg_t *cfg, *cfg_ipv4, *cfg_ipv6;
	const char *sect_name;
	char *addr_first, *addr_last;
    unsigned char addr_maskbits;
    int port_first, port_last;
    char which[sizeof("ABC")];
    char str[INET_ADDRSTRLEN];
    
    struct config_struct cs;

	struct nl_sock *nls;
	int ret;

	int i = 0;
	struct ipv6_prefixes **ipv6_pref = NULL;
	unsigned char ipv6_pref_qty;
	char ipv6_def_prefix64[sizeof("1111:2222:3333:4444:5555:6666::/128")];
	char *ipv6_buf;  
	char *ipv6_check_addr; 
	char *ipv6_check_maskbits; 

	if (argc != 2)
	{
		printf("Usage: %s <config-file>\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	if ( stat(argv[1], &sb) == -1 )
	{
		printf("Error: Can not open configuration file: %s\n", argv[1]);
		exit(EXIT_FAILURE);
	}

	// Load default configuration values for each config option, just in case 
	// they were not included in the config file.
    cfg_opt_t ipv4_opts[] =
    {
        CFG_STR("ipv4_addr_net", IPV4_DEF_NET, CFGF_NONE), 
        CFG_INT("ipv4_addr_net_mask_bits", IPV4_DEF_MASKBITS, CFGF_NONE), 
        CFG_STR("ipv4_pool_range_first", IPV4_DEF_POOL_FIRST, CFGF_NONE), 
        CFG_STR("ipv4_pool_range_last", IPV4_DEF_POOL_LAST, CFGF_NONE), 
        CFG_INT("ipv4_tcp_port_range_first", IPV4_DEF_TCP_PORTS_FIRST, CFGF_NONE), 
        CFG_INT("ipv4_tcp_port_range_last", IPV4_DEF_TCP_PORTS_LAST, CFGF_NONE), 
        CFG_INT("ipv4_udp_port_range_first", IPV4_DEF_UDP_PORTS_FIRST, CFGF_NONE), 
        CFG_INT("ipv4_udp_port_range_last", IPV4_DEF_UDP_PORTS_LAST, CFGF_NONE), 
        CFG_END()
    };

	// Load default configuration values for each config option, just in case 
	// they were not included in the config file.
	sprintf(ipv6_def_prefix64, "%s/%d", IPV6_DEF_PREFIX, IPV6_DEF_MASKBITS );
	cfg_opt_t ipv6_opts[] =
    {
        CFG_STR_LIST("ipv6_net_prefixes", ipv6_def_prefix64, CFGF_NONE), 
        CFG_INT("ipv6_tcp_port_range_first", IPV6_DEF_TCP_PORTS_FIRST, CFGF_NONE), 
        CFG_INT("ipv6_tcp_port_range_last", IPV6_DEF_TCP_PORTS_LAST, CFGF_NONE), 
        CFG_INT("ipv6_udp_port_range_first", IPV6_DEF_UDP_PORTS_FIRST, CFGF_NONE), 
        CFG_INT("ipv6_udp_port_range_last", IPV6_DEF_UDP_PORTS_LAST, CFGF_NONE), 
		CFG_END()
    };
    // Define two sections in config file
    cfg_opt_t opts[] =
    {
        CFG_SEC("ipv4", ipv4_opts, CFGF_NONE),
        CFG_SEC("ipv6", ipv6_opts, CFGF_NONE),
        CFG_END()
    };

	// Parse config file
    cfg = cfg_init(opts, CFGF_NONE);
    if(cfg_parse(cfg, argv[1]) == CFG_PARSE_ERROR)
	{
		printf("Error parsing configuration file: %s\n", argv[1]);
        exit_error_conf(cfg);
	}

	/*
	 * Loading IPv4 configuration
	 *
	 */
	{
        cfg_ipv4 = cfg_getsec(cfg, "ipv4");

		sect_name = cfg_name(cfg_ipv4);
		printf ("Section: %s\n", sect_name);

		// Validate IPv4 pool address
		addr_first = cfg_getstr(cfg_ipv4, "ipv4_addr_net");
        if ( convert_ipv4_addr(addr_first, &iaddrn) == EXIT_FAILURE )	
		{
			printf("Error: Invalid IPv4 address net: %s\n", addr_first);
			exit_error_conf(cfg);
		}
		// Validate netmask bits
        addr_maskbits = cfg_getint(cfg_ipv4, "ipv4_addr_net_mask_bits");
        if ( validate_ipv4_netmask_bits(addr_maskbits) == EXIT_FAILURE )
        {
            printf("Error: Bad IPv4 network mask bits value: %d\n", addr_maskbits);
			exit_error_conf(cfg);
        }
        // Store values in config struct
		cs.ipv4_addr_net = iaddrn;
        cs.ipv4_addr_net_mask_bits = addr_maskbits;
		printf("\tPool Network: %s/%d\n", addr_first, addr_maskbits);
		
		// Validate pool addresses range
		addr_first = cfg_getstr(cfg_ipv4, "ipv4_pool_range_first");
        addr_last = cfg_getstr(cfg_ipv4, "ipv4_pool_range_last");
		if ( convert_ipv4_addr(addr_first, &iaddrf) == EXIT_FAILURE )	// Validate ipv4 addr
		{
			printf("Error: Malformed ipv4_pool_range_first: %s\n", addr_first);
			exit_error_conf(cfg);
		}
		if ( convert_ipv4_addr(addr_last, &iaddrl) == EXIT_FAILURE  )	// Validate ipv4 addr
		{
			printf("Error: Malformed ipv4_pool_range_last: %s\n", addr_last);
			exit_error_conf(cfg);
		}
		if (  validate_ipv4_pool_range(&iaddrn, addr_maskbits, &iaddrf, &iaddrl) == EXIT_FAILURE )	// Validate that: first < last
		{
			printf("Error: Pool addresses badly defined.\n");
			exit_error_conf(cfg);
		}
		// Store values in config struct
        cs.ipv4_pool_range_first = iaddrf;
        cs.ipv4_pool_range_last = iaddrl;
        inet_ntop(AF_INET, &(iaddrf.s_addr), str, INET_ADDRSTRLEN);
		printf("\t\t- First address: %s\n", str);
        inet_ntop(AF_INET, &(iaddrl.s_addr), str, INET_ADDRSTRLEN);
		printf("\t\t- Last address: %s\n", str);
        
        // Validate port ranges
        port_first = cfg_getint(cfg_ipv4, "ipv4_tcp_port_range_first");
        port_last = cfg_getint(cfg_ipv4, "ipv4_tcp_port_range_last");
        sprintf(which, "TCP");
        if ( validate_ports_range(port_first, port_last) == EXIT_FAILURE )
        {
            //~ printf("Error: Invalid first %s port: %d\n", which, port_first);
            printf("Error: Invalid %s ports range.\n", which);
            exit_error_conf(cfg);
        }
        cs.ipv4_tcp_port_first = port_first;
        cs.ipv4_tcp_port_last = port_last;
		printf("\t%s pool port range: %d-%d\n", which, port_first, port_last);
		//
        port_first = cfg_getint(cfg_ipv4, "ipv4_udp_port_range_first");
        port_last = cfg_getint(cfg_ipv4, "ipv4_udp_port_range_last");
        sprintf(which, "UDP");
       if ( validate_ports_range(port_first, port_last) == EXIT_FAILURE )
        {
            printf("Error: Invalid %s ports range.\n", which);
            exit_error_conf(cfg);
        }
        cs.ipv4_udp_port_first = port_first;
        cs.ipv4_udp_port_last = port_last;
		printf("\t%s pool port range: %d-%d\n", which, port_first, port_last);
		printf ("\n" );
    }
	
    /*
     * Loading IPv6 configuration
     *
     */
	{
        cfg_ipv6 = cfg_getsec(cfg, "ipv6");

		sect_name = cfg_name(cfg_ipv6);
        
		printf ("Section: %s\n", sect_name );
        
        // Get number of IPv6 prefixes.
        ipv6_pref_qty = cfg_size(cfg_ipv6, "ipv6_net_prefixes"); 
        // Allocate memory for the array of prefixes.
        ipv6_pref = (struct ipv6_prefixes **) malloc(ipv6_pref_qty * sizeof(struct ipv6_prefixes *));
        for(i = 0; i < ipv6_pref_qty; i++)
        {
			// Split prefix and netmask bits
			ipv6_buf = cfg_getnstr(cfg_ipv6, "ipv6_net_prefixes", i);
			ipv6_check_addr = strtok(ipv6_buf, "/");
			ipv6_check_maskbits = strtok(NULL, "/");
			
			// Validate IPv6 addr
			if ( convert_ipv6_addr(ipv6_check_addr, &i6addrf) == EXIT_FAILURE )	
			{
				printf("Error: Invalid IPv6 address net: %s\n", ipv6_check_addr);
				exit_error_conf(cfg);
			}
			// Validate netmask bits
			addr_maskbits = atoi(ipv6_check_maskbits);
			if ( validate_ipv6_netmask_bits(addr_maskbits) == EXIT_FAILURE )
			{
				printf("Error: Bad IPv6 network mask bits value: %d\n", addr_maskbits);
				exit_error_conf(cfg);
			}
			
			// Allocate memory for each IPv6 prefix
			ipv6_pref[i] = (struct ipv6_prefixes *) malloc(sizeof(struct ipv6_prefixes));
			ipv6_pref[i]->addr = (i6addrf);
			ipv6_pref[i]->maskbits = addr_maskbits;
        }
        // Store prefixes in the config struct
        cs.ipv6_net_prefixes = ipv6_pref;
        cs.ipv6_net_prefixes_qty = ipv6_pref_qty;
			
               
        // Validate port ranges
        port_first = cfg_getint(cfg_ipv6, "ipv6_tcp_port_range_first");
        port_last = cfg_getint(cfg_ipv6, "ipv6_tcp_port_range_last");
        sprintf(which, "TCP");
		if ( validate_ports_range(port_first, port_last) == EXIT_FAILURE )
        {
            printf("Error: Invalid %s ports range.\n", which);
            exit_error_conf(cfg);
        }
        cs.ipv6_tcp_port_range_first = port_first;
        cs.ipv6_tcp_port_range_last = port_last;
		printf("\t%s pool port range: %d-%d\n", which, port_first, port_last);
		//
        port_first = cfg_getint(cfg_ipv6, "ipv6_udp_port_range_first");
        port_last = cfg_getint(cfg_ipv6, "ipv6_udp_port_range_last");
        sprintf(which, "UDP");
		if ( validate_ports_range(port_first, port_last) == EXIT_FAILURE )
        {
            printf("Error: Invalid %s ports range.\n", which);
            exit_error_conf(cfg);
        }
        cs.ipv6_udp_port_range_first = port_first;
        cs.ipv6_udp_port_range_last = port_last;
		printf("\t%s pool port range: %d-%d\n", which, port_first, port_last);
        
		printf ("\n" );
    }

	cfg_free(cfg);

    /* We got the configuration structure, now send it to the module
     * using netlink sockets. */

    // Reserve memory for netlink socket
    nls = nl_socket_alloc();
    if (!nls) {
        printf("bad nl_socket_alloc\n");
        return EXIT_FAILURE;
    }

	// Bind and connect the socket to kernel
    ret = nl_connect(nls, NETLINK_USERSOCK);
    if (ret < 0) {
        nl_perror(ret, "nl_connect");
        nl_socket_free(nls);
        return EXIT_FAILURE;
    }

	// Send socket to module
    ret = nl_send_simple(nls, MSG_TYPE_CONF, 0, &(cs), sizeof(cs));
    if (ret < 0) {
        nl_perror(ret, "nl_send_simple");
        printf("Error sending message, is module loaded?\n");
        nl_close(nls);
        nl_socket_free(nls);
        return EXIT_FAILURE;
    } else {        
	    printf("Message sent (%d bytes):\n", ret);
        //print_nat64_run_conf(nrc);
    }
		
    nl_close(nls);
    nl_socket_free(nls);
    
    exit(EXIT_SUCCESS);
}
Beispiel #25
0
vhost_cfg_t *
vhost_cfg_parse(cfg_t * cfg) {
    vhost_cfg_t * vcfg;
    cfg_t       * log_cfg;
    cfg_t       * req_log_cfg;
    cfg_t       * err_log_cfg;
    cfg_t       * hdr_cfg;
    cfg_t       * default_rule_cfg;
    int           i;
    int           res;

    vcfg              = vhost_cfg_new();
    assert(vcfg != NULL);

    vcfg->server_name = strdup(cfg_title(cfg));
    vcfg->ssl_cfg     = ssl_cfg_parse(cfg_getsec(cfg, "ssl"));

    for (i = 0; i < cfg_size(cfg, "rule"); i++) {
        lztq_elem  * elem;
        rule_cfg_t * rule;

        if (!(rule = rule_cfg_parse(cfg_getnsec(cfg, "rule", i)))) {
            return NULL;
        }

        elem = lztq_append(vcfg->rule_cfgs, rule, sizeof(rule), rule_cfg_free);
        assert(elem != NULL);
    }

    for (i = 0; i < cfg_size(cfg, "aliases"); i++) {
        lztq_elem * elem;
        char      * name;

        assert(cfg_getnstr(cfg, "aliases", i) != NULL);

        name = strdup(cfg_getnstr(cfg, "aliases", i));
        assert(name != NULL);

        elem = lztq_append(vcfg->aliases, name, strlen(name), free);
        assert(elem != NULL);
    }

    if (cfg_size(cfg, "strip-headers")) {
        vcfg->strip_hdrs = lztq_new();
        assert(vcfg->strip_hdrs != NULL);

        for (i = 0; i < cfg_size(cfg, "strip-headers"); i++) {
            lztq_elem * elem;
            char      * hdr_name;

            assert(cfg_getnstr(cfg, "strip-headers", i) != NULL);

            hdr_name = strdup(cfg_getnstr(cfg, "strip-headers", i));
            assert(hdr_name != NULL);

            elem     = lztq_append(vcfg->strip_hdrs, hdr_name, strlen(hdr_name), free);
            assert(elem != NULL);
        }
    }


    log_cfg = cfg_getsec(cfg, "logging");
    hdr_cfg = cfg_getsec(cfg, "headers");

    if (log_cfg) {
        vcfg->req_log = logger_cfg_parse(cfg_getsec(log_cfg, "request"));
        vcfg->err_log = logger_cfg_parse(cfg_getsec(log_cfg, "error"));
    }

    if (hdr_cfg) {
        vcfg->headers = headers_cfg_parse(hdr_cfg);
    }

    return vcfg;
} /* vhost_cfg_parse */
Beispiel #26
0
static int
artwork_get_dir_image(char *path, int isdir, int max_w, int max_h, int format, struct evbuffer *evbuf)
{
  char artwork[PATH_MAX];
  char *ptr;
  int i;
  int j;
  int len;
  int ret;
  cfg_t *lib;
  int nbasenames;

  ret = snprintf(artwork, sizeof(artwork), "%s", path);
  if ((ret < 0) || (ret >= sizeof(artwork)))
    {
      DPRINTF(E_INFO, L_ART, "Artwork path exceeds PATH_MAX\n");

      return -1;
    }

  if (!isdir)
    {
      ptr = strrchr(artwork, '/');
      if (ptr)
	*ptr = '\0';
    }

  len = strlen(artwork);

  lib = cfg_getsec(cfg, "library");
  nbasenames = cfg_size(lib, "artwork_basenames");

  if (nbasenames == 0)
    return -1;

  for (i = 0; i < nbasenames; i++)
    {
      for (j = 0; j < (sizeof(cover_extension) / sizeof(cover_extension[0])); j++)
	{
	  ret = snprintf(artwork + len, sizeof(artwork) - len, "/%s.%s", cfg_getnstr(lib, "artwork_basenames", i), cover_extension[j]);
	  if ((ret < 0) || (ret >= sizeof(artwork) - len))
	    {
	      DPRINTF(E_INFO, L_ART, "Artwork path exceeds PATH_MAX (%s.%s)\n", cfg_getnstr(lib, "artwork_basenames", i), cover_extension[j]);

	      continue;
	    }

	  DPRINTF(E_DBG, L_ART, "Trying directory artwork file %s\n", artwork);

	  ret = access(artwork, F_OK);
	  if (ret < 0)
	    continue;

	  break;
	}

      if (j < (sizeof(cover_extension) / sizeof(cover_extension[0])))
	break;
    }

  if (i == nbasenames)
    return -1;

  return artwork_get(artwork, max_w, max_h, format, evbuf);
}
Beispiel #27
0
//
// E_ProcessBossTypes
//
// Gets the thing type entries in the boss_spawner_types list,
// for use by the SpawnFly codepointer.
//
// modified by schepe to remove 11-type limit
//
static void E_ProcessBossTypes(cfg_t *cfg)
{
   int i, a = 0;
   int numTypes = cfg_size(cfg, SEC_BOSSTYPES);
   int numProbs = cfg_size(cfg, SEC_BOSSPROBS);
   bool useProbs = true;

   E_EDFLogPuts("\t* Processing boss spawn types\n");

   if(!numTypes)
   {
      // haleyjd 05/31/06: allow zero boss types
      E_EDFLogPuts("\t\tNo boss types defined\n");
      return;
   }

   // haleyjd 11/19/03: allow defaults for boss spawn probs
   if(!numProbs)
      useProbs = false;

   if(useProbs ? numTypes != numProbs : numTypes != 11)
   {
      E_EDFLoggedErr(2, 
         "E_ProcessBossTypes: %d boss types, %d boss probs\n",
         numTypes, useProbs ? numProbs : 11);
   }

   // haleyjd 11/21/11: allow multiple runs
   if(BossSpawnTypes)
   {
      efree(BossSpawnTypes);
      BossSpawnTypes = NULL;
   }
   if(BossSpawnProbs)
   {
      efree(BossSpawnProbs);
      BossSpawnProbs = NULL;
   }

   NumBossTypes = numTypes;
   BossSpawnTypes = ecalloc(int *, numTypes, sizeof(int));
   BossSpawnProbs = ecalloc(int *, numTypes, sizeof(int));

   // load boss spawn probabilities
   for(i = 0; i < numTypes; ++i)
   {
      if(useProbs)
      {
         a += cfg_getnint(cfg, SEC_BOSSPROBS, i);
         BossSpawnProbs[i] = a;
      }
      else
         BossSpawnProbs[i] = BossDefaults[i];
   }

   // check that the probabilities total 256
   if(useProbs && a != 256)
   {
      E_EDFLoggedErr(2, 
         "E_ProcessBossTypes: boss spawn probs do not total 256\n");
   }

   for(i = 0; i < numTypes; ++i)
   {
      const char *typeName = cfg_getnstr(cfg, SEC_BOSSTYPES, i);
      int typeNum = E_ThingNumForName(typeName);

      if(typeNum == -1)
      {
         E_EDFLoggedWarning(2, "Warning: invalid boss type '%s'\n", typeName);

         typeNum = UnknownThingType;
      }

      BossSpawnTypes[i] = typeNum;

      E_EDFLogPrintf("\t\tAssigned type %s(#%d) to boss type %d\n",
                     mobjinfo[typeNum]->name, typeNum, i);
   }
}
Beispiel #28
0
int main(int argc, char *argv[])
{
	uint8_t threadid_main = 0;
	pthread_key_create(&threadid_key, NULL);
	pthread_setspecific(threadid_key, &threadid_main);

	mprintf("University of Wisconsin IPMI MicroTCA System Manager\n");
	if (argc > 1 && strcmp(argv[1], "--version") == 0) {
		mprintf("\nCompiled from %s@%s\n", (GIT_BRANCH[0] ? GIT_BRANCH : "git-archive"), (GIT_COMMIT[0] ? GIT_COMMIT : "27868b9b800d107fbb53b68c2fce207144f97a98"));
		if (strlen(GIT_DIRTY) > 1)
			mprintf("%s", GIT_DIRTY);
		mprintf("\n");
		return 0;
	}

	/*
	 * Parse Configuration
	 */

	cfg_opt_t opts_auth[] =
	{
		CFG_STR_LIST(const_cast<char *>("raw"), const_cast<char *>("{}"), CFGF_NONE),
		CFG_STR_LIST(const_cast<char *>("manage"), const_cast<char *>("{}"), CFGF_NONE),
		CFG_STR_LIST(const_cast<char *>("read"), const_cast<char *>("{}"), CFGF_NONE),
		CFG_END()
	};

	cfg_opt_t opts_crate[] =
	{
		CFG_STR(const_cast<char *>("host"), const_cast<char *>(""), CFGF_NONE),
		CFG_STR(const_cast<char *>("description"), const_cast<char *>(""), CFGF_NONE),
		CFG_STR(const_cast<char *>("username"), const_cast<char *>(""), CFGF_NONE),
		CFG_STR(const_cast<char *>("password"), const_cast<char *>(""), CFGF_NONE),
		CFG_INT_CB(const_cast<char *>("authtype"), 0, CFGF_NONE, cfg_parse_authtype),
		CFG_INT_CB(const_cast<char *>("mch"), 0, CFGF_NONE, cfg_parse_MCH),
		CFG_BOOL(const_cast<char *>("enabled"), cfg_true, CFGF_NONE),
		CFG_END()
	};

	cfg_opt_t opts_cardmodule[] =
	{
		CFG_STR(const_cast<char *>("module"), const_cast<char *>(""), CFGF_NONE),
		CFG_STR_LIST(const_cast<char *>("config"), const_cast<char *>("{}"), CFGF_NONE),
		CFG_END()
	};

	cfg_opt_t opts[] =
	{
		CFG_SEC(const_cast<char *>("authentication"), opts_auth, CFGF_NONE),
		CFG_SEC(const_cast<char *>("crate"), opts_crate, CFGF_MULTI),
		CFG_SEC(const_cast<char *>("cardmodule"), opts_cardmodule, CFGF_MULTI),
		CFG_INT(const_cast<char *>("socket_port"), 4681, CFGF_NONE),
		CFG_INT(const_cast<char *>("ratelimit_delay"), 0, CFGF_NONE),
		CFG_BOOL(const_cast<char *>("daemonize"), cfg_false, CFGF_NONE),
		CFG_END()
	};
	cfg_t *cfg = cfg_init(opts, CFGF_NONE);
	cfg_set_validate_func(cfg, "crate|host", &cfg_validate_hostname);
	cfg_set_validate_func(cfg, "socket_port", &cfg_validate_port);

	if (argc >= 2 && access(argv[1], R_OK) == 0) {
		if(cfg_parse(cfg, argv[1]) == CFG_PARSE_ERROR)
			exit(1);
	}
	else if (access(CONFIG_PATH "/" CONFIG_FILE, R_OK) == 0) {
		if(cfg_parse(cfg, CONFIG_PATH "/" CONFIG_FILE) == CFG_PARSE_ERROR)
			exit(1);
	}
	else {
		printf("Config file %s not found, and no argument supplied.\n", CONFIG_PATH "/" CONFIG_FILE);
		printf("Try: %s sysmgr.conf\n", argv[0]);
		exit(1);
	}

	bool crate_found = false;
	bool crate_enabled = false;

	cfg_t *cfgauth = cfg_getsec(cfg, "authentication");
	for(unsigned int i = 0; i < cfg_size(cfgauth, "raw"); i++)
		config_authdata.raw.push_back(std::string(cfg_getnstr(cfgauth, "raw", i)));
	for(unsigned int i = 0; i < cfg_size(cfgauth, "manage"); i++)
		config_authdata.manage.push_back(std::string(cfg_getnstr(cfgauth, "manage", i)));
	for(unsigned int i = 0; i < cfg_size(cfgauth, "read"); i++)
		config_authdata.read.push_back(std::string(cfg_getnstr(cfgauth, "read", i)));

	for(unsigned int i = 0; i < cfg_size(cfg, "crate"); i++) {
		cfg_t *cfgcrate = cfg_getnsec(cfg, "crate", i);
		crate_found = true;

		enum Crate::Mfgr MCH;
		switch (cfg_getint(cfgcrate, "mch")) {
			case Crate::VADATECH: MCH = Crate::VADATECH; break;
			case Crate::NAT: MCH = Crate::NAT; break;
		}

		const char *user = cfg_getstr(cfgcrate, "username");
		const char *pass = cfg_getstr(cfgcrate, "password");

		Crate *crate = new Crate(i+1, MCH, cfg_getstr(cfgcrate, "host"), (user[0] ? user : NULL), (pass[0] ? pass : NULL), cfg_getint(cfgcrate, "authtype"), cfg_getstr(cfgcrate, "description"));

		bool enabled = (cfg_getbool(cfgcrate, "enabled") == cfg_true);
		if (enabled)
			crate_enabled = true;
		threadlocal.push_back(threadlocaldata_t(crate, enabled));
	}

	for(unsigned int i = 0; i < cfg_size(cfg, "cardmodule"); i++) {
		cfg_t *cfgmodule = cfg_getnsec(cfg, "cardmodule", i);

		const char *module = cfg_getstr(cfgmodule, "module");

		std::vector<std::string> configdata;
		for(unsigned int i = 0; i < cfg_size(cfgmodule, "config"); i++)
			configdata.push_back(std::string(cfg_getnstr(cfgmodule, "config", i)));

		std::string default_module_path = DEFAULT_MODULE_PATH;
	   	if (getenv("SYSMGR_MODULE_PATH") != NULL)
			default_module_path = getenv("SYSMGR_MODULE_PATH");

		std::string modulepath = module;
		if (modulepath.find("/") == std::string::npos)
			modulepath = default_module_path +"/"+ modulepath;

		cardmodule_t cm;
		cm.dl_addr = dlopen(modulepath.c_str(), RTLD_NOW|RTLD_GLOBAL);
		if (cm.dl_addr == NULL) {
			printf("Error loading module %s:\n\t%s\n", module, dlerror());
			exit(2);
		}

		void *sym;
#define LOAD_SYM(name, type) \
		sym = dlsym(cm.dl_addr, #name); \
		if (sym == NULL) { \
			mprintf("Error loading module %s " type " " #name ":\n\t%s\n", module, dlerror()); \
			exit(2); \
		}

		LOAD_SYM(APIVER, "variable");
		cm.APIVER = *reinterpret_cast<uint32_t*>(sym);

		LOAD_SYM(MIN_APIVER, "variable");
		cm.MIN_APIVER = *reinterpret_cast<uint32_t*>(sym);

		if (cm.APIVER < 2 || cm.MIN_APIVER > 2) {
			mprintf("Error loading module %s: Incompatible API version %u\n", module, cm.APIVER);
		}

		LOAD_SYM(initialize_module, "function");
		cm.initialize_module = reinterpret_cast<bool (*)(std::vector<std::string>)>(sym);

		LOAD_SYM(instantiate_card, "function");
		cm.instantiate_card = reinterpret_cast<Card* (*)(Crate*, std::string, void*, uint8_t)>(sym);

#undef LOAD_SYM

		if (!cm.initialize_module(configdata)) {
			printf("Error loading module %s: initialize_module() returned false\n", module);
			exit(2);
		}

		card_modules.insert(card_modules.begin(), cm);
	}

	uint16_t port = cfg_getint(cfg, "socket_port");
	config_ratelimit_delay = cfg_getint(cfg, "ratelimit_delay");
	bool daemonize = (cfg_getbool(cfg, "daemonize") == cfg_true);

	cfg_free(cfg);

	if (!crate_found) {
		printf("No crate specified in the configuration file.\n");
		exit(1);
	}
	if (!crate_enabled) {
		printf("No crates are enabled in the configuration file.\n");
		printf("No crates to service.\n");
		exit(1);
	}

	if (daemonize) {
		do_fork();
		stdout_use_syslog = true;
		mprintf("University of Wisconsin IPMI MicroTCA System Manager\n");
	}

	/*
	 * Initialize library crypto routines before spawning threads.
	 * This connect will fail due to hostname too long, after running the crypt init functions.
	 *
	 * Max Hostname Limit: 64
	 */
	ipmi_ctx_t dummy_ipmi_ctx = ipmi_ctx_create();
	if (ipmi_ctx_open_outofband_2_0(dummy_ipmi_ctx,
				".................................................................",			// hostname
				NULL,					// username
				NULL,					// password
				NULL,						// k_g
				0,							// k_g_len,
				4,							// privilege_level
				0,							// cipher_suite_id
				0,							// session_timeout
				5,							// retransmission_timeout
				IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_OPEN_SESSION_PRIVILEGE,	// workaround_flags
				IPMI_FLAGS_DEFAULT			// flags
				) == 0) {
		ipmi_ctx_close(dummy_ipmi_ctx);
	}
	ipmi_ctx_destroy(dummy_ipmi_ctx);

	/*
	 * Instantiate Worker Threads
	 */

	for (std::vector<threadlocaldata_t>::iterator it = threadlocal.begin(); it != threadlocal.end(); it++)
		if (it->enabled)
			pthread_create(&it->thread, NULL, crate_monitor, (void *)it->crate->get_number());

#ifndef DEBUG_ONESHOT
	protocol_server(port);
#endif

	for (std::vector<threadlocaldata_t>::iterator it = threadlocal.begin(); it != threadlocal.end(); it++)
		if (it->enabled)
			pthread_join(it->thread, NULL);
}
Beispiel #29
0
int handle_lispd_config_file()
{
    cfg_t           *cfg   = 0;
    unsigned int    i      = 0;
    unsigned        n      = 0;
    int             ret    = 0;

    static cfg_opt_t map_server_opts[] = {
    CFG_STR("address",      0, CFGF_NONE),
    CFG_INT("key-type",     0, CFGF_NONE),
    CFG_STR("key",          0, CFGF_NONE),
    CFG_BOOL("proxy-reply", cfg_false, CFGF_NONE),
    CFG_BOOL("verify",      cfg_false, CFGF_NONE),
    CFG_END()
    };

    static cfg_opt_t db_mapping_opts[] = {
        CFG_STR("eid-prefix",           0, CFGF_NONE),
        CFG_INT("iid",                  -1, CFGF_NONE),
        CFG_STR("interface",            0, CFGF_NONE),
        CFG_INT("priority_v4",          0, CFGF_NONE),
        CFG_INT("weight_v4",            0, CFGF_NONE),
        CFG_INT("priority_v6",          0, CFGF_NONE),
        CFG_INT("weight_v6",            0, CFGF_NONE),
        CFG_END()
    };

    static cfg_opt_t mc_mapping_opts[] = {
        CFG_STR("eid-prefix",           0, CFGF_NONE),
        CFG_INT("iid",                  0, CFGF_NONE),
        CFG_STR("rloc",                 0, CFGF_NONE),
        CFG_INT("priority",             0, CFGF_NONE),
        CFG_INT("weight",               0, CFGF_NONE),
        CFG_END()
    };

    static cfg_opt_t petr_mapping_opts[] = {
            CFG_STR("address",              0, CFGF_NONE),
            CFG_INT("priority",           255, CFGF_NONE),
            CFG_INT("weight",               0, CFGF_NONE),
            CFG_END()
    };

    cfg_opt_t opts[] = {
        CFG_SEC("database-mapping",     db_mapping_opts, CFGF_MULTI),
        CFG_SEC("static-map-cache",     mc_mapping_opts, CFGF_MULTI),
        CFG_SEC("map-server",           map_server_opts, CFGF_MULTI),
        CFG_SEC("proxy-etr",            petr_mapping_opts, CFGF_MULTI),
        CFG_INT("map-request-retries",  0, CFGF_NONE),
        CFG_INT("control-port",         0, CFGF_NONE),
        CFG_BOOL("debug",               cfg_false, CFGF_NONE),
        CFG_STR("map-resolver",         0, CFGF_NONE),
        CFG_STR_LIST("proxy-itrs",      0, CFGF_NONE),
        CFG_END()
    };

    /*
     *  parse config_file
     */

    cfg = cfg_init(opts, CFGF_NOCASE);
    ret = cfg_parse(cfg, config_file);

    if (ret == CFG_FILE_ERROR) {
        syslog(LOG_DAEMON, "Couldn't find config file %s, exiting...", config_file);
        exit(EXIT_FAILURE);
    } else if(ret == CFG_PARSE_ERROR) {
        syslog(LOG_DAEMON, "NOTE: Version 0.2.4 changed the format of the 'proxy-etr' element.");
        syslog(LOG_DAEMON, "      Check the 'lispd.conf.example' file for an example entry in");
        syslog(LOG_DAEMON, "      the new format.");
        syslog(LOG_DAEMON, "Parse error in file %s, exiting...", config_file);
        exit(EXIT_FAILURE);
    }

    
    /*
     *  lispd config options
     */

    ret = cfg_getint(cfg, "map-request-retries");
    if (ret != 0)
        map_request_retries = ret;

    cfg_getbool(cfg, "debug") ? (debug = 1) : (debug = 0); 

    /*
     *  LISP config options
     */

    /*
     *  handle map-resolver config
     */

    map_resolver = cfg_getstr(cfg, "map-resolver");
    if (!add_server(map_resolver, &map_resolvers))
        return(0); 
#ifdef DEBUG
    syslog(LOG_DAEMON, "Added %s to map-resolver list", map_resolver);
#endif

    /*
     *  handle proxy-etr config
     */


    n = cfg_size(cfg, "proxy-etr");
    for(i = 0; i < n; i++) {
        cfg_t *petr = cfg_getnsec(cfg, "proxy-etr", i);
        if (!add_proxy_etr_entry(petr, &proxy_etrs)) {
            syslog(LOG_DAEMON, "Can't add proxy-etr %d (%s)", i, cfg_getstr(petr, "address"));
        }
    }

    if (!proxy_etrs){
        syslog(LOG_DAEMON, "WARNING: No Proxy-ETR defined. Packets to non-LISP destinations will be forwarded natively (no LISP encapsulation). This may prevent mobility in some scenarios.");
        sleep(3);
    }

    /*
     *  handle proxy-itr config
     */

    n = cfg_size(cfg, "proxy-itrs");
    for(i = 0; i < n; i++) {
        if ((proxy_itr = cfg_getnstr(cfg, "proxy-itrs", i)) != NULL) {
            if (!add_server(proxy_itr, &proxy_itrs))
                continue;
#ifdef DEBUG
            syslog(LOG_DAEMON, "Added %s to proxy-itr list", proxy_itr);
#endif
        }
    }

    /*
     *  handle database-mapping config
     */

    n = cfg_size(cfg, "database-mapping");
    for(i = 0; i < n; i++) {
        cfg_t *dm = cfg_getnsec(cfg, "database-mapping", i);
        if (!add_database_mapping(dm)) {
            syslog(LOG_DAEMON, "Can't add database-mapping %d (%s->%s)",
               i,
               cfg_getstr(dm, "eid-prefix"),
               cfg_getstr(dm, "interface"));
        }
    }

    /*
     *  handle map-server config
     */

    n = cfg_size(cfg, "map-server");
    for(i = 0; i < n; i++) {
        cfg_t *ms = cfg_getnsec(cfg, "map-server", i);
        if (!add_map_server(cfg_getstr(ms, "address"),
                                cfg_getint(ms, "key-type"),
                cfg_getstr(ms, "key"),
                (cfg_getbool(ms, "proxy-reply") ? 1:0),
                (cfg_getbool(ms, "verify")      ? 1:0)))

            return(0);
#ifdef DEBUG
        syslog(LOG_DAEMON, "Added %s to map-server list",
            cfg_getstr(ms, "address"));
#endif
    }

    /*
     *  handle static-map-cache config
     */

    n = cfg_size(cfg, "static-map-cache");
    for(i = 0; i < n; i++) {
        cfg_t *smc = cfg_getnsec(cfg, "static-map-cache", i);
            if (!add_static_map_cache_entry(smc)) {
        syslog(LOG_DAEMON,"Can't add static-map-cache %d (EID:%s -> RLOC:%s)",
               i,
               cfg_getstr(smc, "eid-prefix"),
               cfg_getstr(smc, "rloc"));
        }
    }


#if (DEBUG > 3)
    dump_tree(AF_INET,AF4_database);
    dump_tree(AF_INET6,AF6_database);
    dump_database();
    dump_map_servers();
    dump_servers(map_resolvers, "map-resolvers");
    dump_servers(proxy_etrs, "proxy-etrs");
    dump_servers(proxy_itrs, "proxy-itrs");
    dump_map_cache();
#endif

    cfg_free(cfg);
    return(0);
}
Beispiel #30
0
//
// E_ProcessCast
//
// Creates the DOOM II cast call information
//
static void E_ProcessCast(cfg_t *cfg)
{
   static bool firsttime = true;
   int i, numcastorder = 0, numcastsections = 0;
   cfg_t **ci_order;

   E_EDFLogPuts("\t* Processing cast call\n");
   
   // get number of cast sections
   numcastsections = cfg_size(cfg, SEC_CAST);

   if(firsttime && !numcastsections) // on main parse, at least one is required.
      E_EDFLoggedErr(2, "E_ProcessCast: no cast members defined.\n");

   firsttime = false;

   E_EDFLogPrintf("\t\t%d cast member(s) defined\n", numcastsections);

   // haleyjd 11/21/11: allow multiple runs
   if(castorder)
   {
      int i;

      // free names
      for(i = 0; i < max_castorder; i++)
      {
         if(castorder[i].name)
            efree(castorder[i].name);
      }
      // free castorder
      efree(castorder);
      castorder = NULL;
      max_castorder = 0;
   }

   // check if the "castorder" array is defined for imposing an
   // order on the castinfo sections
   numcastorder = cfg_size(cfg, SEC_CASTORDER);

   E_EDFLogPrintf("\t\t%d cast member(s) in castorder\n", numcastorder);

   // determine size of castorder
   max_castorder = (numcastorder > 0) ? numcastorder : numcastsections;

   // allocate with size+1 for an end marker
   castorder = estructalloc(castinfo_t, max_castorder + 1);
   ci_order  = ecalloc(cfg_t **, sizeof(cfg_t *), max_castorder);

   if(numcastorder > 0)
   {
      for(i = 0; i < numcastorder; ++i)
      {
         const char *title = cfg_getnstr(cfg, SEC_CASTORDER, i);         
         cfg_t *section    = cfg_gettsec(cfg, SEC_CAST, title);

         if(!section)
         {
            E_EDFLoggedErr(2, 
               "E_ProcessCast: unknown cast member '%s' in castorder\n", 
               title);
         }

         ci_order[i] = section;
      }
   }
   else
   {
      // no castorder array is defined, so use the cast members
      // in the order they are encountered (for backward compatibility)
      for(i = 0; i < numcastsections; ++i)
         ci_order[i] = cfg_getnsec(cfg, SEC_CAST, i);
   }


   for(i = 0; i < max_castorder; ++i)
   {
      int j;
      const char *tempstr;
      int tempint = 0;
      cfg_t *castsec = ci_order[i];

      // resolve thing type
      tempstr = cfg_getstr(castsec, ITEM_CAST_TYPE);
      if(!tempstr || 
         (tempint = E_ThingNumForName(tempstr)) == -1)
      {
         E_EDFLoggedWarning(2, "Warning: cast %d: unknown thing type %s\n",
                            i, tempstr);

         tempint = UnknownThingType;
      }
      castorder[i].type = tempint;

      // get cast name, if any -- the first seventeen entries can
      // default to using the internal string editable via BEX strings
      tempstr = cfg_getstr(castsec, ITEM_CAST_NAME);
      if(cfg_size(castsec, ITEM_CAST_NAME) == 0 && i < 17)
         castorder[i].name = NULL; // set from DeHackEd
      else
         castorder[i].name = estrdup(tempstr); // store provided value

      // get stopattack flag (used by player)
      castorder[i].stopattack = cfg_getbool(castsec, ITEM_CAST_SA);

      // process sound blocks (up to four will be processed)
      tempint = cfg_size(castsec, ITEM_CAST_SOUND);
      for(j = 0; j < 4; ++j)
      {
         castorder[i].sounds[j].frame = 0;
         castorder[i].sounds[j].sound = 0;
      }
      for(j = 0; j < tempint && j < 4; ++j)
      {
         int num;
         sfxinfo_t *sfx;
         const char *name;
         cfg_t *soundsec = cfg_getnsec(castsec, ITEM_CAST_SOUND, j);

         // if these are invalid, just fill them with zero rather
         // than causing an error, as they're very unimportant

         // name of sound to play
         name = cfg_getstr(soundsec, ITEM_CAST_SOUNDNAME);
         
         // haleyjd 03/22/06: modified to support dehnum auto-allocation
         if((sfx = E_EDFSoundForName(name)) == NULL)
         {
            E_EDFLoggedWarning(2, "Warning: cast member references invalid sound %s\n",
                               name);
            castorder[i].sounds[j].sound = 0;
         }
         else
         {
            if(sfx->dehackednum != -1 || E_AutoAllocSoundDEHNum(sfx))
               castorder[i].sounds[j].sound = sfx->dehackednum;
            else
            {
               E_EDFLoggedWarning(2, "Warning: could not auto-allocate a DeHackEd number "
                                     "for sound %s\n", name);
               castorder[i].sounds[j].sound = 0;
            }
         }

         // name of frame that triggers sound event
         name = cfg_getstr(soundsec, ITEM_CAST_SOUNDFRAME);
         if((num = E_StateNumForName(name)) < 0)
            num = 0;
         castorder[i].sounds[j].frame = num;
      }
   }

   // initialize the end marker to all zeroes
   memset(&castorder[max_castorder], 0, sizeof(castinfo_t));

   // free the ci_order table
   efree(ci_order);
}