123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- /*
- * cfgfile.c:
- *
- * Copyright (c) 2003 DecisionSoft Ltd.
- *
- */
- #include <stdio.h>
- #include <string.h>
- #include <errno.h>
- #include <stdlib.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
- char * config_directives[] = {
- "interface",
- "dns-resolution",
- "port-resolution",
- "filter-code",
- "show-bars",
- "promiscuous",
- "hide-source",
- "hide-destination",
- "use-bytes",
- "sort",
- "line-display",
- "show-totals",
- "log-scale",
- "max-bandwidth",
- "net-filter",
- "net-filter6",
- "link-local",
- "port-display",
- "timed-output",
- "no-curses",
- "num-lines",
- NULL
- };
- stringmap config;
- extern options_t options ;
- int is_cfgdirective_valid(const char *s) {
- int t;
- for (t = 0; config_directives[t] != NULL; t++)
- if (strcmp(s, config_directives[t]) == 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 whinge) {
- int ret = 0;
- FILE *fp;
- char *line;
- int i = 1;
- line = xmalloc(MAX_CONFIG_LINE);
- fp = fopen(f, "rt");
- if (!fp) {
- if(whinge) 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) {
- stringmap S;
- char *s, *t;
- if (!value) return -1;
- if (!(S = stringmap_find(config, directive)))
- return 0;
- s = (char*)S->d.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) {
- xfree(S->d.v);
- S->d = item_ptr(xstrdup(s));
- }
- else {
- stringmap_insert(config, directive, item_ptr(xstrdup(s)));
- }
- }
- int read_config(char *file, int whinge_on_error) {
- return read_config_file(file, whinge_on_error);
- }
|