Annotation of embedaddon/bmon/src/conf.c, revision 1.1.1.1
1.1 misho 1: /*
2: * conf.c Config Crap
3: *
4: * Copyright (c) 2001-2005 Thomas Graf <tgraf@suug.ch>
5: *
6: * Permission is hereby granted, free of charge, to any person obtaining a
7: * copy of this software and associated documentation files (the "Software"),
8: * to deal in the Software without restriction, including without limitation
9: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10: * and/or sell copies of the Software, and to permit persons to whom the
11: * Software is furnished to do so, subject to the following conditions:
12: *
13: * The above copyright notice and this permission notice shall be included
14: * in all copies or substantial portions of the Software.
15: *
16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22: * DEALINGS IN THE SOFTWARE.
23: */
24:
25: #include <bmon/bmon.h>
26: #include <bmon/conf.h>
27: #include <bmon/bindings.h>
28: #include <bmon/input.h>
29: #include <bmon/output.h>
30: #include <bmon/utils.h>
31:
32: static int show_only_running = 1;
33: static int do_signal_output = 0;
34: static char fg_char = '*';
35: static char bg_char = '.';
36: static char noise_char = ':';
37: static char unk_char = '?';
38: static y_unit_t y_unit = Y_DYNAMIC;
39: static x_unit_t x_unit = X_SEC;
40: static char * configfile = NULL;
41: static float read_interval = 1.0f;
42: static unsigned long sleep_time = 20000;
43: static int use_si = 0;
44: static int ngraphs = 1;
45: static float hb_factor = 0.1;
46: static float rate_interval = 1.0f;
47: static float lifetime = 30.0f;
48: static char * itemtabfile = "/etc/bmon/itemtab";
49:
50: #if defined HAVE_CURSES
51: #if defined HAVE_USE_DEFAULT_COLORS
52: layout_t layout[] =
53: {
54: {-1, -1, 0}, /* dummy, not used */
55: {-1, -1, 0}, /* default */
56: {-1, -1, A_REVERSE}, /* statusbar */
57: {-1, -1, 0}, /* header */
58: {-1, -1, 0}, /* list */
59: {-1, -1, A_REVERSE}, /* selected */
60: };
61: #else
62: layout_t layout[] =
63: {
64: {0, 0, 0}, /* dummy, not used */
65: {COLOR_BLACK, COLOR_WHITE, 0}, /* default */
66: {COLOR_BLACK, COLOR_WHITE, A_REVERSE}, /* statusbar */
67: {COLOR_BLACK, COLOR_WHITE, 0}, /* header */
68: {COLOR_BLACK, COLOR_WHITE, 0}, /* list */
69: {COLOR_BLACK, COLOR_WHITE, A_REVERSE}, /* selected */
70: };
71: #endif
72: #endif
73:
74: #define SPLIT(str, var) \
75: do { \
76: char *s; \
77: for (s = str; *s; s++) { \
78: if (*s == ' ' || *s == '\t') \
79: break; \
80: } \
81: if (!*s) \
82: break; \
83: *s = '\0'; \
84: for (++s;*s == ' ' || *s == '\t'; s++); \
85: if (!*s) \
86: break; \
87: var = s; \
88: } while(0);
89:
90: static void conf_read(const char *);
91:
92: static inline void parse_include(char *buf)
93: {
94: conf_read(buf);
95: }
96:
97: #if defined HAVE_CURSES
98: static int parse_color(const char *color)
99: {
100: if (!strcmp(color, "default"))
101: return -1;
102: else if (!strcasecmp(color, "black"))
103: return COLOR_BLACK;
104: else if (!strcasecmp(color, "red"))
105: return COLOR_RED;
106: else if (!strcasecmp(color, "green"))
107: return COLOR_GREEN;
108: else if (!strcasecmp(color, "yellow"))
109: return COLOR_YELLOW;
110: else if (!strcasecmp(color, "blue"))
111: return COLOR_BLUE;
112: else if (!strcasecmp(color, "magenta"))
113: return COLOR_MAGENTA;
114: else if (!strcasecmp(color, "cyan"))
115: return COLOR_CYAN;
116: else if (!strcasecmp(color, "white"))
117: return COLOR_WHITE;
118: else
119: return -1;
120: }
121:
122: static void parse_layout(char *buf)
123: {
124: char *id, *fg = NULL, *bg = NULL, *attr, *s;
125: layout_t l;
126:
127: id = buf;
128: SPLIT(buf, fg)
129: SPLIT(fg, bg)
130:
131: for (s = bg; *s; s++) {
132: if (*s == ' ' || *s == '\t')
133: break;
134: }
135:
136: if (*s) {
137: *s = '\0';
138: s++;
139:
140: for (; *s == ' ' || *s == '\t'; s++);
141: if (*s)
142: attr = s;
143: else
144: attr = NULL;
145: }
146: else
147: attr = NULL;
148:
149: if ((l.fg = parse_color(fg)) == -1)
150: return;
151:
152: if ((l.bg = parse_color(bg)) == -1)
153: return;
154:
155: l.attr = 0;
156:
157: if (attr)
158: {
159: if (!strcasecmp(attr, "reverse"))
160: l.attr |= A_REVERSE;
161: else if (!strcasecmp(attr, "bold"))
162: l.attr |= A_BOLD;
163: else if (!strcasecmp(attr, "underline"))
164: l.attr |= A_UNDERLINE;
165: }
166:
167: #define COPY_LAYOUT(id) do { \
168: layout[id].fg = l.fg; \
169: layout[id].bg = l.bg; \
170: layout[id].attr = l.attr; \
171: } while (0);
172:
173: if (!strcasecmp(id, "default"))
174: COPY_LAYOUT(LAYOUT_DEFAULT)
175: else if (!strcasecmp(id, "statusbar"))
176: COPY_LAYOUT(LAYOUT_STATUSBAR)
177: else if (!strcasecmp(id, "header"))
178: COPY_LAYOUT(LAYOUT_HEADER)
179: else if (!strcasecmp(id, "list"))
180: COPY_LAYOUT(LAYOUT_LIST)
181: else if (!strcasecmp(id, "selected"))
182: COPY_LAYOUT(LAYOUT_SELECTED)
183:
184: #undef COPY_LAYOUT
185: }
186: #endif
187:
188: static void parse_bind(char *buf)
189: {
190: char *ch, *cmd = NULL, *args, *s;
191: binding_t *b;
192: int i;
193:
194: ch = buf;
195: SPLIT(buf, cmd);
196: args = strdup(cmd);
197:
198: b = xcalloc(1, sizeof(binding_t));
199: b->args[0] = args;
200:
201: for (s = args, i = 1; i < 255; i++) {
202: s = strchr (s, ' ');
203: if (s) {
204: *s = '\0';
205: s++;
206: b->args[i] = s;
207: } else
208: break;
209: }
210:
211: b->args[i] = NULL;
212:
213: b->ch = ch[0];
214: b->cmd = strdup(b->args[0]);
215:
216: add_binding(b);
217: }
218:
219: void conf_parse_option(const char *id, const char *value)
220: {
221: #define MATCH(STR) if (!strcasecmp(id, STR))
222: MATCH("input")
223: set_input(value);
224: else MATCH("secondary_input")
225: set_sec_input(value);
226: else MATCH("output")
227: set_output(value);
228: else MATCH("secondary_output")
229: set_sec_output(value);
230: else MATCH("policy")
231: item_parse_policy(value);
232: else MATCH("read_interval")
233: set_read_interval(value);
234: else MATCH("sleep_time")
235: set_sleep_time(value);
236: else MATCH("show_all")
237: set_show_only_running(0);
238: else MATCH("use_si")
239: set_use_si();
240: else MATCH("nr_graphs")
241: set_ngraphs(strtol(value, NULL, 0));
242: else MATCH("heartbeat_factor")
243: set_hb_factor(value);
244: else MATCH("rate_interval")
245: set_rate_interval(value);
246: else MATCH("lifetime")
247: set_lifetime(value);
248: else MATCH("itemtab")
249: set_itemtab(value);
250: #undef MATCH
251: }
252:
253: tv_t * parse_tv(char *data)
254: {
255: char *value;
256: tv_t *tv = xcalloc(1, sizeof(tv_t));
257:
258: value = strchr(data, '=');
259:
260: if (value) {
261: *value = '\0';
262: ++value;
263: tv->value = strdup(value);
264: }
265:
266: tv->type = strdup(data);
267: return tv;
268: }
269:
270: module_conf_t * parse_module(char *data)
271: {
272: char *name = data, *opts = data, *next;
273: module_conf_t *m;
274:
275: if (!*name)
276: quit("No module name given");
277:
278: m = xcalloc(1, sizeof(module_conf_t));
279:
280: opts = strchr(data, ':');
281:
282: if (opts) {
283: *opts = '\0';
284: opts++;
285:
286: do {
287: tv_t *tv;
288: next = strchr(opts, ';');
289:
290: if (next) {
291: *next = '\0';
292: ++next;
293: }
294:
295: tv = parse_tv(opts);
296:
297: tv->next = m->attrs;
298: m->attrs = tv;
299:
300: opts = next;
301: } while(next);
302: }
303:
304: m->name = strdup(name);
305: return m;
306: }
307:
308:
309: module_conf_t * parse_module_param(const char *data)
310: {
311: char *buf = strdup(data);
312: char *next;
313: char *current = buf;
314: module_conf_t *m, *list = NULL;
315:
316: do {
317: next = strchr(current, ',');
318:
319: if (next) {
320: *next = '\0';
321: ++next;
322: }
323:
324: m = parse_module(current);
325:
326: if (m) {
327: m->next = list;
328: list = m;
329: }
330:
331: current = next;
332: } while (next);
333:
334: free(buf);
335:
336: return list;
337: }
338:
339:
340: static inline void parse_config_line(char *buf)
341: {
342: char *tok = NULL;
343:
344: SPLIT(buf, tok);
345: if (!strcasecmp(buf, "include"))
346: parse_include(tok);
347: #if defined HAVE_CURSES
348: else if (!strcasecmp(buf, "layout"))
349: parse_layout(tok);
350: #endif
351: else if (!strcasecmp(buf, "bind"))
352: parse_bind(tok);
353: else
354: conf_parse_option(buf, tok);
355: }
356:
357: static void conf_read(const char *path)
358: {
359: FILE *f;
360: char buf[1024];
361:
362: if (!(f = fopen(path, "r")))
363: return;
364:
365: memset(buf, 0, sizeof(buf));
366:
367: while (fgets(buf, sizeof(buf), f)) {
368: char *p;
369:
370: if ('#' == *buf)
371: goto skip;
372:
373: if ((p = strchr(buf, '\r')))
374: *p = '\0';
375:
376: if ((p = strchr(buf, '\n')))
377: *p = '\0';
378:
379: if (*buf)
380: parse_config_line(buf);
381:
382: skip:
383: memset(buf, 0, sizeof(buf));
384: }
385:
386: fclose(f);
387: }
388:
389: void read_configfile(void)
390: {
391: if (configfile)
392: conf_read(configfile);
393: else {
394: conf_read("/etc/bmon.conf");
395:
396: if (getenv("HOME")) {
397: char path[FILENAME_MAX+1];
398: snprintf(path, sizeof(path), "%s/.bmonrc", getenv("HOME"));
399: conf_read(path);
400: }
401: }
402: }
403:
404:
405: inline void set_configfile(const char *file)
406: {
407: static int set = 0;
408: if (!set) {
409: configfile = strdup(file);
410: set = 1;
411: }
412: }
413:
414: inline void set_itemtab(const char *file)
415: {
416: static int set = 0;
417: if (!set) {
418: itemtabfile = strdup(file);
419: set = 1;
420: }
421: }
422:
423: inline char *get_itemtab(void)
424: {
425: return itemtabfile;
426: }
427:
428: inline void set_read_interval(const char *i)
429: {
430: static int set = 0;
431: if (!set) {
432: read_interval = (float) strtod(i, NULL);
433: set = 1;
434: }
435: }
436:
437: inline float get_read_interval(void)
438: {
439: return read_interval;
440: }
441:
442: inline void get_read_interval_as_ts(timestamp_t *ts)
443: {
444: float_to_ts(ts, read_interval);
445: }
446:
447:
448: inline void set_x_unit(const char *x, int force)
449: {
450: static int set = 0;
451: if (!set || force) {
452: if (tolower(*x) == 's')
453: x_unit = X_SEC;
454: else if (tolower(*x) == 'm')
455: x_unit = X_MIN;
456: else if (tolower(*x) == 'h')
457: x_unit = X_HOUR;
458: else if (tolower(*x) == 'd')
459: x_unit = X_DAY;
460: else if (tolower(*x) == 'r')
461: x_unit = X_READ;
462: else
463: quit("Unknown X-axis unit '%s'\n", x);
464: set = 1;
465: }
466: }
467:
468: inline x_unit_t get_x_unit(void)
469: {
470: return x_unit;
471: }
472:
473: inline void set_y_unit(const char *y)
474: {
475: static int set = 0;
476: if (!set) {
477: if (tolower(*y) == 'b')
478: y_unit = Y_BYTE;
479: else if (tolower(*y) == 'k')
480: y_unit = Y_KILO;
481: else if (tolower(*y) == 'm')
482: y_unit = Y_MEGA;
483: else if (tolower(*y) == 'g')
484: y_unit = Y_GIGA;
485: else if (tolower(*y) == 't')
486: y_unit = Y_TERA;
487: else
488: quit("Unknown Y-axis unit '%s'\n", y);
489: set = 1;
490: }
491: }
492:
493: inline y_unit_t get_y_unit(void)
494: {
495: return y_unit;
496: }
497:
498:
499: inline char get_fg_char(void)
500: {
501: return fg_char;
502: }
503:
504: inline void set_fg_char(char c)
505: {
506: static int set = 0;
507: if (!set) {
508: fg_char = c;
509: set = 1;
510: }
511: }
512:
513: inline char get_unk_char(void)
514: {
515: return unk_char;
516: }
517:
518: inline void set_unk_char(char c)
519: {
520: static int set = 0;
521: if (!set) {
522: unk_char = c;
523: set = 1;
524: }
525: }
526:
527: inline char get_bg_char(void)
528: {
529: return bg_char;
530: }
531:
532: inline void set_bg_char(char c)
533: {
534: static int set = 0;
535: if (!set) {
536: bg_char = c;
537: set = 1;
538: }
539: }
540:
541: inline char get_noise_char(void)
542: {
543: return noise_char;
544: }
545:
546: inline void set_noise_char(char c)
547: {
548: static int set = 0;
549: if (!set) {
550: noise_char = c;
551: set = 1;
552: }
553: }
554:
555: inline void set_sleep_time(const char *s)
556: {
557: static int set = 0;
558: if (!set) {
559: double d = strtod(s, NULL);
560: sleep_time = (unsigned long) (d * 1000000.0f);
561: set = 1;
562: }
563: }
564:
565: inline unsigned long get_sleep_time(void)
566: {
567: return sleep_time;
568: }
569:
570: inline void set_signal_output(int i)
571: {
572: static int set = 0;
573: if (!set) {
574: do_signal_output = i;
575: set = 1;
576: }
577: }
578:
579: inline int get_signal_output(void)
580: {
581: return do_signal_output;
582: }
583:
584: inline void set_show_only_running(int i)
585: {
586: static int set = 0;
587: if (!set) {
588: show_only_running = i;
589: set = 1;
590: }
591: }
592:
593: inline int get_show_only_running(void)
594: {
595: return show_only_running;
596: }
597:
598: inline void set_use_si(void)
599: {
600: use_si = 1;
601: }
602:
603: inline int get_use_si(void)
604: {
605: return use_si;
606: }
607:
608: inline void set_ngraphs(int n)
609: {
610: static int set = 0;
611: if (!set) {
612: ngraphs = n;
613: set = 1;
614: }
615: }
616:
617: inline int get_ngraphs(void)
618: {
619: return ngraphs;
620: }
621:
622: inline float get_hb_factor(void)
623: {
624: return hb_factor;
625: }
626:
627: inline void set_hb_factor(const char *s)
628: {
629: static int set = 0;
630: if (!set) {
631: hb_factor = strtod(s, NULL);
632: set = 1;
633: }
634: }
635:
636: inline void set_rate_interval(const char *i)
637: {
638: static int set = 0;
639: if (!set) {
640: rate_interval = (float) strtod(i, NULL);
641: set = 1;
642: }
643: }
644:
645: inline float get_rate_interval(void)
646: {
647: return rate_interval;
648: }
649:
650: inline void set_lifetime(const char *i)
651: {
652: static int set = 0;
653: if (!set) {
654: lifetime = (float) strtod(i, NULL);
655: set = 1;
656: }
657: }
658:
659: inline float get_lifetime(void)
660: {
661: return lifetime / read_interval;
662: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>