File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bmon / src / conf.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:19:56 2012 UTC (12 years, 4 months ago) by misho
Branches: bmon, MAIN
CVS tags: v2_1_0p0, v2_1_0, HEAD
bmon

    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>