version 1.1.1.1, 2012/02/21 22:19:56
|
version 1.1.1.2, 2014/07/30 07:55:27
|
Line 1
|
Line 1
|
/* |
/* |
* conf.c Config Crap |
* conf.c Config Crap |
* |
* |
* Copyright (c) 2001-2005 Thomas Graf <tgraf@suug.ch> | * Copyright (c) 2001-2013 Thomas Graf <tgraf@suug.ch> |
| * Copyright (c) 2013 Red Hat, Inc. |
* |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* copy of this software and associated documentation files (the "Software"), |
Line 24
|
Line 25
|
|
|
#include <bmon/bmon.h> |
#include <bmon/bmon.h> |
#include <bmon/conf.h> |
#include <bmon/conf.h> |
#include <bmon/bindings.h> | #include <bmon/unit.h> |
#include <bmon/input.h> | #include <bmon/attr.h> |
#include <bmon/output.h> | #include <bmon/element.h> |
| #include <bmon/element_cfg.h> |
| #include <bmon/history.h> |
#include <bmon/utils.h> |
#include <bmon/utils.h> |
|
|
static int show_only_running = 1; | cfg_t *cfg; |
static int do_signal_output = 0; | |
static char fg_char = '*'; | |
static char bg_char = '.'; | |
static char noise_char = ':'; | |
static char unk_char = '?'; | |
static y_unit_t y_unit = Y_DYNAMIC; | |
static x_unit_t x_unit = X_SEC; | |
static char * configfile = NULL; | |
static float read_interval = 1.0f; | |
static unsigned long sleep_time = 20000; | |
static int use_si = 0; | |
static int ngraphs = 1; | |
static float hb_factor = 0.1; | |
static float rate_interval = 1.0f; | |
static float lifetime = 30.0f; | |
static char * itemtabfile = "/etc/bmon/itemtab"; | |
|
|
|
static cfg_opt_t element_opts[] = { |
|
CFG_STR("description", NULL, CFGF_NONE), |
|
CFG_BOOL("show", cfg_true, CFGF_NONE), |
|
CFG_INT("rxmax", 0, CFGF_NONE), |
|
CFG_INT("txmax", 0, CFGF_NONE), |
|
CFG_INT("max", 0, CFGF_NONE), |
|
CFG_END() |
|
}; |
|
|
|
static cfg_opt_t history_opts[] = { |
|
CFG_FLOAT("interval", 1.0f, CFGF_NONE), |
|
CFG_INT("size", 60, CFGF_NONE), |
|
CFG_STR("type", "64bit", CFGF_NONE), |
|
CFG_END() |
|
}; |
|
|
|
static cfg_opt_t attr_opts[] = { |
|
CFG_STR("description", "", CFGF_NONE), |
|
CFG_STR("unit", "", CFGF_NONE), |
|
CFG_STR("type", "counter", CFGF_NONE), |
|
CFG_BOOL("history", cfg_false, CFGF_NONE), |
|
CFG_END() |
|
}; |
|
|
|
static cfg_opt_t variant_opts[] = { |
|
CFG_FLOAT_LIST("div", "{}", CFGF_NONE), |
|
CFG_STR_LIST("txt", "", CFGF_NONE), |
|
CFG_END() |
|
}; |
|
|
|
static cfg_opt_t unit_opts[] = { |
|
CFG_SEC("variant", variant_opts, CFGF_MULTI | CFGF_TITLE), |
|
CFG_END() |
|
}; |
|
|
|
static cfg_opt_t global_opts[] = { |
|
CFG_FLOAT("read_interval", 1.0f, CFGF_NONE), |
|
CFG_FLOAT("rate_interval", 1.0f, CFGF_NONE), |
|
CFG_FLOAT("lifetime", 30.0f, CFGF_NONE), |
|
CFG_FLOAT("history_variance", 0.1f, CFGF_NONE), |
|
CFG_FLOAT("variance", 0.1f, CFGF_NONE), |
|
CFG_BOOL("show_all", cfg_false, CFGF_NONE), |
|
CFG_INT("unit_exp", -1, CFGF_NONE), |
|
CFG_INT("sleep_time", 20000UL, CFGF_NONE), |
|
CFG_BOOL("use_si", 0, CFGF_NONE), |
|
CFG_BOOL("use_bit", 0, CFGF_NONE), |
|
CFG_STR("uid", NULL, CFGF_NONE), |
|
CFG_STR("gid", NULL, CFGF_NONE), |
|
CFG_STR("policy", "", CFGF_NONE), |
|
CFG_SEC("unit", unit_opts, CFGF_MULTI | CFGF_TITLE), |
|
CFG_SEC("attr", attr_opts, CFGF_MULTI | CFGF_TITLE), |
|
CFG_SEC("history", history_opts, CFGF_MULTI | CFGF_TITLE), |
|
CFG_SEC("element", element_opts, CFGF_MULTI | CFGF_TITLE), |
|
CFG_END() |
|
}; |
|
|
|
float cfg_read_interval; |
|
float cfg_rate_interval; |
|
float cfg_rate_variance; |
|
float cfg_history_variance; |
|
int cfg_show_all; |
|
int cfg_unit_exp = DYNAMIC_EXP; |
|
|
|
static char * configfile = NULL; |
|
|
#if defined HAVE_CURSES |
#if defined HAVE_CURSES |
#if defined HAVE_USE_DEFAULT_COLORS |
#if defined HAVE_USE_DEFAULT_COLORS |
layout_t layout[] = | struct layout cfg_layout[] = |
{ |
{ |
{-1, -1, 0}, /* dummy, not used */ |
{-1, -1, 0}, /* dummy, not used */ |
{-1, -1, 0}, /* default */ |
{-1, -1, 0}, /* default */ |
Line 59 layout_t layout[] =
|
Line 111 layout_t layout[] =
|
{-1, -1, A_REVERSE}, /* selected */ |
{-1, -1, A_REVERSE}, /* selected */ |
}; |
}; |
#else |
#else |
layout_t layout[] = | struct layout cfg_layout[] = |
{ |
{ |
{0, 0, 0}, /* dummy, not used */ |
{0, 0, 0}, /* dummy, not used */ |
{COLOR_BLACK, COLOR_WHITE, 0}, /* default */ |
{COLOR_BLACK, COLOR_WHITE, 0}, /* default */ |
Line 71 layout_t layout[] =
|
Line 123 layout_t layout[] =
|
#endif |
#endif |
#endif |
#endif |
|
|
#define SPLIT(str, var) \ |
|
do { \ |
|
char *s; \ |
|
for (s = str; *s; s++) { \ |
|
if (*s == ' ' || *s == '\t') \ |
|
break; \ |
|
} \ |
|
if (!*s) \ |
|
break; \ |
|
*s = '\0'; \ |
|
for (++s;*s == ' ' || *s == '\t'; s++); \ |
|
if (!*s) \ |
|
break; \ |
|
var = s; \ |
|
} while(0); |
|
|
|
static void conf_read(const char *); |
|
|
|
static inline void parse_include(char *buf) |
|
{ |
|
conf_read(buf); |
|
} |
|
|
|
#if defined HAVE_CURSES |
|
static int parse_color(const char *color) |
|
{ |
|
if (!strcmp(color, "default")) |
|
return -1; |
|
else if (!strcasecmp(color, "black")) |
|
return COLOR_BLACK; |
|
else if (!strcasecmp(color, "red")) |
|
return COLOR_RED; |
|
else if (!strcasecmp(color, "green")) |
|
return COLOR_GREEN; |
|
else if (!strcasecmp(color, "yellow")) |
|
return COLOR_YELLOW; |
|
else if (!strcasecmp(color, "blue")) |
|
return COLOR_BLUE; |
|
else if (!strcasecmp(color, "magenta")) |
|
return COLOR_MAGENTA; |
|
else if (!strcasecmp(color, "cyan")) |
|
return COLOR_CYAN; |
|
else if (!strcasecmp(color, "white")) |
|
return COLOR_WHITE; |
|
else |
|
return -1; |
|
} |
|
|
|
static void parse_layout(char *buf) |
|
{ |
|
char *id, *fg = NULL, *bg = NULL, *attr, *s; |
|
layout_t l; |
|
|
|
id = buf; |
|
SPLIT(buf, fg) |
|
SPLIT(fg, bg) |
|
|
|
for (s = bg; *s; s++) { |
|
if (*s == ' ' || *s == '\t') |
|
break; |
|
} |
|
|
|
if (*s) { |
|
*s = '\0'; |
|
s++; |
|
|
|
for (; *s == ' ' || *s == '\t'; s++); |
|
if (*s) |
|
attr = s; |
|
else |
|
attr = NULL; |
|
} |
|
else |
|
attr = NULL; |
|
|
|
if ((l.fg = parse_color(fg)) == -1) |
|
return; |
|
|
|
if ((l.bg = parse_color(bg)) == -1) |
|
return; |
|
|
|
l.attr = 0; |
|
|
|
if (attr) |
|
{ |
|
if (!strcasecmp(attr, "reverse")) |
|
l.attr |= A_REVERSE; |
|
else if (!strcasecmp(attr, "bold")) |
|
l.attr |= A_BOLD; |
|
else if (!strcasecmp(attr, "underline")) |
|
l.attr |= A_UNDERLINE; |
|
} |
|
|
|
#define COPY_LAYOUT(id) do { \ |
|
layout[id].fg = l.fg; \ |
|
layout[id].bg = l.bg; \ |
|
layout[id].attr = l.attr; \ |
|
} while (0); |
|
|
|
if (!strcasecmp(id, "default")) |
|
COPY_LAYOUT(LAYOUT_DEFAULT) |
|
else if (!strcasecmp(id, "statusbar")) |
|
COPY_LAYOUT(LAYOUT_STATUSBAR) |
|
else if (!strcasecmp(id, "header")) |
|
COPY_LAYOUT(LAYOUT_HEADER) |
|
else if (!strcasecmp(id, "list")) |
|
COPY_LAYOUT(LAYOUT_LIST) |
|
else if (!strcasecmp(id, "selected")) |
|
COPY_LAYOUT(LAYOUT_SELECTED) |
|
|
|
#undef COPY_LAYOUT |
|
} |
|
#endif |
|
|
|
static void parse_bind(char *buf) |
|
{ |
|
char *ch, *cmd = NULL, *args, *s; |
|
binding_t *b; |
|
int i; |
|
|
|
ch = buf; |
|
SPLIT(buf, cmd); |
|
args = strdup(cmd); |
|
|
|
b = xcalloc(1, sizeof(binding_t)); |
|
b->args[0] = args; |
|
|
|
for (s = args, i = 1; i < 255; i++) { |
|
s = strchr (s, ' '); |
|
if (s) { |
|
*s = '\0'; |
|
s++; |
|
b->args[i] = s; |
|
} else |
|
break; |
|
} |
|
|
|
b->args[i] = NULL; |
|
|
|
b->ch = ch[0]; |
|
b->cmd = strdup(b->args[0]); |
|
|
|
add_binding(b); |
|
} |
|
|
|
void conf_parse_option(const char *id, const char *value) |
|
{ |
|
#define MATCH(STR) if (!strcasecmp(id, STR)) |
|
MATCH("input") |
|
set_input(value); |
|
else MATCH("secondary_input") |
|
set_sec_input(value); |
|
else MATCH("output") |
|
set_output(value); |
|
else MATCH("secondary_output") |
|
set_sec_output(value); |
|
else MATCH("policy") |
|
item_parse_policy(value); |
|
else MATCH("read_interval") |
|
set_read_interval(value); |
|
else MATCH("sleep_time") |
|
set_sleep_time(value); |
|
else MATCH("show_all") |
|
set_show_only_running(0); |
|
else MATCH("use_si") |
|
set_use_si(); |
|
else MATCH("nr_graphs") |
|
set_ngraphs(strtol(value, NULL, 0)); |
|
else MATCH("heartbeat_factor") |
|
set_hb_factor(value); |
|
else MATCH("rate_interval") |
|
set_rate_interval(value); |
|
else MATCH("lifetime") |
|
set_lifetime(value); |
|
else MATCH("itemtab") |
|
set_itemtab(value); |
|
#undef MATCH |
|
} |
|
|
|
tv_t * parse_tv(char *data) |
tv_t * parse_tv(char *data) |
{ |
{ |
char *value; |
char *value; |
tv_t *tv = xcalloc(1, sizeof(tv_t)); |
tv_t *tv = xcalloc(1, sizeof(tv_t)); |
|
|
|
init_list_head(&tv->tv_list); |
|
|
value = strchr(data, '='); |
value = strchr(data, '='); |
|
|
if (value) { |
if (value) { |
*value = '\0'; |
*value = '\0'; |
++value; |
++value; |
tv->value = strdup(value); | tv->tv_value = strdup(value); |
} |
} |
|
|
tv->type = strdup(data); | tv->tv_type = strdup(data); |
return tv; |
return tv; |
} |
} |
|
|
Line 277 module_conf_t * parse_module(char *data)
|
Line 152 module_conf_t * parse_module(char *data)
|
|
|
m = xcalloc(1, sizeof(module_conf_t)); |
m = xcalloc(1, sizeof(module_conf_t)); |
|
|
|
init_list_head(&m->m_attrs); |
|
|
opts = strchr(data, ':'); |
opts = strchr(data, ':'); |
|
|
if (opts) { |
if (opts) { |
Line 293 module_conf_t * parse_module(char *data)
|
Line 170 module_conf_t * parse_module(char *data)
|
} |
} |
|
|
tv = parse_tv(opts); |
tv = parse_tv(opts); |
|
list_add_tail(&tv->tv_list, &m->m_attrs); |
|
|
tv->next = m->attrs; |
|
m->attrs = tv; |
|
|
|
opts = next; |
opts = next; |
} while(next); |
} while(next); |
} |
} |
|
|
m->name = strdup(name); | m->m_name = strdup(name); |
return m; |
return m; |
} |
} |
|
|
|
|
module_conf_t * parse_module_param(const char *data) | int parse_module_param(const char *data, struct list_head *list) |
{ |
{ |
char *buf = strdup(data); |
char *buf = strdup(data); |
char *next; |
char *next; |
char *current = buf; |
char *current = buf; |
module_conf_t *m, *list = NULL; | module_conf_t *m; |
| int n = 0; |
|
|
do { |
do { |
next = strchr(current, ','); |
next = strchr(current, ','); |
Line 322 module_conf_t * parse_module_param(const char *data)
|
Line 198 module_conf_t * parse_module_param(const char *data)
|
} |
} |
|
|
m = parse_module(current); |
m = parse_module(current); |
|
|
if (m) { |
if (m) { |
m->next = list; | list_add_tail(&m->m_list, list); |
list = m; | n++; |
} |
} |
|
|
current = next; |
current = next; |
Line 333 module_conf_t * parse_module_param(const char *data)
|
Line 208 module_conf_t * parse_module_param(const char *data)
|
|
|
free(buf); |
free(buf); |
|
|
return list; | return n; |
} |
} |
|
|
| static void configfile_read_history(void) |
static inline void parse_config_line(char *buf) | |
{ |
{ |
char *tok = NULL; | int i, nhistory; |
| |
SPLIT(buf, tok); | |
if (!strcasecmp(buf, "include")) | |
parse_include(tok); | |
#if defined HAVE_CURSES | |
else if (!strcasecmp(buf, "layout")) | |
parse_layout(tok); | |
#endif | |
else if (!strcasecmp(buf, "bind")) | |
parse_bind(tok); | |
else | |
conf_parse_option(buf, tok); | |
} | |
|
|
static void conf_read(const char *path) | nhistory = cfg_size(cfg, "history"); |
{ | |
FILE *f; | |
char buf[1024]; | |
|
|
if (!(f = fopen(path, "r"))) | for (i = 0; i < nhistory; i++) { |
return; | struct history_def *def; |
| cfg_t *history; |
| const char *name, *type; |
| float interval; |
| int size; |
|
|
memset(buf, 0, sizeof(buf)); | if (!(history = cfg_getnsec(cfg, "history", i))) |
| BUG(); |
|
|
while (fgets(buf, sizeof(buf), f)) { | if (!(name = cfg_title(history))) |
char *p; | BUG(); |
|
|
if ('#' == *buf) | interval = cfg_getfloat(history, "interval"); |
goto skip; | size = cfg_getint(history, "size"); |
| type = cfg_getstr(history, "type"); |
|
|
if ((p = strchr(buf, '\r'))) | if (interval == 0.0f) |
*p = '\0'; | interval = cfg_getfloat(cfg, "read_interval"); |
|
|
if ((p = strchr(buf, '\n'))) | def = history_def_alloc(name); |
*p = '\0'; | def->hd_interval = interval; |
| def->hd_size = size; |
|
|
if (*buf) | if (!strcasecmp(type, "8bit")) |
parse_config_line(buf); | def->hd_type = HISTORY_TYPE_8; |
| else if (!strcasecmp(type, "16bit")) |
skip: | def->hd_type = HISTORY_TYPE_16; |
memset(buf, 0, sizeof(buf)); | else if (!strcasecmp(type, "32bit")) |
| def->hd_type = HISTORY_TYPE_32; |
| else if (!strcasecmp(type, "64bit")) |
| def->hd_type = HISTORY_TYPE_64; |
| else |
| quit("Invalid type \'%s\', must be \"(8|16|32|64)bit\"" |
| " in history definition #%d\n", type, i+1); |
} |
} |
|
|
fclose(f); |
|
} |
} |
|
|
void read_configfile(void) | static void configfile_read_element_cfg(void) |
{ |
{ |
if (configfile) | int i, nelement; |
conf_read(configfile); | |
else { | |
conf_read("/etc/bmon.conf"); | |
| |
if (getenv("HOME")) { | |
char path[FILENAME_MAX+1]; | |
snprintf(path, sizeof(path), "%s/.bmonrc", getenv("HOME")); | |
conf_read(path); | |
} | |
} | |
} | |
|
|
|
nelement = cfg_size(cfg, "element"); |
|
|
inline void set_configfile(const char *file) | for (i = 0; i < nelement; i++) { |
{ | struct element_cfg *ec; |
static int set = 0; | cfg_t *element; |
if (!set) { | const char *name, *description; |
configfile = strdup(file); | long max; |
set = 1; | |
} | |
} | |
|
|
inline void set_itemtab(const char *file) | if (!(element = cfg_getnsec(cfg, "element", i))) |
{ | BUG(); |
static int set = 0; | |
if (!set) { | |
itemtabfile = strdup(file); | |
set = 1; | |
} | |
} | |
|
|
inline char *get_itemtab(void) | if (!(name = cfg_title(element))) |
{ | BUG(); |
return itemtabfile; | |
} | |
|
|
inline void set_read_interval(const char *i) | ec = element_cfg_alloc(name); |
{ | |
static int set = 0; | |
if (!set) { | |
read_interval = (float) strtod(i, NULL); | |
set = 1; | |
} | |
} | |
|
|
inline float get_read_interval(void) | if ((description = cfg_getstr(element, "description"))) |
{ | ec->ec_description = strdup(description); |
return read_interval; | |
} | |
|
|
inline void get_read_interval_as_ts(timestamp_t *ts) | if ((max = cfg_getint(element, "max"))) |
{ | ec->ec_rxmax = ec->ec_txmax = max; |
float_to_ts(ts, read_interval); | |
} | |
|
|
|
if ((max = cfg_getint(element, "rxmax"))) |
|
ec->ec_rxmax = max; |
|
|
inline void set_x_unit(const char *x, int force) | if ((max = cfg_getint(element, "txmax"))) |
{ | ec->ec_txmax = max; |
static int set = 0; | |
if (!set || force) { | if (cfg_getbool(element, "show")) |
if (tolower(*x) == 's') | ec->ec_flags |= ELEMENT_CFG_SHOW; |
x_unit = X_SEC; | |
else if (tolower(*x) == 'm') | |
x_unit = X_MIN; | |
else if (tolower(*x) == 'h') | |
x_unit = X_HOUR; | |
else if (tolower(*x) == 'd') | |
x_unit = X_DAY; | |
else if (tolower(*x) == 'r') | |
x_unit = X_READ; | |
else |
else |
quit("Unknown X-axis unit '%s'\n", x); | ec->ec_flags |= ELEMENT_CFG_HIDE; |
set = 1; | |
} |
} |
} |
} |
|
|
inline x_unit_t get_x_unit(void) | static void add_div(struct unit *unit, int type, cfg_t *variant) |
{ |
{ |
return x_unit; | int ndiv, n, ntxt; |
} | |
|
|
inline void set_y_unit(const char *y) | if (!(ndiv = cfg_size(variant, "div"))) |
{ | return; |
static int set = 0; | |
if (!set) { | |
if (tolower(*y) == 'b') | |
y_unit = Y_BYTE; | |
else if (tolower(*y) == 'k') | |
y_unit = Y_KILO; | |
else if (tolower(*y) == 'm') | |
y_unit = Y_MEGA; | |
else if (tolower(*y) == 'g') | |
y_unit = Y_GIGA; | |
else if (tolower(*y) == 't') | |
y_unit = Y_TERA; | |
else | |
quit("Unknown Y-axis unit '%s'\n", y); | |
set = 1; | |
} | |
} | |
|
|
inline y_unit_t get_y_unit(void) | ntxt = cfg_size(variant, "txt"); |
{ | if (ntxt != ndiv) |
return y_unit; | quit("Number of elements for div and txt not equal\n"); |
} | |
|
|
|
if (!list_empty(&unit->u_div[type])) { |
|
struct fraction *f, *n; |
|
|
inline char get_fg_char(void) | list_for_each_entry_safe(f, n, &unit->u_div[type], f_list) |
{ | fraction_free(f); |
return fg_char; | } |
} | |
|
|
inline void set_fg_char(char c) | for (n = 0; n < ndiv; n++) { |
{ | char *txt; |
static int set = 0; | float div; |
if (!set) { | |
fg_char = c; | div = cfg_getnfloat(variant, "div", n); |
set = 1; | txt = cfg_getnstr(variant, "txt", n); |
| |
| unit_add_div(unit, type, txt, div); |
} |
} |
} |
} |
|
|
inline char get_unk_char(void) | static void configfile_read_units(void) |
{ |
{ |
return unk_char; | int i, nunits; |
} | struct unit *u; |
|
|
inline void set_unk_char(char c) | nunits = cfg_size(cfg, "unit"); |
{ | |
static int set = 0; | for (i = 0; i < nunits; i++) { |
if (!set) { | int nvariants, n; |
unk_char = c; | cfg_t *unit; |
set = 1; | const char *name; |
| |
| if (!(unit = cfg_getnsec(cfg, "unit", i))) |
| BUG(); |
| |
| if (!(name = cfg_title(unit))) |
| BUG(); |
| |
| if (!(nvariants = cfg_size(unit, "variant"))) |
| continue; |
| |
| if (!(u = unit_add(name))) |
| continue; |
| |
| for (n = 0; n < nvariants; n++) { |
| cfg_t *variant; |
| const char *vtitle; |
| |
| if (!(variant = cfg_getnsec(unit, "variant", n))) |
| BUG(); |
| |
| if (!(vtitle = cfg_title(variant))) |
| BUG(); |
| |
| if (!strcasecmp(vtitle, "default")) |
| add_div(u, UNIT_DEFAULT, variant); |
| else if (!strcasecmp(vtitle, "si")) |
| add_div(u, UNIT_SI, variant); |
| else if (!strcasecmp(vtitle, "bit")) |
| add_div(u, UNIT_BIT, variant); |
| else |
| quit("Unknown unit variant \'%s\'\n", vtitle); |
| } |
} |
} |
} |
} |
|
|
inline char get_bg_char(void) | static void configfile_read_attrs(void) |
{ |
{ |
return bg_char; | int i, nattrs, t; |
} | |
|
|
inline void set_bg_char(char c) | nattrs = cfg_size(cfg, "attr"); |
{ | |
static int set = 0; | for (i = 0; i < nattrs; i++) { |
if (!set) { | struct unit *u; |
bg_char = c; | cfg_t *attr; |
set = 1; | const char *name, *description, *unit, *type; |
| int flags = 0; |
| |
| if (!(attr = cfg_getnsec(cfg, "attr", i))) |
| BUG(); |
| |
| if (!(name = cfg_title(attr))) |
| BUG(); |
| |
| description = cfg_getstr(attr, "description"); |
| unit = cfg_getstr(attr, "unit"); |
| type = cfg_getstr(attr, "type"); |
| |
| if (!unit) |
| quit("Attribute '%s' is missing unit specification\n", |
| name); |
| |
| if (!type) |
| quit("Attribute '%s' is missing type specification\n", |
| name); |
| |
| if (!(u = unit_lookup(unit))) |
| quit("Unknown unit \'%s\' attribute '%s'\n", |
| unit, name); |
| |
| if (!strcasecmp(type, "counter")) |
| t = ATTR_TYPE_COUNTER; |
| else if (!strcasecmp(type, "rate")) |
| t = ATTR_TYPE_RATE; |
| else if (!strcasecmp(type, "percent")) |
| t = ATTR_TYPE_PERCENT; |
| else |
| quit("Unknown type \'%s\' in attribute '%s'\n", |
| type, name); |
| |
| if (cfg_getbool(attr, "history")) |
| flags |= ATTR_FORCE_HISTORY; |
| |
| if (cfg_getbool(attr, "ignore_overflows")) |
| flags |= ATTR_IGNORE_OVERFLOWS; |
| |
| attr_def_add(name, description, u, t, flags); |
} |
} |
} |
} |
|
|
inline char get_noise_char(void) | static void conf_read(const char *path, int must) |
{ |
{ |
return noise_char; | int err; |
} | |
|
|
inline void set_noise_char(char c) | DBG("Reading configfile %s...", path); |
{ | |
static int set = 0; | if (access(path, R_OK) != 0) { |
if (!set) { | if (must) |
noise_char = c; | quit("Error: Unable to read configfile \"%s\": %s\n", |
set = 1; | path, strerror(errno)); |
| else |
| return; |
} |
} |
} |
|
|
|
inline void set_sleep_time(const char *s) | err = cfg_parse(cfg, path); |
{ | if (err == CFG_FILE_ERROR) { |
static int set = 0; | quit("Error while reading configfile \"%s\": %s\n", |
if (!set) { | path, strerror(errno)); |
double d = strtod(s, NULL); | } else if (err == CFG_PARSE_ERROR) { |
sleep_time = (unsigned long) (d * 1000000.0f); | quit("Error while reading configfile \"%s\": parse error\n", |
set = 1; | path); |
} |
} |
} |
|
|
|
inline unsigned long get_sleep_time(void) | configfile_read_units(); |
{ | configfile_read_history(); |
return sleep_time; | configfile_read_attrs(); |
| configfile_read_element_cfg(); |
} |
} |
|
|
inline void set_signal_output(int i) | static const char default_config[] = \ |
{ | "unit byte {" \ |
static int set = 0; | " variant default {" \ |
if (!set) { | " div = { 1, 1024, 1048576, 1073741824, 1099511627776}" \ |
do_signal_output = i; | " txt = { \"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\" }" \ |
set = 1; | " }" \ |
} | " variant si {" \ |
} | " div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \ |
| " txt = { \"B\", \"KB\", \"MB\", \"GB\", \"TB\" }" \ |
| " }" \ |
| " variant bit {" \ |
| " div = { 0.125, 125, 125000, 125000000, 125000000000 }" \ |
| " txt = { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \ |
| " }" \ |
| " }" \ |
| "unit bit {" \ |
| " variant default {" \ |
| " div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \ |
| " txt = { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \ |
| " }" \ |
| " variant si {" \ |
| " div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \ |
| " txt = { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \ |
| " }" \ |
| " variant bit {" \ |
| " div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \ |
| " txt = { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \ |
| " }" \ |
| "}" \ |
| "unit number {" \ |
| " variant default {" \ |
| " div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \ |
| " txt = { \"\", \"K\", \"M\", \"G\", \"T\" }" \ |
| " }" \ |
| "}" \ |
| "unit percent {" \ |
| " variant default {" \ |
| " div = { 1. }" \ |
| " txt = { \"%\" }" \ |
| " }" \ |
| "}" \ |
| "history second {" \ |
| " interval = 1.0" \ |
| " size = 60" \ |
| "}" \ |
| "history minute {" \ |
| " interval = 60.0" \ |
| " size = 60" \ |
| "}" \ |
| "history hour {" \ |
| " interval = 3600.0" \ |
| " size = 60" \ |
| "}" \ |
| "history day {" \ |
| " interval = 86400.0" \ |
| " size = 60" \ |
| "}"; |
|
|
inline int get_signal_output(void) | static void conf_read_default(void) |
{ |
{ |
return do_signal_output; | int err; |
} | |
|
|
inline void set_show_only_running(int i) | DBG("Reading default config"); |
{ | |
static int set = 0; | |
if (!set) { | |
show_only_running = i; | |
set = 1; | |
} | |
} | |
|
|
inline int get_show_only_running(void) | err = cfg_parse_buf(cfg, default_config); |
{ | if (err) |
return show_only_running; | quit("Error while parsing default config\n"); |
} | |
|
|
inline void set_use_si(void) | configfile_read_units(); |
{ | configfile_read_history(); |
use_si = 1; | configfile_read_attrs(); |
| configfile_read_element_cfg(); |
} |
} |
|
|
inline int get_use_si(void) | void configfile_read(void) |
{ |
{ |
return use_si; | if (configfile) |
} | conf_read(configfile, 1); |
| else { |
inline void set_ngraphs(int n) | conf_read(SYSCONFDIR "/bmon.conf", 0); |
{ | |
static int set = 0; | if (getenv("HOME")) { |
if (!set) { | char path[FILENAME_MAX+1]; |
ngraphs = n; | snprintf(path, sizeof(path), "%s/.bmonrc", |
set = 1; | getenv("HOME")); |
| conf_read(path, 0); |
| } |
} |
} |
} |
} |
|
|
inline int get_ngraphs(void) | void conf_init_pre(void) |
{ |
{ |
return ngraphs; | conf_read_default(); |
} |
} |
|
|
inline float get_hb_factor(void) | void conf_init_post(void) |
{ |
{ |
return hb_factor; | cfg_read_interval = cfg_getfloat(cfg, "read_interval"); |
| cfg_rate_interval = cfg_getfloat(cfg, "rate_interval"); |
| cfg_rate_variance = cfg_getfloat(cfg, "variance") * cfg_rate_interval; |
| cfg_history_variance = cfg_getfloat(cfg, "history_variance"); |
| cfg_show_all = cfg_getbool(cfg, "show_all"); |
| cfg_unit_exp = cfg_getint(cfg, "unit_exp"); |
| |
| element_parse_policy(cfg_getstr(cfg, "policy")); |
} |
} |
|
|
inline void set_hb_factor(const char *s) | void set_configfile(const char *file) |
{ |
{ |
static int set = 0; |
static int set = 0; |
if (!set) { |
if (!set) { |
hb_factor = strtod(s, NULL); | configfile = strdup(file); |
set = 1; |
set = 1; |
} |
} |
} |
} |
|
|
inline void set_rate_interval(const char *i) | void set_unit_exp(const char *name) |
{ |
{ |
static int set = 0; | if (tolower(*name) == 'b') |
if (!set) { | cfg_setint(cfg, "unit_exp", 0); |
rate_interval = (float) strtod(i, NULL); | else if (tolower(*name) == 'k') |
set = 1; | cfg_setint(cfg, "unit_exp", 1); |
} | else if (tolower(*name) == 'm') |
| cfg_setint(cfg, "unit_exp", 2); |
| else if (tolower(*name) == 'g') |
| cfg_setint(cfg, "unit_exp", 3); |
| else if (tolower(*name) == 't') |
| cfg_setint(cfg, "unit_exp", 4); |
| else if (tolower(*name) == 'd') |
| cfg_setint(cfg, "unit_exp", DYNAMIC_EXP); |
| else |
| quit("Unknown unit exponent '%s'\n", name); |
} |
} |
|
|
inline float get_rate_interval(void) | unsigned int get_lifecycles(void) |
{ |
{ |
return rate_interval; | return (unsigned int) |
| (cfg_getfloat(cfg, "lifetime") / cfg_getfloat(cfg, "read_interval")); |
} |
} |
|
|
inline void set_lifetime(const char *i) | static void __exit conf_shutdown(void) |
{ |
{ |
static int set = 0; | cfg_free(cfg); |
if (!set) { | |
lifetime = (float) strtod(i, NULL); | |
set = 1; | |
} | |
} |
} |
|
|
inline float get_lifetime(void) | static void __init __conf_init(void) |
{ |
{ |
return lifetime / read_interval; | DBG("init"); |
| |
| cfg = cfg_init(global_opts, CFGF_NOCASE); |
| |
| /* FIXME: Add validation functions */ |
| //cfg_set_validate_func(cfg, "bookmark", &cb_validate_bookmark); |
} |
} |