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>