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>