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