diff options
author | Stef Walter <stef@memberwebs.com> | 2006-01-25 04:07:04 +0000 |
---|---|---|
committer | Stef Walter <stef@memberwebs.com> | 2006-01-25 04:07:04 +0000 |
commit | 7fcead4473bc224bc8c6a66e2db3b3ee87f751d4 (patch) | |
tree | d92c54aed884ed001f7901bbb4bef9623975df76 /src/rrdbotd.c | |
parent | 26a677b17880a14b9345270cb15b37d27d7d4797 (diff) |
Configuration file parsing for rrdbotd.
Diffstat (limited to 'src/rrdbotd.c')
-rw-r--r-- | src/rrdbotd.c | 214 |
1 files changed, 46 insertions, 168 deletions
diff --git a/src/rrdbotd.c b/src/rrdbotd.c index 064c603..bee836e 100644 --- a/src/rrdbotd.c +++ b/src/rrdbotd.c @@ -41,7 +41,6 @@ #include <unistd.h> #include <stdarg.h> #include <syslog.h> -#include <dirent.h> /* TODO: Abstract these headers away nicely */ #include <bsnmp/asn1.h> @@ -57,6 +56,9 @@ * GLOBALS */ +/* The one main state object */ +rb_state g_state; + /* TODO: These should be set from the command line */ static int daemonized = 0; static int debug_level = 7; @@ -92,189 +94,53 @@ test_bsnmpd() } /* ----------------------------------------------------------------------------- - * CONFIG FILES + * CLEANUP */ -static char* -read_config_file(const char* configfile) +typedef struct _exit_stack { - char* config = NULL; - FILE* f = NULL; - long len; - - ASSERT(configfile); - - f = fopen(configfile, "r"); - if(f == NULL) - err(1, "couldn't open config file: %s", configfile); - - /* Figure out size */ - if(fseek(f, 0, SEEK_END) == -1 || (len = ftell(f)) == -1 || fseek(f, 0, SEEK_SET) == -1) - err(1, "couldn't seek config file: %s", configfile); - - if((config = (char*)malloc(len + 2)) == NULL) - errx(1, "out of memory"); - - /* And read in one block */ - if(fread(config, 1, len, f) != len) - err(1, "couldn't read config file: %s", configfile); + voidfunc func; + void* data; - fclose(f); - - /* Null terminate the data */ - config[len] = '\n'; - config[len + 1] = 0; - - /* Remove nasty dos line endings */ - remove_cr(config); - - rb_messagex(LOG_DEBUG, "read config file: %s", configfile); - return config; + /* We have a list of these beauties */ + struct _exit_stack* next; } +exit_stack; + +/* Our exit stack */ +static exit_stack* atexits = NULL; +static int atexit_registered = 0; static void -parse_config_file(const char* configfile) +atexit_do_stack(void) { - char* name = NULL; - char* value = NULL; - char* config; - char* next; - char* header; - char* p; - char* t; - int pos; - - config = read_config_file(configfile); - next = config; - - /* Go through lines and process them */ - while((t = strchr(next, '\n')) != NULL) + exit_stack* next; + for(; atexits; atexits = next) { - *t = 0; - p = next; /* Do this before cleaning below */ - next = t + 1; - - t = trim_start(p); - - /* Continuation line (had spaces at start) */ - if(p < t && *t) - { - if(!value) - errx(2, "invalid continuation in config: %s", p); - - /* Calculate the end of the current value */ - t = value + strlen(value); - ASSERT(t < p); - - /* Continuations are separated by spaces */ - *t = ' '; - t++; - - continue; - } - - // No continuation hand off value if necessary - if(name && value) - { - rb_messagex(LOG_DEBUG, "parsed configuration value: [%s] %s = %s", header, name, value); - // TODO: Hand off pairs here - } - - name = NULL; - value = NULL; - - /* Empty lines / comments at start / comments without continuation */ - if(!*t || *p == '#') - continue; - - /* A header */ - if(*p == '[') - { - t = p + strcspn(p, "]"); - if(!*t || t == p + 1) - errx(2, "invalid config header: %s", p); - - *t = 0; - header = trim_space(p + 1); - continue; - } - - /* Look for the break between name = value on the same line */ - t = p + strcspn(p, ":="); - if(!*t) - errx(2, "invalid config line: %s", p); - - /* Null terminate and split value part */ - *t = 0; - t++; - - name = trim_space(p); - value = trim_space(t); - } - - if(name && value) - { - rb_messagex(LOG_DEBUG, "parsed configuration value: %s = %s", name, value); - // TODO: Hand off pairs here + next = atexits->next; + (atexits->func)(atexits->data); + free(atexits); } - - // TODO: Eventually no freeing - free(config); } -static void -parse_config_dir(const char* confdir) +void +rb_atexit(voidfunc func, void* data) { - char olddir[MAXPATHLEN]; - char configfile[MAXPATHLEN]; - DIR* top; - struct dirent* tope; - DIR* dir; - struct dirent* dire; - - /* Get the current directory */ - if(!getcwd(olddir, MAXPATHLEN)) - *olddir = 0; - - if(chdir(confdir) == -1 || - (top = opendir(".")) == NULL) - err("couldn't read config directory: %s", confdir); - - while((tope = readdir(top)) != NULL) - { - /* Only go through the category directories */ - if(!(tope->d_type & DT_DIR)) - continue; - - /* None of these dumb dots */ - if(strcmp(tope->d_name, ".") == 0 || - strcmp(tope->d_name, "..") == 0) - continue; + exit_stack* ae; - dir = opendir(tope->d_name); - if(!dir) - err("couldn't read config directory: %s/%s", confdir, tope->d_name); + ASSERT(func); - while((dire = readdir(dir)) != NULL) - { - if(dire->d_type != DT_REG && dire->d_type != DT_LNK) - continue; - - /* Build a happy path name */ - snprintf(configfile, MAXPATHLEN, "%s/%s/%s", confdir, tope->d_name, dire->d_name); - configfile[MAXPATHLEN - 1] = 0; - - parse_config_file(configfile); - } + ae = (exit_stack*)calloc(1, sizeof(exit_stack)); + if(ae) + { + ae->func = func; + ae->data = data; + ae->next = atexits; + atexits = ae; - closedir(dir); + if(!atexit_registered) + atexit(atexit_do_stack); } - - closedir(top); - - /* And put it back nicely */ - if(*olddir) - chdir(olddir); } /* ----------------------------------------------------------------------------- @@ -348,6 +214,13 @@ main(int argc, char* argv[]) int daemonize; char ch; + /* Initialize the state stuff */ + memset(&g_state, 0, sizeof(g_state)); + + /* TODO: These should come from configure, and from arguments */ + g_state.rrddir = "/data/projects/rrdui/work"; + g_state.confdir = "/data/projects/rrdui/conf"; + /* Parse the arguments nicely */ while((ch = getopt(argc, argv, "v")) != -1) { @@ -371,7 +244,12 @@ main(int argc, char* argv[]) argc -= optind; argv += optind; - parse_config_dir("/data/projects/rrdui/conf"); + rb_config_parse(); + + printf("a test\n"); + + rb_config_free(); + return 0; } |