summaryrefslogtreecommitdiffstats
path: root/conffile/conffile.c
diff options
context:
space:
mode:
Diffstat (limited to 'conffile/conffile.c')
-rw-r--r--conffile/conffile.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/conffile/conffile.c b/conffile/conffile.c
new file mode 100644
index 0000000..d4efc78
--- /dev/null
+++ b/conffile/conffile.c
@@ -0,0 +1,200 @@
+/* config file parser functions
+ *
+ * (C) 2000 by Harald Welte <laforge@gnumonks.org>
+ *
+ * $Id: conffile.c,v 1.7 2000/11/16 17:20:52 laforge Exp $
+ *
+ * This code is distributed under the terms of GNU GPL */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "conffile.h"
+
+#ifdef DEBUG_CONF
+#define DEBUGC(format, args...) fprintf(stderr, format, ## args)
+#else
+#define DEBUGC(format, args...)
+#endif
+
+/* linked list of all registered configuration directives */
+static config_entry_t *config = NULL;
+
+/* points to config entry with error */
+config_entry_t *config_errce = NULL;
+
+/* Filename of the config file */
+static char *fname = NULL;
+
+/* the the next word in string */
+static char *get_word(const char *string)
+{
+ int len;
+ char *word, *space;
+ space = strrchr(string, ' ');
+
+ if (!space) {
+ space = strrchr(string, '\t');
+ if (!space)
+ return NULL;
+ }
+ len = space - string;
+ if (!len)
+ return NULL;
+
+ word = (char *) malloc(len+1);
+ if (!word)
+ return NULL;
+
+ strncpy(word, string, len);
+
+// if (*(word + len) == '\n')
+ *(word + len) = '\0';
+
+ return word;
+}
+
+/* do we have a config directive for this name */
+static int config_iskey(char *name)
+{
+ config_entry_t *ce;
+
+ for (ce = config; ce; ce = ce->next) {
+ if (!strcmp(name, ce->key))
+ return 0;
+ }
+
+ return 1;
+}
+
+/***********************************************************************
+ * PUBLIC INTERFACE
+ ***********************************************************************/
+
+/* register linked list of config directives with us */
+int config_register_key(config_entry_t *ce)
+{
+ config_entry_t *myentry;
+
+ if (!ce)
+ return 1;
+
+ /* prepend our list to the global config list */
+ for (myentry = ce; myentry->next; myentry = myentry->next) {
+ }
+ myentry->next = config;
+ config = ce;
+
+ return 0;
+}
+
+/* register config file with us */
+int config_register_file(const char *file)
+{
+ /* FIXME: stat of file */
+ if (fname)
+ return 1;
+
+ fname = (char *) malloc(strlen(file)+1);
+ if (!fname)
+ return -ERROOM;
+
+ strcpy(fname, file);
+
+ return 0;
+}
+
+/* parse config file */
+int config_parse_file(int final)
+{
+ FILE *cfile;
+ char *line, *word, *args;
+ config_entry_t *ce;
+ int err = 0;
+
+ line = (char *) malloc(LINE_LEN+1);
+ if (!line)
+ return -ERROOM;
+
+ cfile = fopen(fname, "r");
+ if (!cfile) {
+ free(line);
+ return -ERROPEN;
+ }
+
+ while (fgets(line, LINE_LEN, cfile))
+ {
+ DEBUGC("line read: %s\n", line);
+ if (*line == '#')
+ continue;
+
+ word = get_word(line);
+ if (!word)
+ continue;
+
+#if 0
+ /* if we do the final parse and word is not a config key */
+ if (final && config_iskey(word)) {
+ DEBUGC("final and key '%s' not found\n", word);
+ err = -ERRUNKN;
+ goto cpf_error;
+ }
+#endif
+
+ args = line + strlen(word) + 1;
+ *(args + strlen(args) - 1 ) = '\0';
+
+ DEBUGC("parse_file: entering main loop\n");
+ for (ce = config; ce; ce = ce->next) {
+ DEBUGC("parse main loop, key: %s\n", ce->key);
+ if (strcmp(ce->key, word)) {
+ continue;
+ }
+
+ if (ce->hit && !(ce->options & CONFIG_OPT_MULTI))
+ {
+ DEBUGC("->ce-hit and option not multi!\n");
+ config_errce = ce;
+ err = -ERRMULT;
+ goto cpf_error;
+ }
+ if (final)
+ ce->hit++;
+ switch (ce->type) {
+ case CONFIG_TYPE_STRING:
+ if (strlen(args) <
+ CONFIG_VAL_STRING_LEN ) {
+ strcpy(ce->u.string, args);
+ }
+ break;
+ case CONFIG_TYPE_INT:
+ ce->u.value = atoi(args);
+ break;
+ case CONFIG_TYPE_CALLBACK:
+ (ce->u.parser)(args);
+ break;
+ }
+ break;
+ }
+ DEBUGC("parse_file: exiting main loop\n");
+ }
+
+
+ for (ce = config; ce; ce = ce->next) {
+ DEBUGC("ce post loop, ce=%s\n", ce->key);
+ if ((ce->options & CONFIG_OPT_MANDATORY) && (ce->hit == 0) && final) {
+ DEBUGC("mandatory config directive %s not found\n",
+ ce->key);
+ config_errce = ce;
+ err = -ERRMAND;
+ goto cpf_error;
+ }
+
+ }
+
+cpf_error:
+ free(line);
+ fclose(cfile);
+ return err;
+}
+