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>