File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bmon / src / conf.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 21 14:58:35 2019 UTC (4 years, 8 months ago) by misho
Branches: bmon, MAIN
CVS tags: v4_0p0, HEAD
bmon ver 4.0

    1: /*
    2:  * conf.c        Config Crap
    3:  *
    4:  * Copyright (c) 2001-2013 Thomas Graf <tgraf@suug.ch>
    5:  * Copyright (c) 2013 Red Hat, Inc.
    6:  *
    7:  * Permission is hereby granted, free of charge, to any person obtaining a
    8:  * copy of this software and associated documentation files (the "Software"),
    9:  * to deal in the Software without restriction, including without limitation
   10:  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   11:  * and/or sell copies of the Software, and to permit persons to whom the
   12:  * Software is furnished to do so, subject to the following conditions:
   13:  *
   14:  * The above copyright notice and this permission notice shall be included
   15:  * in all copies or substantial portions of the Software.
   16:  *
   17:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   18:  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   19:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   20:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   21:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   22:  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   23:  * DEALINGS IN THE SOFTWARE.
   24:  */
   25: 
   26: #include <bmon/bmon.h>
   27: #include <bmon/conf.h>
   28: #include <bmon/unit.h>
   29: #include <bmon/attr.h>
   30: #include <bmon/element.h>
   31: #include <bmon/element_cfg.h>
   32: #include <bmon/history.h>
   33: #include <bmon/layout.h>
   34: #include <bmon/utils.h>
   35: 
   36: cfg_t *cfg;
   37: 
   38: static cfg_opt_t element_opts[] = {
   39: 	CFG_STR("description", NULL, CFGF_NONE),
   40: 	CFG_BOOL("show", cfg_true, CFGF_NONE),
   41: 	CFG_INT("rxmax", 0, CFGF_NONE),
   42: 	CFG_INT("txmax", 0, CFGF_NONE),
   43: 	CFG_INT("max", 0, CFGF_NONE),
   44: 	CFG_END()
   45: };
   46: 
   47: static cfg_opt_t history_opts[] = {
   48: 	CFG_FLOAT("interval", 1.0f, CFGF_NONE),
   49: 	CFG_INT("size", 60, CFGF_NONE),
   50: 	CFG_STR("type", "64bit", CFGF_NONE),
   51: 	CFG_END()
   52: };
   53: 
   54: static cfg_opt_t attr_opts[] = {
   55: 	CFG_STR("description", "", CFGF_NONE),
   56: 	CFG_STR("unit", "", CFGF_NONE),
   57: 	CFG_STR("type", "counter", CFGF_NONE),
   58: 	CFG_BOOL("history", cfg_false, CFGF_NONE),
   59: 	CFG_END()
   60: };
   61: 
   62: static cfg_opt_t variant_opts[] = {
   63: 	CFG_FLOAT_LIST("div", "{}", CFGF_NONE),
   64: 	CFG_STR_LIST("txt", "", CFGF_NONE),
   65: 	CFG_END()
   66: };
   67: 
   68: static cfg_opt_t unit_opts[] = {
   69: 	CFG_SEC("variant", variant_opts, CFGF_MULTI | CFGF_TITLE),
   70: 	CFG_END()
   71: };
   72: 
   73: static cfg_opt_t color_opts[] = {
   74:     CFG_STR_LIST("color_pair", "", CFGF_NONE),
   75:     CFG_END()
   76: };
   77: 
   78: static cfg_opt_t layout_opts[] = {
   79:     CFG_SEC("color", color_opts, CFGF_MULTI | CFGF_TITLE),
   80:     CFG_END()
   81: };
   82: 
   83: static cfg_opt_t global_opts[] = {
   84: 	CFG_FLOAT("read_interval", 1.0f, CFGF_NONE),
   85: 	CFG_FLOAT("rate_interval", 1.0f, CFGF_NONE),
   86: 	CFG_FLOAT("lifetime", 30.0f, CFGF_NONE),
   87: 	CFG_FLOAT("history_variance", 0.1f, CFGF_NONE),
   88: 	CFG_FLOAT("variance", 0.1f, CFGF_NONE),
   89: 	CFG_BOOL("show_all", cfg_false, CFGF_NONE),
   90: 	CFG_INT("unit_exp", -1, CFGF_NONE),
   91: 	CFG_INT("sleep_time", 20000UL, CFGF_NONE),
   92: 	CFG_BOOL("use_si", 0, CFGF_NONE),
   93: 	CFG_BOOL("use_bit", 0, CFGF_NONE),
   94: 	CFG_STR("uid", NULL, CFGF_NONE),
   95: 	CFG_STR("gid", NULL, CFGF_NONE),
   96: 	CFG_STR("policy", "", CFGF_NONE),
   97: 	CFG_SEC("unit", unit_opts, CFGF_MULTI | CFGF_TITLE),
   98: 	CFG_SEC("attr", attr_opts, CFGF_MULTI | CFGF_TITLE),
   99: 	CFG_SEC("history", history_opts, CFGF_MULTI | CFGF_TITLE),
  100: 	CFG_SEC("element", element_opts, CFGF_MULTI | CFGF_TITLE),
  101:     CFG_SEC("layout", layout_opts, CFGF_MULTI | CFGF_TITLE),
  102: 	CFG_END()
  103: };
  104: 
  105: float			cfg_read_interval;
  106: float			cfg_rate_interval;
  107: float			cfg_rate_variance;
  108: float			cfg_history_variance;
  109: int			cfg_show_all;
  110: int			cfg_unit_exp		= DYNAMIC_EXP;
  111: 
  112: static char *		configfile		= NULL;
  113: 
  114: #if defined HAVE_CURSES
  115: #if defined HAVE_USE_DEFAULT_COLORS
  116: struct layout cfg_layout[] =
  117: {
  118:     {-1, -1, 0},            /* dummy, not used */
  119:     {-1, -1, 0},            /* default */
  120:     {-1, -1, A_REVERSE},    /* statusbar */
  121:     {-1, -1, 0},            /* header */
  122:     {-1, -1, 0},            /* list */
  123:     {-1, -1, A_REVERSE},    /* selected */
  124:     {-1, -1, 0},            /* RX graph */
  125:     {-1, -1, 0},            /* TX graph */
  126: };
  127: #else
  128: struct layout cfg_layout[] =
  129: {
  130: 	{0, 0, 0},                               /* dummy, not used */
  131: 	{COLOR_WHITE, COLOR_BLACK, 0},           /* default */
  132: 	{COLOR_BLUE,   COLOR_GREEN, A_REVERSE},  /* statusbar */
  133: 	{COLOR_GREEN,  COLOR_BLACK, 0},          /* header */
  134: 	{COLOR_WHITE,  COLOR_BLACK, 0},          /* list */
  135: 	{COLOR_YELLOW, COLOR_BLACK, A_REVERSE},  /* selected */
  136:     {COLOR_GREEN,  COLOR_BLACK, 0},          /* RX graph */
  137:     {COLOR_RED,    COLOR_BLACK, 0},          /* TX graph */
  138: };
  139: #endif
  140: #endif
  141: 
  142: tv_t * parse_tv(char *data)
  143: {
  144: 	char *value;
  145: 	tv_t *tv = xcalloc(1, sizeof(tv_t));
  146: 
  147: 	init_list_head(&tv->tv_list);
  148: 
  149: 	value = strchr(data, '=');
  150: 
  151: 	if (value) {
  152: 		*value = '\0';
  153: 		++value;
  154: 		tv->tv_value = strdup(value);
  155: 	}
  156: 
  157: 	tv->tv_type = strdup(data);
  158: 	return tv;
  159: }
  160: 
  161: module_conf_t * parse_module(char *data)
  162: {
  163: 	char *name = data, *opts = data, *next;
  164: 	module_conf_t *m;
  165: 
  166: 	if (!*name)
  167: 		quit("No module name given");
  168: 
  169: 	m = xcalloc(1, sizeof(module_conf_t));
  170: 
  171: 	init_list_head(&m->m_attrs);
  172: 
  173: 	opts = strchr(data, ':');
  174: 
  175: 	if (opts) {
  176: 		*opts = '\0';
  177: 		opts++;
  178: 
  179: 		do {
  180: 			tv_t *tv;
  181: 			next = strchr(opts, ';');
  182: 
  183: 			if (next) {
  184: 				*next = '\0';
  185: 				++next;
  186: 			}
  187: 
  188: 			tv = parse_tv(opts);
  189: 			list_add_tail(&tv->tv_list, &m->m_attrs);
  190: 
  191: 			opts = next;
  192: 		} while(next);
  193: 	}
  194: 
  195: 	m->m_name = strdup(name);
  196: 	return m;
  197: }
  198: 
  199: 
  200: int parse_module_param(const char *data, struct list_head *list)
  201: {
  202: 	char *buf = strdup(data);
  203: 	char *next;
  204: 	char *current = buf;
  205: 	module_conf_t *m;
  206: 	int n = 0;
  207: 	
  208: 	do {
  209: 		next = strchr(current, ',');
  210: 
  211: 		if (next) {
  212: 			*next = '\0';
  213: 			++next;
  214: 		}
  215: 
  216: 		m = parse_module(current);
  217: 		if (m) {
  218: 			list_add_tail(&m->m_list, list);
  219: 			n++;
  220: 		}
  221: 
  222: 		current = next;
  223: 	} while (next);
  224: 
  225: 	free(buf);
  226: 
  227: 	return n;
  228: }
  229: 
  230: static void configfile_read_history(void)
  231: {
  232: 	int i, nhistory;
  233: 
  234: 	nhistory = cfg_size(cfg, "history");
  235: 
  236: 	for (i = 0; i < nhistory; i++) {
  237: 		struct history_def *def;
  238: 		cfg_t *history;
  239: 		const char *name, *type;
  240: 		float interval;
  241: 		int size;
  242: 
  243: 		if (!(history = cfg_getnsec(cfg, "history", i)))
  244: 			BUG();
  245: 
  246: 		if (!(name = cfg_title(history)))
  247: 			BUG();
  248: 
  249: 		interval = cfg_getfloat(history, "interval");
  250: 		size = cfg_getint(history, "size");
  251: 		type = cfg_getstr(history, "type");
  252: 
  253: 		if (interval == 0.0f)
  254: 			interval = cfg_getfloat(cfg, "read_interval");
  255: 
  256: 		def = history_def_alloc(name);
  257: 		def->hd_interval = interval;
  258: 		def->hd_size = size;
  259: 
  260: 		if (!strcasecmp(type, "8bit"))
  261: 			def->hd_type = HISTORY_TYPE_8;
  262: 		else if (!strcasecmp(type, "16bit"))
  263: 			def->hd_type = HISTORY_TYPE_16;
  264: 		else if (!strcasecmp(type, "32bit"))
  265: 			def->hd_type = HISTORY_TYPE_32;
  266: 		else if (!strcasecmp(type, "64bit"))
  267: 			def->hd_type = HISTORY_TYPE_64;
  268: 		else
  269: 			quit("Invalid type \'%s\', must be \"(8|16|32|64)bit\""
  270: 			     " in history definition #%d\n", type, i+1);
  271: 	}
  272: }
  273: 
  274: static void configfile_read_element_cfg(void)
  275: {
  276: 	int i, nelement;
  277: 
  278: 	nelement = cfg_size(cfg, "element");
  279: 
  280: 	for (i = 0; i < nelement; i++) {
  281: 		struct element_cfg *ec;
  282: 		cfg_t *element;
  283: 		const char *name, *description;
  284: 		long max;
  285: 
  286: 		if (!(element = cfg_getnsec(cfg, "element", i)))
  287: 			BUG();
  288: 
  289: 		if (!(name = cfg_title(element)))
  290: 			BUG();
  291: 
  292: 		ec = element_cfg_alloc(name);
  293: 
  294: 		if ((description = cfg_getstr(element, "description")))
  295: 			ec->ec_description = strdup(description);
  296: 
  297: 		if ((max = cfg_getint(element, "max")))
  298: 			ec->ec_rxmax = ec->ec_txmax = max;
  299: 
  300: 		if ((max = cfg_getint(element, "rxmax")))
  301: 			ec->ec_rxmax = max;
  302: 
  303: 		if ((max = cfg_getint(element, "txmax")))
  304: 			ec->ec_txmax = max;
  305: 
  306: 		if (cfg_getbool(element, "show"))
  307: 			ec->ec_flags |= ELEMENT_CFG_SHOW;
  308: 		else
  309: 			ec->ec_flags |= ELEMENT_CFG_HIDE;
  310: 	}
  311: }
  312: 
  313: static void add_div(struct unit *unit, int type, cfg_t *variant)
  314: {
  315: 	int ndiv, n, ntxt;
  316: 
  317: 	if (!(ndiv = cfg_size(variant, "div")))
  318: 		return;
  319: 
  320: 	ntxt = cfg_size(variant, "txt");
  321: 	if (ntxt != ndiv)
  322: 		quit("Number of elements for div and txt not equal\n");
  323: 
  324: 	if (!list_empty(&unit->u_div[type])) {
  325: 		struct fraction *f, *n;
  326: 
  327: 		list_for_each_entry_safe(f, n, &unit->u_div[type], f_list)
  328: 			fraction_free(f);
  329: 	}
  330: 
  331: 	for (n = 0; n < ndiv; n++) {
  332: 		char *txt;
  333: 		float div;
  334: 
  335: 		div = cfg_getnfloat(variant, "div", n);
  336: 		txt = cfg_getnstr(variant, "txt", n);
  337: 
  338: 		unit_add_div(unit, type, txt, div);
  339: 	}
  340: }
  341: 
  342: static void configfile_read_units(void)
  343: {
  344: 	int i, nunits;
  345: 	struct unit *u;
  346: 
  347: 	nunits = cfg_size(cfg, "unit");
  348: 
  349: 	for (i = 0; i < nunits; i++) {
  350: 		int nvariants, n;
  351: 		cfg_t *unit;
  352: 		const char *name;
  353: 
  354: 		if (!(unit = cfg_getnsec(cfg, "unit", i)))
  355: 			BUG();
  356: 
  357: 		if (!(name = cfg_title(unit)))
  358: 			BUG();
  359: 
  360: 		if (!(nvariants = cfg_size(unit, "variant")))
  361: 			continue;
  362: 
  363: 		if (!(u = unit_add(name)))
  364: 			continue;
  365: 
  366: 		for (n = 0; n < nvariants; n++) {
  367: 			cfg_t *variant;
  368: 			const char *vtitle;
  369: 
  370: 			if (!(variant = cfg_getnsec(unit, "variant", n)))
  371: 				BUG();
  372: 
  373: 			if (!(vtitle = cfg_title(variant)))
  374: 				BUG();
  375: 
  376: 			if (!strcasecmp(vtitle, "default"))
  377: 				add_div(u, UNIT_DEFAULT, variant);
  378: 			else if (!strcasecmp(vtitle, "si"))
  379: 				add_div(u, UNIT_SI, variant);
  380: 			else if (!strcasecmp(vtitle, "bit"))
  381: 				add_div(u, UNIT_BIT, variant);
  382: 			else
  383: 				quit("Unknown unit variant \'%s\'\n", vtitle);
  384: 		}
  385: 	}
  386: }
  387: 
  388: static void configfile_read_attrs(void)
  389: {
  390: 	int i, nattrs, t = 0;
  391: 
  392: 	nattrs = cfg_size(cfg, "attr");
  393: 
  394: 	for (i = 0; i < nattrs; i++) {
  395: 		struct unit *u;
  396: 		cfg_t *attr;
  397: 		const char *name, *description, *unit, *type;
  398: 		int flags = 0;
  399: 
  400: 		if (!(attr = cfg_getnsec(cfg, "attr", i)))
  401: 			BUG();
  402: 
  403: 		if (!(name = cfg_title(attr)))
  404: 			BUG();
  405: 
  406: 		description = cfg_getstr(attr, "description");
  407: 		unit = cfg_getstr(attr, "unit");
  408: 		type = cfg_getstr(attr, "type");
  409: 
  410: 		if (!unit)
  411: 			quit("Attribute '%s' is missing unit specification\n",
  412: 			     name);
  413: 
  414: 		if (!type)
  415: 			quit("Attribute '%s' is missing type specification\n",
  416: 			     name);
  417: 
  418: 		if (!(u = unit_lookup(unit)))
  419: 			quit("Unknown unit \'%s\' attribute '%s'\n",
  420: 				unit, name);
  421: 
  422: 		if (!strcasecmp(type, "counter"))
  423: 			t = ATTR_TYPE_COUNTER;
  424: 		else if (!strcasecmp(type, "rate"))
  425: 			t = ATTR_TYPE_RATE;
  426: 		else if (!strcasecmp(type, "percent"))
  427: 			t = ATTR_TYPE_PERCENT;
  428: 		else
  429: 			quit("Unknown type \'%s\' in attribute '%s'\n",
  430: 				type, name);
  431: 
  432: 		if (cfg_getbool(attr, "history"))
  433: 			flags |= ATTR_FORCE_HISTORY;
  434: 
  435: 		if (cfg_getbool(attr, "ignore_overflows"))
  436: 			flags |= ATTR_IGNORE_OVERFLOWS;
  437: 
  438: 		attr_def_add(name, description, u, t, flags);
  439: 	}
  440: }
  441: 
  442: static void configfile_read_layout_cfg(void)
  443: {
  444:     int i, nlayouts;
  445:     cfg_t *lout;
  446:     nlayouts = cfg_size(cfg, "layout");
  447:     for (i = 0; i < nlayouts; i++)
  448:     {
  449:         int c, ncolors;
  450:         const char *name;
  451:         if (!(lout = cfg_getnsec(cfg, "layout", i)))
  452:             BUG();
  453: 
  454:         if (!(name = cfg_title(lout)))
  455:             BUG();
  456: 
  457:         ncolors = cfg_size(lout, "color");
  458:         if (ncolors > LAYOUT_MAX) {
  459:             fprintf(stderr, "Warning excceeded maximum number of layouts\n");
  460:             ncolors = LAYOUT_MAX;
  461:         }
  462: 
  463:         for (c = 0; c < ncolors; c++) {
  464:             cfg_t *color_pair;
  465: 
  466:             if (!(color_pair = cfg_getnsec(lout, "color", c)))
  467:                 BUG();
  468: 
  469:             if (!(name = cfg_title(color_pair)))
  470:                 BUG();
  471: 
  472:             add_layout(name, color_pair);
  473:         }
  474:     }
  475: }
  476: 
  477: static void conf_read(const char *path, int must)
  478: {
  479: 	int err;
  480: 
  481: 	DBG("Reading configfile %s...", path);
  482: 
  483: 	if (access(path, R_OK) != 0) {
  484: 		if (must)
  485: 			quit("Error: Unable to read configfile \"%s\": %s\n",
  486: 			     path, strerror(errno));
  487: 		else
  488: 			return;
  489: 	}
  490: 
  491: 	err = cfg_parse(cfg, path);
  492: 	if (err == CFG_FILE_ERROR) {
  493: 		quit("Error while reading configfile \"%s\": %s\n",
  494: 		     path, strerror(errno));
  495: 	} else if (err == CFG_PARSE_ERROR) {
  496: 		quit("Error while reading configfile \"%s\": parse error\n",
  497: 		     path);
  498: 	}
  499: 
  500: 	configfile_read_units();
  501: 	configfile_read_history();
  502: 	configfile_read_attrs();
  503: 	configfile_read_element_cfg();
  504:     configfile_read_layout_cfg();
  505: }
  506: 
  507: static const char default_config[] = \
  508: "unit byte {" \
  509: " 	variant default {" \
  510: " 		div	= { 1, 1024, 1048576, 1073741824, 1099511627776}" \
  511: " 		txt	= { \"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\" }" \
  512: " 	}" \
  513: " 	variant si {" \
  514: " 		div	= { 1, 1000, 1000000, 1000000000, 1000000000000 }" \
  515: " 		txt	= { \"B\", \"KB\", \"MB\", \"GB\", \"TB\" }" \
  516: " 	}" \
  517: " 	variant bit {" \
  518: " 		div	= { 0.125, 125, 125000, 125000000, 125000000000 }" \
  519: " 		txt	= { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \
  520: " 	}" \
  521: " }" \
  522: "unit bit {" \
  523: " 	variant default {" \
  524: " 		div	= { 1, 1000, 1000000, 1000000000, 1000000000000 }" \
  525: " 		txt	= { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \
  526: " 	}" \
  527: " 	variant si {" \
  528: " 		div	= { 1, 1000, 1000000, 1000000000, 1000000000000 }" \
  529: " 		txt	= { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \
  530: " 	}" \
  531: " 	variant bit {" \
  532: " 		div	= { 1, 1000, 1000000, 1000000000, 1000000000000 }" \
  533: " 		txt	= { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \
  534: " 	}" \
  535: "}" \
  536: "unit number {" \
  537: " 	variant default {" \
  538: " 		div	= { 1, 1000, 1000000, 1000000000, 1000000000000 }" \
  539: " 		txt	= { \"\", \"K\", \"M\", \"G\", \"T\" }" \
  540: " 	}" \
  541: "}" \
  542: "unit percent {" \
  543: "	variant default {" \
  544: "		div	= { 1. }" \
  545: "		txt	= { \"%\" }" \
  546: "	}" \
  547: "}" \
  548: "history second {" \
  549: "	interval	= 1.0" \
  550: "	size		= 60" \
  551: "}" \
  552: "history minute {" \
  553: "	interval	= 60.0" \
  554: "	size		= 60" \
  555: "}" \
  556: "history hour {" \
  557: "	interval	= 3600.0" \
  558: "	size		= 60" \
  559: "}" \
  560: "history day {" \
  561: "	interval	= 86400.0" \
  562: "	size		= 60" \
  563: "}"
  564: "layout colors {" \
  565: "   color default {" \
  566: "       color_pair = { \"white\", \"black\" }" \
  567: "   }" \
  568: "   color statusbar{" \
  569: "       color_pair = { \"blue\", \"white\", \"reverse\" }" \
  570: "   }" \
  571: "   color header {" \
  572: "       color_pair = { \"yellow\", \"black\" }" \
  573: "   }" \
  574: "   color list {" \
  575: "       color_pair = { \"white\", \"black\" }" \
  576: "   }" \
  577: "   color selected {" \
  578: "       color_pair = { \"yellow\", \"black\", \"reverse\" }" \
  579: "   }" \
  580: "   color rx_graph {" \
  581: "       color_pair = { \"green\", \"black\" }" \
  582: "   }" \
  583: "   color tx_graph {" \
  584: "       color_pair = { \"red\", \"black\" }" \
  585: "   }" \
  586: "}";
  587: 
  588: static void conf_read_default(void)
  589: {
  590: 	int err;
  591: 
  592: 	DBG("Reading default config");
  593: 
  594: 	err = cfg_parse_buf(cfg, default_config);
  595: 	if (err)
  596: 		quit("Error while parsing default config\n");
  597: 
  598: 	configfile_read_units();
  599: 	configfile_read_history();
  600: 	configfile_read_attrs();
  601: 	configfile_read_element_cfg();
  602:     configfile_read_layout_cfg();
  603: }
  604: 
  605: void configfile_read(void)
  606: {
  607: 	if (configfile)
  608: 		conf_read(configfile, 1);
  609: 	else {
  610: 		conf_read(SYSCONFDIR "/bmon.conf", 0);
  611: 		
  612: 		if (getenv("HOME")) {
  613: 			char path[FILENAME_MAX+1];
  614: 			snprintf(path, sizeof(path), "%s/.bmonrc",
  615: 				 getenv("HOME"));
  616: 			conf_read(path, 0);
  617: 		}
  618: 	}
  619: }
  620: 
  621: void conf_init_pre(void)
  622: {
  623: 	conf_read_default();
  624: }
  625: 
  626: void conf_init_post(void)
  627: {
  628: 	cfg_read_interval = cfg_getfloat(cfg, "read_interval");
  629: 	cfg_rate_interval = cfg_getfloat(cfg, "rate_interval");
  630: 	cfg_rate_variance = cfg_getfloat(cfg, "variance") * cfg_rate_interval;
  631: 	cfg_history_variance = cfg_getfloat(cfg, "history_variance");
  632: 	cfg_show_all = cfg_getbool(cfg, "show_all");
  633: 	cfg_unit_exp = cfg_getint(cfg, "unit_exp");
  634: 
  635: 	element_parse_policy(cfg_getstr(cfg, "policy"));
  636: }
  637: 
  638: void set_configfile(const char *file)
  639: {
  640: 	static int set = 0;
  641: 	if (!set) {
  642: 		configfile = strdup(file);
  643: 		set = 1;
  644: 	}
  645: }
  646: 
  647: void set_unit_exp(const char *name)
  648: {
  649: 	if (tolower(*name) == 'b')
  650: 		cfg_setint(cfg, "unit_exp", 0);
  651: 	else if (tolower(*name) == 'k')
  652: 		cfg_setint(cfg, "unit_exp", 1);
  653: 	else if (tolower(*name) == 'm')
  654: 		cfg_setint(cfg, "unit_exp", 2);
  655: 	else if (tolower(*name) == 'g')
  656: 		cfg_setint(cfg, "unit_exp", 3);
  657: 	else if (tolower(*name) == 't')
  658: 		cfg_setint(cfg, "unit_exp", 4);
  659: 	else if (tolower(*name) == 'd')
  660: 		cfg_setint(cfg, "unit_exp", DYNAMIC_EXP);
  661: 	else
  662: 		quit("Unknown unit exponent '%s'\n", name);
  663: }
  664: 
  665: unsigned int get_lifecycles(void)
  666: {
  667: 	return (unsigned int)
  668: 		(cfg_getfloat(cfg, "lifetime") / cfg_getfloat(cfg, "read_interval"));
  669: }
  670: 
  671: static void __exit conf_shutdown(void)
  672: {
  673: 	cfg_free(cfg);
  674: }
  675: 
  676: static void __init __conf_init(void)
  677: {
  678: 	DBG("init");
  679: 
  680: 	cfg = cfg_init(global_opts, CFGF_NOCASE);
  681: 
  682: 	/* FIXME: Add validation functions */
  683: 	//cfg_set_validate_func(cfg, "bookmark", &cb_validate_bookmark);
  684: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>