File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / iftop / cfgfile.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 18 14:04:50 2016 UTC (7 years, 8 months ago) by misho
Branches: iftop, MAIN
CVS tags: v1_0rc4, HEAD
iftop 1.0pre4

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>