version 1.1.1.1, 2012/02/21 22:19:56
|
version 1.1.1.3, 2019/10/21 14:58:35
|
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/layout.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"; | |
|
|
#if defined HAVE_CURSES | static cfg_opt_t element_opts[] = { |
#if defined HAVE_USE_DEFAULT_COLORS | CFG_STR("description", NULL, CFGF_NONE), |
layout_t layout[] = | CFG_BOOL("show", cfg_true, CFGF_NONE), |
{ | CFG_INT("rxmax", 0, CFGF_NONE), |
{-1, -1, 0}, /* dummy, not used */ | CFG_INT("txmax", 0, CFGF_NONE), |
{-1, -1, 0}, /* default */ | CFG_INT("max", 0, CFGF_NONE), |
{-1, -1, A_REVERSE}, /* statusbar */ | CFG_END() |
{-1, -1, 0}, /* header */ | |
{-1, -1, 0}, /* list */ | |
{-1, -1, A_REVERSE}, /* selected */ | |
}; |
}; |
#else | |
layout_t layout[] = | static cfg_opt_t history_opts[] = { |
{ | CFG_FLOAT("interval", 1.0f, CFGF_NONE), |
{0, 0, 0}, /* dummy, not used */ | CFG_INT("size", 60, CFGF_NONE), |
{COLOR_BLACK, COLOR_WHITE, 0}, /* default */ | CFG_STR("type", "64bit", CFGF_NONE), |
{COLOR_BLACK, COLOR_WHITE, A_REVERSE}, /* statusbar */ | CFG_END() |
{COLOR_BLACK, COLOR_WHITE, 0}, /* header */ | |
{COLOR_BLACK, COLOR_WHITE, 0}, /* list */ | |
{COLOR_BLACK, COLOR_WHITE, A_REVERSE}, /* selected */ | |
}; |
}; |
#endif |
|
#endif |
|
|
|
#define SPLIT(str, var) \ | static cfg_opt_t attr_opts[] = { |
do { \ | CFG_STR("description", "", CFGF_NONE), |
char *s; \ | CFG_STR("unit", "", CFGF_NONE), |
for (s = str; *s; s++) { \ | CFG_STR("type", "counter", CFGF_NONE), |
if (*s == ' ' || *s == '\t') \ | CFG_BOOL("history", cfg_false, CFGF_NONE), |
break; \ | CFG_END() |
} \ | }; |
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 cfg_opt_t variant_opts[] = { |
| CFG_FLOAT_LIST("div", "{}", CFGF_NONE), |
| CFG_STR_LIST("txt", "", CFGF_NONE), |
| CFG_END() |
| }; |
|
|
static inline void parse_include(char *buf) | static cfg_opt_t unit_opts[] = { |
{ | CFG_SEC("variant", variant_opts, CFGF_MULTI | CFGF_TITLE), |
conf_read(buf); | CFG_END() |
} | }; |
|
|
#if defined HAVE_CURSES | static cfg_opt_t color_opts[] = { |
static int parse_color(const char *color) | CFG_STR_LIST("color_pair", "", CFGF_NONE), |
{ | CFG_END() |
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) | static cfg_opt_t layout_opts[] = { |
{ | CFG_SEC("color", color_opts, CFGF_MULTI | CFGF_TITLE), |
char *id, *fg = NULL, *bg = NULL, *attr, *s; | CFG_END() |
layout_t l; | }; |
|
|
id = buf; | static cfg_opt_t global_opts[] = { |
SPLIT(buf, fg) | CFG_FLOAT("read_interval", 1.0f, CFGF_NONE), |
SPLIT(fg, bg) | 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_SEC("layout", layout_opts, CFGF_MULTI | CFGF_TITLE), |
| CFG_END() |
| }; |
|
|
for (s = bg; *s; s++) { | float cfg_read_interval; |
if (*s == ' ' || *s == '\t') | float cfg_rate_interval; |
break; | float cfg_rate_variance; |
} | float cfg_history_variance; |
| int cfg_show_all; |
| int cfg_unit_exp = DYNAMIC_EXP; |
|
|
if (*s) { | static char * configfile = NULL; |
*s = '\0'; | |
s++; | |
|
|
for (; *s == ' ' || *s == '\t'; s++); | #if defined HAVE_CURSES |
if (*s) | #if defined HAVE_USE_DEFAULT_COLORS |
attr = s; | struct layout cfg_layout[] = |
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; | {-1, -1, 0}, /* dummy, not used */ |
binding_t *b; | {-1, -1, 0}, /* default */ |
int i; | {-1, -1, A_REVERSE}, /* statusbar */ |
| {-1, -1, 0}, /* header */ |
ch = buf; | {-1, -1, 0}, /* list */ |
SPLIT(buf, cmd); | {-1, -1, A_REVERSE}, /* selected */ |
args = strdup(cmd); | {-1, -1, 0}, /* RX graph */ |
| {-1, -1, 0}, /* TX graph */ |
b = xcalloc(1, sizeof(binding_t)); | }; |
b->args[0] = args; | #else |
| struct layout cfg_layout[] = |
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)) | {0, 0, 0}, /* dummy, not used */ |
MATCH("input") | {COLOR_WHITE, COLOR_BLACK, 0}, /* default */ |
set_input(value); | {COLOR_BLUE, COLOR_GREEN, A_REVERSE}, /* statusbar */ |
else MATCH("secondary_input") | {COLOR_GREEN, COLOR_BLACK, 0}, /* header */ |
set_sec_input(value); | {COLOR_WHITE, COLOR_BLACK, 0}, /* list */ |
else MATCH("output") | {COLOR_YELLOW, COLOR_BLACK, A_REVERSE}, /* selected */ |
set_output(value); | {COLOR_GREEN, COLOR_BLACK, 0}, /* RX graph */ |
else MATCH("secondary_output") | {COLOR_RED, COLOR_BLACK, 0}, /* TX graph */ |
set_sec_output(value); | }; |
else MATCH("policy") | #endif |
item_parse_policy(value); | #endif |
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 168 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 186 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 214 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 224 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; | |
| if (!(element = cfg_getnsec(cfg, "element", i))) |
| BUG(); |
| |
| if (!(name = cfg_title(element))) |
| BUG(); |
| |
| ec = element_cfg_alloc(name); |
| |
| if ((description = cfg_getstr(element, "description"))) |
| ec->ec_description = strdup(description); |
| |
| if ((max = cfg_getint(element, "max"))) |
| ec->ec_rxmax = ec->ec_txmax = max; |
| |
| if ((max = cfg_getint(element, "rxmax"))) |
| ec->ec_rxmax = max; |
| |
| if ((max = cfg_getint(element, "txmax"))) |
| ec->ec_txmax = max; |
| |
| if (cfg_getbool(element, "show")) |
| ec->ec_flags |= ELEMENT_CFG_SHOW; |
| else |
| ec->ec_flags |= ELEMENT_CFG_HIDE; |
} |
} |
} |
} |
|
|
inline void set_itemtab(const char *file) | static void add_div(struct unit *unit, int type, cfg_t *variant) |
{ |
{ |
static int set = 0; | int ndiv, n, ntxt; |
if (!set) { | |
itemtabfile = strdup(file); | if (!(ndiv = cfg_size(variant, "div"))) |
set = 1; | return; |
| |
| ntxt = cfg_size(variant, "txt"); |
| if (ntxt != ndiv) |
| quit("Number of elements for div and txt not equal\n"); |
| |
| if (!list_empty(&unit->u_div[type])) { |
| struct fraction *f, *n; |
| |
| list_for_each_entry_safe(f, n, &unit->u_div[type], f_list) |
| fraction_free(f); |
} |
} |
} |
|
|
|
inline char *get_itemtab(void) | for (n = 0; n < ndiv; n++) { |
{ | char *txt; |
return itemtabfile; | float div; |
} | |
|
|
inline void set_read_interval(const char *i) | div = cfg_getnfloat(variant, "div", n); |
{ | txt = cfg_getnstr(variant, "txt", n); |
static int set = 0; | |
if (!set) { | unit_add_div(unit, type, txt, div); |
read_interval = (float) strtod(i, NULL); | |
set = 1; | |
} |
} |
} |
} |
|
|
inline float get_read_interval(void) | static void configfile_read_units(void) |
{ |
{ |
return read_interval; | int i, nunits; |
} | struct unit *u; |
|
|
inline void get_read_interval_as_ts(timestamp_t *ts) | nunits = cfg_size(cfg, "unit"); |
{ | |
float_to_ts(ts, read_interval); | |
} | |
|
|
|
for (i = 0; i < nunits; i++) { |
|
int nvariants, n; |
|
cfg_t *unit; |
|
const char *name; |
|
|
inline void set_x_unit(const char *x, int force) | if (!(unit = cfg_getnsec(cfg, "unit", i))) |
{ | BUG(); |
static int set = 0; | |
if (!set || force) { | if (!(name = cfg_title(unit))) |
if (tolower(*x) == 's') | BUG(); |
x_unit = X_SEC; | |
else if (tolower(*x) == 'm') | if (!(nvariants = cfg_size(unit, "variant"))) |
x_unit = X_MIN; | continue; |
else if (tolower(*x) == 'h') | |
x_unit = X_HOUR; | if (!(u = unit_add(name))) |
else if (tolower(*x) == 'd') | continue; |
x_unit = X_DAY; | |
else if (tolower(*x) == 'r') | for (n = 0; n < nvariants; n++) { |
x_unit = X_READ; | cfg_t *variant; |
else | const char *vtitle; |
quit("Unknown X-axis unit '%s'\n", x); | |
set = 1; | 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 x_unit_t get_x_unit(void) | static void configfile_read_attrs(void) |
{ |
{ |
return x_unit; | int i, nattrs, t = 0; |
} | |
|
|
inline void set_y_unit(const char *y) | nattrs = cfg_size(cfg, "attr"); |
{ | |
static int set = 0; | for (i = 0; i < nattrs; i++) { |
if (!set) { | struct unit *u; |
if (tolower(*y) == 'b') | cfg_t *attr; |
y_unit = Y_BYTE; | const char *name, *description, *unit, *type; |
else if (tolower(*y) == 'k') | int flags = 0; |
y_unit = Y_KILO; | |
else if (tolower(*y) == 'm') | if (!(attr = cfg_getnsec(cfg, "attr", i))) |
y_unit = Y_MEGA; | BUG(); |
else if (tolower(*y) == 'g') | |
y_unit = Y_GIGA; | if (!(name = cfg_title(attr))) |
else if (tolower(*y) == 't') | BUG(); |
y_unit = Y_TERA; | |
| 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 |
else |
quit("Unknown Y-axis unit '%s'\n", y); | quit("Unknown type \'%s\' in attribute '%s'\n", |
set = 1; | 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 y_unit_t get_y_unit(void) | static void configfile_read_layout_cfg(void) |
{ |
{ |
return y_unit; | int i, nlayouts; |
} | cfg_t *lout; |
| nlayouts = cfg_size(cfg, "layout"); |
| for (i = 0; i < nlayouts; i++) |
| { |
| int c, ncolors; |
| const char *name; |
| if (!(lout = cfg_getnsec(cfg, "layout", i))) |
| BUG(); |
|
|
|
if (!(name = cfg_title(lout))) |
|
BUG(); |
|
|
inline char get_fg_char(void) | ncolors = cfg_size(lout, "color"); |
{ | if (ncolors > LAYOUT_MAX) { |
return fg_char; | fprintf(stderr, "Warning excceeded maximum number of layouts\n"); |
} | ncolors = LAYOUT_MAX; |
| } |
|
|
inline void set_fg_char(char c) | for (c = 0; c < ncolors; c++) { |
{ | cfg_t *color_pair; |
static int set = 0; | |
if (!set) { | |
fg_char = c; | |
set = 1; | |
} | |
} | |
|
|
inline char get_unk_char(void) | if (!(color_pair = cfg_getnsec(lout, "color", c))) |
{ | BUG(); |
return unk_char; | |
} | |
|
|
inline void set_unk_char(char c) | if (!(name = cfg_title(color_pair))) |
{ | BUG(); |
static int set = 0; | |
if (!set) { | |
unk_char = c; | |
set = 1; | |
} | |
} | |
|
|
inline char get_bg_char(void) | add_layout(name, color_pair); |
{ | } |
return bg_char; | } |
} |
} |
|
|
inline void set_bg_char(char c) | static void conf_read(const char *path, int must) |
{ |
{ |
static int set = 0; | int err; |
if (!set) { | |
bg_char = c; | |
set = 1; | |
} | |
} | |
|
|
inline char get_noise_char(void) | DBG("Reading configfile %s...", path); |
{ | |
return noise_char; | |
} | |
|
|
inline void set_noise_char(char c) | if (access(path, R_OK) != 0) { |
{ | if (must) |
static int set = 0; | quit("Error: Unable to read configfile \"%s\": %s\n", |
if (!set) { | path, strerror(errno)); |
noise_char = c; | else |
set = 1; | 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(); |
| configfile_read_layout_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" \ |
| "}" |
| "layout colors {" \ |
| " color default {" \ |
| " color_pair = { \"white\", \"black\" }" \ |
| " }" \ |
| " color statusbar{" \ |
| " color_pair = { \"blue\", \"white\", \"reverse\" }" \ |
| " }" \ |
| " color header {" \ |
| " color_pair = { \"yellow\", \"black\" }" \ |
| " }" \ |
| " color list {" \ |
| " color_pair = { \"white\", \"black\" }" \ |
| " }" \ |
| " color selected {" \ |
| " color_pair = { \"yellow\", \"black\", \"reverse\" }" \ |
| " }" \ |
| " color rx_graph {" \ |
| " color_pair = { \"green\", \"black\" }" \ |
| " }" \ |
| " color tx_graph {" \ |
| " color_pair = { \"red\", \"black\" }" \ |
| " }" \ |
| "}"; |
|
|
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(); |
| configfile_read_layout_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); |
} |
} |