#include "lib/lib.h"
#include "lib/conf2.h"
#include "lib/mempool.h"
+#include "lib/clists.h"
#include <stdlib.h>
#include <string.h>
}
}
+/* Initialization */
+
+static struct section {
+ struct section *prev;
+ byte *name;
+ struct cf_section *sec;
+} *sections;
+
+void
+cf_declare_section(byte *name, struct cf_section *sec)
+{
+ struct section *s = sections;
+ for (; s; s=s->prev)
+ if (!strcasecmp(s->name, name))
+ die("Cannot register cf_section %s twice", name);
+ s = xmalloc(sizeof(struct section));
+ s->prev = sections;
+ s->name = name;
+ s->sec = sec;
+ sections = s;
+}
+
+void
+cf_init_section(byte *name, struct cf_section *sec, void *ptr)
+{
+ if (sec->size)
+ bzero(ptr, sec->size);
+ for (uns i=0; sec->cfg[i].cls; i++)
+ if (sec->cfg[i].cls == CC_SECTION)
+ cf_init_section(sec->cfg[i].name, sec->cfg[i].u.sec, ptr + (addr_int_t) sec->cfg[i].ptr);
+ else if (sec->cfg[i].cls == CC_LIST)
+ clist_init(sec->cfg[i].ptr);
+ byte *msg = sec->init(ptr);
+ if (msg)
+ die("Cannot initialize section %s: %s", name, msg);
+}
+
+static void
+global_init(void)
+{
+ for (struct section *s=sections; s; s=s->prev)
+ cf_init_section(s->name, s->sec, NULL);
+}
+
/* Safe loading and reloading */
+byte *cf_def_file = DEFAULT_CONFIG;
+
static byte *load_file(byte *file);
static byte *load_string(byte *string);
* (uns*) (*ptr - parsers[type].size) = number;
return ((cf_parser*) parsers[type].parser) (number, pars, *ptr);
}
+
void *ptr; // pointer to a global variable or an offset in a section
union {
enum cf_type type; // type of a static or dynamic attribute
- struct cf_section *sub; // declaration of a section or a list
+ struct cf_section *sec; // declaration of a section or a list
cf_parser *par; // parser function
} u;
};
#define CF_STATIC(n,p,T,t,c) { .cls = CC_STATIC, .name = n, .number = c, .ptr = CHECK_PTR_TYPE(p,t*), .u.type = CT_##T }
#define CF_DYNAMIC(n,p,T,t,c) { .cls = CC_DYNAMIC, .name = n, .number = c, .ptr = CHECK_PTR_TYPE(p,t**), .u.type = CT_##T }
#define CF_PARSER(n,p,f,c) { .cls = CC_PARSER, .name = n, .number = c, .ptr = p, .u.par = (cf_parser*) f }
-#define CF_SECTION(n,p,s) { .cls = CC_SECTION, .name = n, .number = 1, .ptr = p, .u.sub = s }
-#define CF_LIST(n,p,s) { .cls = CC_LIST, .name = n, .number = 1, .ptr = CHECK_PTR_TYPE(p,struct clist*), .u.sub = s }
+#define CF_SECTION(n,p,s) { .cls = CC_SECTION, .name = n, .number = 1, .ptr = p, .u.sec = s }
+#define CF_LIST(n,p,s) { .cls = CC_LIST, .name = n, .number = 1, .ptr = CHECK_PTR_TYPE(p,struct clist*), .u.sec = s }
/* Configuration items for basic types */
#define CF_INT(n,p) CF_STATIC(n,p,INT,int,1)
#define CF_INT_ARY(n,p,c) CF_STATIC(n,p,INT,int,c)
extern uns cf_need_journal;
void cf_journal_block(void *ptr, uns len);
+/* Declaration */
+void cf_declare_section(byte *name, struct cf_section *sec);
+void cf_init_section(byte *name, struct cf_section *sec, void *ptr);
+
/* Safe reloading and loading of configuration files */
+extern byte *cf_def_file;
byte *cf_reload(byte *file);
byte *cf_load(byte *file);
byte *cf_set(byte *string);