Annotation of embedaddon/iftop/cfgfile.c, revision 1.1
1.1 ! misho 1: /*
! 2: * cfgfile.c:
! 3: *
! 4: * Copyright (c) 2003 DecisionSoft Ltd.
! 5: *
! 6: */
! 7:
! 8: #include <stdio.h>
! 9: #include <string.h>
! 10: #include <errno.h>
! 11:
! 12: #include "stringmap.h"
! 13: #include "iftop.h"
! 14: #include "options.h"
! 15: #include "cfgfile.h"
! 16:
! 17: #define CONFIG_TYPE_STRING 0
! 18: #define CONFIG_TYPE_BOOL 1
! 19: #define CONFIG_TYPE_INT 2
! 20:
! 21: #define MAX_CONFIG_LINE 2048
! 22:
! 23: char * config_directives[] = {
! 24: "interface",
! 25: "dns-resolution",
! 26: "port-resolution",
! 27: "filter-code",
! 28: "show-bars",
! 29: "promiscuous",
! 30: "hide-source",
! 31: "hide-destination",
! 32: "use-bytes",
! 33: "sort",
! 34: "line-display",
! 35: "show-totals",
! 36: "log-scale",
! 37: "max-bandwidth",
! 38: "net-filter",
! 39: "port-display",
! 40: NULL
! 41: };
! 42:
! 43: stringmap config;
! 44:
! 45: extern options_t options ;
! 46:
! 47: int is_cfgdirective_valid(const char *s) {
! 48: char **t;
! 49: for (t = config_directives; *t != NULL; ++t)
! 50: if (strcmp(s, *t) == 0) return 1;
! 51: return 0;
! 52: }
! 53:
! 54: int config_init() {
! 55: config = stringmap_new();
! 56: return config != NULL;
! 57: }
! 58:
! 59: /* read_config_file:
! 60: * Read a configuration file consisting of key: value tuples, returning a
! 61: * stringmap of the results. Prints errors to stderr, rather than using
! 62: * syslog, since this file is called at program startup. Returns 1 on success
! 63: * or 0 on failure. */
! 64: int read_config_file(const char *f, int whinge) {
! 65: int ret = 0;
! 66: FILE *fp;
! 67: char *line;
! 68: int i = 1;
! 69:
! 70: line = xmalloc(MAX_CONFIG_LINE);
! 71:
! 72: fp = fopen(f, "rt");
! 73: if (!fp) {
! 74: if(whinge) fprintf(stderr, "%s: %s\n", f, strerror(errno));
! 75: goto fail;
! 76: }
! 77:
! 78: while (fgets(line, MAX_CONFIG_LINE, fp)) {
! 79: char *key, *value, *r;
! 80:
! 81: for (r = line + strlen(line) - 1; r > line && *r == '\n'; *(r--) = 0);
! 82:
! 83: /* Get continuation lines. Ugly. */
! 84: while (*(line + strlen(line) - 1) == '\\') {
! 85: if (!fgets(line + strlen(line) - 1, MAX_CONFIG_LINE - strlen(line), fp))
! 86: break;
! 87: for (r = line + strlen(line) - 1; r > line && *r == '\n'; *(r--) = 0);
! 88: }
! 89:
! 90: /* Strip comment. */
! 91: key = strpbrk(line, "#\n");
! 92: if (key) *key = 0;
! 93:
! 94: /* foo : bar baz quux
! 95: * key^ ^value */
! 96: key = line + strspn(line, " \t");
! 97: value = strchr(line, ':');
! 98:
! 99: if (value) {
! 100: /* foo : bar baz quux
! 101: * key^ ^r ^value */
! 102: ++value;
! 103:
! 104: r = key + strcspn(key, " \t:");
! 105: if (r != key) {
! 106: item *I;
! 107: *r = 0;
! 108:
! 109: /* foo\0: bar baz quux
! 110: * key^ ^value ^r */
! 111: value += strspn(value, " \t");
! 112: r = value + strlen(value) - 1;
! 113: while (strchr(" \t", *r) && r > value) --r;
! 114: *(r + 1) = 0;
! 115:
! 116: /* (Removed check for zero length value.) */
! 117:
! 118: /* Check that this is a valid key. */
! 119: if (!is_cfgdirective_valid(key))
! 120: fprintf(stderr, "%s:%d: warning: unknown directive \"%s\"\n", f, i, key);
! 121: else if ((I = stringmap_insert(config, key, item_ptr(xstrdup(value)))))
! 122: /* Don't warn of repeated directives, because they
! 123: * may have been specified via the command line
! 124: * Previous option takes precedence.
! 125: */
! 126: fprintf(stderr, "%s:%d: warning: repeated directive \"%s\"\n", f, i, key);
! 127: }
! 128: }
! 129:
! 130: memset(line, 0, MAX_CONFIG_LINE); /* security paranoia */
! 131:
! 132: ++i;
! 133: }
! 134:
! 135: ret = 1;
! 136:
! 137: fail:
! 138: if (fp) fclose(fp);
! 139: if (line) xfree(line);
! 140:
! 141: return ret;
! 142: }
! 143:
! 144: int config_get_int(const char *directive, int *value) {
! 145: stringmap S;
! 146: char *s, *t;
! 147:
! 148: if (!value) return -1;
! 149:
! 150: S = stringmap_find(config, directive);
! 151: if (!S) return 0;
! 152:
! 153: s = (char*)S->d.v;
! 154: if (!*s) return -1;
! 155: errno = 0;
! 156: *value = strtol(s, &t, 10);
! 157: if (*t) return -1;
! 158:
! 159: return errno == ERANGE ? -1 : 1;
! 160: }
! 161:
! 162: /* config_get_float:
! 163: * Get an integer value from a config string. Returns 1 on success, -1 on
! 164: * failure, or 0 if no value was found. */
! 165: int config_get_float(const char *directive, float *value) {
! 166: stringmap S;
! 167: item *I;
! 168: char *s, *t;
! 169:
! 170: if (!value) return -1;
! 171:
! 172: if (!(S = stringmap_find(config, directive)))
! 173: return 0;
! 174:
! 175: s = (char*)S->d.v;
! 176: if (!*s) return -1;
! 177: errno = 0;
! 178: *value = strtod(s, &t);
! 179: if (*t) return -1;
! 180:
! 181: return errno == ERANGE ? -1 : 1;
! 182: }
! 183:
! 184: /* config_get_string;
! 185: * Get a string value from the config file. Returns NULL if it is not
! 186: * present. */
! 187: char *config_get_string(const char *directive) {
! 188: stringmap S;
! 189:
! 190: S = stringmap_find(config, directive);
! 191: if (S) return (char*)S->d.v;
! 192: else return NULL;
! 193: }
! 194:
! 195: /* config_get_bool:
! 196: * Get a boolean value from the config file. Returns false if not present. */
! 197: int config_get_bool(const char *directive) {
! 198: char *s;
! 199:
! 200: s = config_get_string(directive);
! 201: if (s && (strcmp(s, "yes") == 0 || strcmp(s, "true") == 0))
! 202: return 1;
! 203: else
! 204: return 0;
! 205: }
! 206:
! 207: /* config_get_enum:
! 208: * Get an enumeration value from the config file. Returns false if not
! 209: * present or an invalid value is found. */
! 210: int config_get_enum(const char *directive, config_enumeration_type *enumeration, int *value) {
! 211: char *s;
! 212: config_enumeration_type *t;
! 213: s = config_get_string(directive);
! 214: if(s) {
! 215: for(t = enumeration; t->name; t++) {
! 216: if(strcmp(s,t->name) == 0) {
! 217: *value = t->value;
! 218: return 1;
! 219: }
! 220: }
! 221: fprintf(stderr,"Invalid enumeration value \"%s\" for directive \"%s\"\n", s, directive);
! 222: }
! 223: return 0;
! 224: }
! 225:
! 226: /* config_set_string; Sets a value in the config, possibly overriding
! 227: * an existing value
! 228: */
! 229: void config_set_string(const char *directive, const char* s) {
! 230: stringmap S;
! 231:
! 232: S = stringmap_find(config, directive);
! 233: if (S) stringmap_delete_free(S);
! 234: stringmap_insert(config, directive, item_ptr(xstrdup(s)));
! 235: }
! 236:
! 237: int read_config(char *file, int whinge_on_error) {
! 238: void* o;
! 239:
! 240: return read_config_file(file, whinge_on_error);
! 241: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>