Annotation of embedaddon/iftop/cfgfile.c, revision 1.1.1.2

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>
1.1.1.2 ! misho      11: #include <stdlib.h>
1.1       misho      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", 
1.1.1.2 ! misho      40:        "net-filter6", 
        !            41:         "link-local",
1.1       misho      42:        "port-display", 
1.1.1.2 ! misho      43:        "timed-output",
        !            44:        "no-curses",
        !            45:        "num-lines",
1.1       misho      46:        NULL
                     47: };
                     48: 
                     49: stringmap config;
                     50: 
                     51: extern options_t options ;
                     52: 
                     53: int is_cfgdirective_valid(const char *s) {
1.1.1.2 ! misho      54:     int t;
        !            55:     for (t = 0; config_directives[t] != NULL; t++)
        !            56:        if (strcmp(s, config_directives[t]) == 0) return 1;
1.1       misho      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);
1.1.1.2 ! misho     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:     }
1.1       misho     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>