diff options
author | pdw <> | 2003-10-19 06:44:33 +0000 |
---|---|---|
committer | pdw <> | 2003-10-19 06:44:33 +0000 |
commit | 458045923be8a5ff15493a2fd4343f1899a03fa0 (patch) | |
tree | 625f07958bf4f2b41da1d0774f8fea26e2a3faed /cfgfile.c | |
parent | 3824538a293966a04eeec220110cc6e84f133312 (diff) | |
download | iftop-458045923be8a5ff15493a2fd4343f1899a03fa0.zip |
Added initial config file support.
Diffstat (limited to 'cfgfile.c')
-rw-r--r-- | cfgfile.c | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/cfgfile.c b/cfgfile.c new file mode 100644 index 0000000..bb3bf69 --- /dev/null +++ b/cfgfile.c @@ -0,0 +1,251 @@ +/* + * cfgfile.c: + * + * Copyright (c) 2003 DecisionSoft Ltd. + * + */ + +#include <stdio.h> +#include <errno.h> + +#include "stringmap.h" +#include "iftop.h" +#include "options.h" +#include "cfgfile.h" + +#define CONFIG_TYPE_STRING 0 +#define CONFIG_TYPE_BOOL 1 +#define CONFIG_TYPE_INT 2 + +#define MAX_CONFIG_LINE 2048 + +typedef struct { + char * name; + int type; +} config_item_type; + +config_item_type config_directives[] = { + { "interface", CONFIG_TYPE_STRING }, + { "dns-resolution", CONFIG_TYPE_BOOL }, + { "port-resolution", CONFIG_TYPE_BOOL }, + { "filter-code", CONFIG_TYPE_STRING }, + { "show-bars", CONFIG_TYPE_BOOL }, + { "promiscuous", CONFIG_TYPE_BOOL }, + { "show-ports", CONFIG_TYPE_INT }, + { "hide-source", CONFIG_TYPE_INT }, + { "hide-destination", CONFIG_TYPE_INT }, + { "use-bytes", CONFIG_TYPE_INT }, + { "sort", CONFIG_TYPE_INT }, + { "line-display", CONFIG_TYPE_INT }, + { "show-totals", CONFIG_TYPE_INT }, + { "log-scale", CONFIG_TYPE_INT }, + { "max-bandwidth", CONFIG_TYPE_INT }, + { "net-filter", CONFIG_TYPE_INT }, + { "port-display", CONFIG_TYPE_INT }, + { NULL, 0} +}; + +stringmap config; + +extern options_t options ; + +int is_cfgdirective_valid(const char *s) { + config_item_type* t; + for (t = config_directives; t->name != NULL; ++t) + if (strcmp(s, t->name) == 0) return 1; + return 0; +} + +int config_init() { + config = stringmap_new(); + return config != NULL; +} + +/* read_config_file: + * Read a configuration file consisting of key: value tuples, returning a + * stringmap of the results. Prints errors to stderr, rather than using + * syslog, since this file is called at program startup. Returns 1 on success + * or 0 on failure. */ +int read_config_file(const char *f) { + int ret = 0; + FILE *fp; + char *line; + int i = 1; + + line = xmalloc(MAX_CONFIG_LINE); + + fp = fopen(f, "rt"); + if (!fp) { + fprintf(stderr, "%s: %s\n", f, strerror(errno)); + goto fail; + } + + while (fgets(line, MAX_CONFIG_LINE, fp)) { + char *key, *value, *r; + + for (r = line + strlen(line) - 1; r > line && *r == '\n'; *(r--) = 0); + + /* Get continuation lines. Ugly. */ + while (*(line + strlen(line) - 1) == '\\') { + if (!fgets(line + strlen(line) - 1, MAX_CONFIG_LINE - strlen(line), fp)) + break; + for (r = line + strlen(line) - 1; r > line && *r == '\n'; *(r--) = 0); + } + + /* Strip comment. */ + key = strpbrk(line, "#\n"); + if (key) *key = 0; + + /* foo : bar baz quux + * key^ ^value */ + key = line + strspn(line, " \t"); + value = strchr(line, ':'); + + if (value) { + /* foo : bar baz quux + * key^ ^r ^value */ + ++value; + + r = key + strcspn(key, " \t:"); + if (r != key) { + item *I; + *r = 0; + + /* foo\0: bar baz quux + * key^ ^value ^r */ + value += strspn(value, " \t"); + r = value + strlen(value) - 1; + while (strchr(" \t", *r) && r > value) --r; + *(r + 1) = 0; + + /* (Removed check for zero length value.) */ + + /* Check that this is a valid key. */ + if (!is_cfgdirective_valid(key)) + fprintf(stderr, "%s:%d: warning: unknown directive \"%s\"\n", f, i, key); + else if ((I = stringmap_insert(config, key, item_ptr(xstrdup(value))))) + /* Don't warn of repeated directives, because they + * may have been specified via the command line + * Previous option takes precedence. + */ + fprintf(stderr, "%s:%d: warning: repeated directive \"%s\"\n", f, i, key); + } + } + + memset(line, 0, MAX_CONFIG_LINE); /* security paranoia */ + + ++i; + } + + ret = 1; + +fail: + if (fp) fclose(fp); + if (line) xfree(line); + + return ret; +} + +int config_get_int(const char *directive, int *value) { + stringmap S; + char *s, *t; + + if (!value) return -1; + + S = stringmap_find(config, directive); + if (!S) return 0; + + s = (char*)S->d.v; + if (!*s) return -1; + errno = 0; + *value = strtol(s, &t, 10); + if (*t) return -1; + + return errno == ERANGE ? -1 : 1; +} + +/* config_get_float: + * Get an integer value from a config string. Returns 1 on success, -1 on + * failure, or 0 if no value was found. */ +int config_get_float(const char *directive, float *value) { + item *I; + char *s, *t; + + if (!value) return -1; + + I = stringmap_find(config, directive); + if (!I) return 0; + + s = (char*)I->v; + if (!*s) return -1; + errno = 0; + *value = strtod(s, &t); + if (*t) return -1; + + return errno == ERANGE ? -1 : 1; +} + +/* config_get_string; + * Get a string value from the config file. Returns NULL if it is not + * present. */ +char *config_get_string(const char *directive) { + stringmap S; + + S = stringmap_find(config, directive); + if (S) return (char*)S->d.v; + else return NULL; +} + +/* config_get_bool: + * Get a boolean value from the config file. Returns false if not present. */ +int config_get_bool(const char *directive) { + char *s; + + s = config_get_string(directive); + if (s && (strcmp(s, "yes") == 0 || strcmp(s, "true") == 0)) + return 1; + else + return 0; +} + +/* config_get_enum: + * Get an enumeration value from the config file. Returns false if not + * present or an invalid value is found. */ +int config_get_enum(const char *directive, config_enumeration_type *enumeration, int *value) { + char *s; + config_enumeration_type *t; + s = config_get_string(directive); + if(s) { + for(t = enumeration; t->name; t++) { + if(strcmp(s,t->name) == 0) { + *value = t->value; + return 1; + } + } + fprintf(stderr,"Invalid enumeration value \"%s\" for directive \"%s\"\n", s, directive); + } + return 0; +} + +/* config_set_string; Sets a value in the config, possibly overriding + * an existing value + */ +void config_set_string(const char *directive, const char* s) { + stringmap S; + + S = stringmap_find(config, directive); + if (S) stringmap_delete_free(S); + stringmap_insert(config, directive, item_ptr(xstrdup(s))); +} + +int read_config(char *file) { + config_item_type* t; + void* o; + + read_config_file(file); + if(config == NULL) { + fprintf(stderr,"Unable to read config file\n"); + return 0; + } + return 1; +} |