Annotation of embedaddon/bmon/src/conf.c, revision 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>