Annotation of embedaddon/bmon/src/node.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * node.c            node handling
                      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/node.h>
                     27: #include <bmon/item.h>
                     28: #include <bmon/utils.h>
                     29: 
                     30: static node_t *nodes;
                     31: static size_t nodes_size;
                     32: static size_t nnodes;
                     33: static const char * node_name;
                     34: static node_t *local_node;
                     35: static node_t *current_node;
                     36: 
                     37: 
                     38: node_t * lookup_node(const char *name, int creat)
                     39: {
                     40:        int i;
                     41: 
                     42:        if (NULL == nodes) {
                     43:                nodes_size = 32;
                     44:                nodes = xcalloc(nodes_size, sizeof(node_t));
                     45:        }
                     46: 
                     47:        for (i = 0; i < nodes_size; i++)
                     48:                if (nodes[i].n_name && !strcmp(name, nodes[i].n_name))
                     49:                        return &nodes[i];
                     50: 
                     51:        if (creat) {
                     52:                for (i = 0; i < nodes_size; i++)
                     53:                        if (NULL == nodes[i].n_name)
                     54:                                break;
                     55: 
                     56:                while (i >= nodes_size) {
                     57:                        int oldsize = nodes_size;
                     58:                        nodes_size += 32;
                     59:                        nodes = xrealloc(nodes, nodes_size * sizeof(node_t));
                     60:                        memset((uint8_t *) nodes + oldsize, 0, (nodes_size - oldsize) * sizeof(node_t));
                     61:                }
                     62: 
                     63:                nodes[i].n_name = strdup(name);
                     64:                nodes[i].n_index = i;
                     65:                nnodes++;
                     66:                return &nodes[i];
                     67:        }
                     68: 
                     69:        return NULL;
                     70: }
                     71: 
                     72: void foreach_node(void (*cb)(node_t *, void *), void *arg)
                     73: {
                     74:        int i;
                     75: 
                     76:        for (i = 0; i < nnodes; i++)
                     77:                cb(&nodes[i], arg);
                     78: }
                     79: 
                     80: void foreach_item(node_t *n, void (*cb)(item_t *, void *), void *arg)
                     81: {
                     82:        int i;
                     83: 
                     84:        for (i = 0; i < n->n_nitems; i++)
                     85:                if (n->n_items[i].i_name[0])
                     86:                        cb(&n->n_items[i], arg);
                     87: }
                     88: 
                     89: 
                     90: void foreach_node_item(void (*cb)(node_t *, item_t *, void *), void *arg)
                     91: {
                     92:        int i, m;
                     93: 
                     94:        for (i = 0; i < nnodes; i++) {
                     95:                node_t *n = &nodes[i];
                     96:                
                     97:                for (m = 0; m < n->n_nitems; m++)
                     98:                        if (n->n_items[m].i_name[0])
                     99:                                cb(n, &n->n_items[m], arg);
                    100:        }
                    101: }
                    102: 
                    103: 
                    104: static void __reset_item(node_t *n, item_t *i, void *arg)
                    105: {
                    106:        reset_item(i);
                    107: }
                    108: 
                    109: void reset_nodes(void)
                    110: {
                    111:        foreach_node_item(__reset_item, NULL);
                    112: }
                    113: 
                    114: static void __remove_unused_item(node_t *n, item_t *i, void *arg)
                    115: {
                    116:        remove_unused_items(i);
                    117: }
                    118: 
                    119: void remove_unused_node_items(void)
                    120: {
                    121:        foreach_node_item(__remove_unused_item, NULL);
                    122: }
                    123: 
                    124: 
                    125: 
                    126: node_t * get_local_node(void)
                    127: {
                    128:        if (NULL == local_node)
                    129:                local_node = lookup_node(node_name, 1);
                    130: 
                    131:        return local_node;
                    132: }
                    133: 
                    134: int get_nnodes(void)
                    135: {
                    136:        return nnodes;
                    137: }
                    138: 
                    139: static void get_node_info(void)
                    140: {
                    141:        struct utsname uts;
                    142:        
                    143:        if (uname(&uts) < 0)
                    144:                quit("utsname failed: %s\n", strerror(errno));
                    145:        
                    146:        node_name = strdup(uts.nodename);
                    147: }
                    148: 
                    149: void calc_node_rate(node_t *node)
                    150: {
                    151:        int i;
                    152: 
                    153:        node->n_rx_maj_total = 0;
                    154:        node->n_tx_maj_total = 0;
                    155:        node->n_rx_min_total = 0;
                    156:        node->n_tx_min_total = 0;
                    157: 
                    158:        for (i = 0; i < node->n_nitems; i++) {
                    159:                item_t *it = &node->n_items[i];
                    160:                if (it->i_name[0] &&
                    161:                    it->i_level == 0 &&
                    162:                    !(it->i_flags & ITEM_FLAG_EXCLUDE)) {
                    163:                        stat_attr_t *maj = lookup_attr(it, it->i_major_attr);
                    164:                        stat_attr_t *min = lookup_attr(it, it->i_minor_attr);
                    165: 
                    166:                        if (maj) {
                    167:                                node->n_rx_maj_total += attr_get_rx_rate(maj);
                    168:                                node->n_tx_maj_total += attr_get_tx_rate(maj);
                    169:                        }
                    170: 
                    171:                        if (min) {
                    172:                                node->n_rx_min_total += attr_get_rx_rate(min);
                    173:                                node->n_tx_min_total += attr_get_tx_rate(min);
                    174:                        }
                    175:                        
                    176:                }
                    177:        }
                    178: }
                    179: 
                    180: void calc_node_rates(void)
                    181: {
                    182:        int i;
                    183: 
                    184:        for (i = 0; i < nnodes; i++)
                    185:                calc_node_rate(&nodes[i]);
                    186: }
                    187: 
                    188: node_t * get_current_node(void)
                    189: {
                    190:        return current_node;
                    191: }
                    192: 
                    193: int first_node(void)
                    194: {
                    195:        int i;
                    196: 
                    197:        if (nnodes <= 0)
                    198:                return EMPTY_LIST;
                    199:        
                    200:        for (i = 0; i < nnodes; i++) {
                    201:                if (nodes[i].n_name) {
                    202:                        current_node = &nodes[i];
                    203:                        return 0;
                    204:                }
                    205:        }
                    206:        
                    207:        return EMPTY_LIST;
                    208: }
                    209: 
                    210: int last_node(void)
                    211: {
                    212:        int i;
                    213:        
                    214:        if (nnodes <= 0)
                    215:                return EMPTY_LIST;
                    216:        
                    217:        for (i = (nnodes - 1); i >= 0; i--) {
                    218:                if (nodes[i].n_name) {
                    219:                        current_node = &nodes[i];
                    220:                        return 0;
                    221:                }
                    222:        }
                    223:        
                    224:        return EMPTY_LIST;
                    225: }
                    226:        
                    227: 
                    228: int prev_node(void)
                    229: {
                    230:        if (nnodes <= 0)
                    231:                return EMPTY_LIST;
                    232:        
                    233:        if (current_node == NULL)
                    234:                return first_node();
                    235:        else {
                    236:                int i;
                    237:                for (i = (current_node->n_index - 1); i >= 0; i--) {
                    238:                        if (nodes[i].n_name) {
                    239:                                current_node = &nodes[i];
                    240:                                return 0;
                    241:                        }
                    242:                }
                    243:                return END_OF_LIST;
                    244:        }
                    245:        
                    246:        return EMPTY_LIST;
                    247: }
                    248: 
                    249: int next_node(void)
                    250: {
                    251:        if (nnodes <= 0)
                    252:                return EMPTY_LIST;
                    253:        
                    254:        if (current_node == NULL)
                    255:                return first_node();
                    256:        else {
                    257:                int i;
                    258:                for (i = (current_node->n_index + 1); i < nnodes; i++) {
                    259:                        if (nodes[i].n_name) {
                    260:                                current_node = &nodes[i];
                    261:                                return 0;
                    262:                        }
                    263:                }
                    264:                return END_OF_LIST;
                    265:        }
                    266:        
                    267:        return EMPTY_LIST;
                    268: }
                    269: 
                    270: item_t * get_current_item(void)
                    271: {
                    272:        if (current_node) {
                    273:                if (current_node->n_selected < current_node->n_nitems &&
                    274:                    current_node->n_selected >= 0) {
                    275:                        item_t *i = &(current_node->n_items[current_node->n_selected]);
                    276: 
                    277:                        if (i->i_name[0])
                    278:                                return i;
                    279:                }
                    280:        }
                    281:        return NULL;
                    282: }
                    283: 
                    284: int first_item(void)
                    285: {
                    286:        int i;
                    287:        
                    288:        if (current_node == NULL)
                    289:                return EMPTY_LIST;
                    290:        
                    291:        if (current_node->n_nitems <= 0)
                    292:                return EMPTY_LIST;
                    293:        
                    294:        for (i = 0; i < current_node->n_nitems; i++) {
                    295:                if (current_node->n_items[i].i_name[0]) {
                    296:                        current_node->n_selected = i;
                    297:                        return 0;
                    298:                }
                    299:        }
                    300:        
                    301:        return EMPTY_LIST;
                    302: }
                    303: 
                    304: int last_item(void)
                    305: {
                    306:        int i;
                    307:        
                    308:        if (current_node == NULL)
                    309:                return EMPTY_LIST;
                    310: 
                    311:        if (current_node->n_nitems <= 0)
                    312:                return EMPTY_LIST;
                    313: 
                    314:        for (i = (current_node->n_nitems - 1); i >= 0; i--) {
                    315:                if (current_node->n_items[i].i_name[0]) {
                    316:                        current_node->n_selected = i;
                    317:                        return 0;
                    318:                }
                    319:        }
                    320: 
                    321:        return EMPTY_LIST;
                    322: }
                    323: 
                    324: int goto_item(int num)
                    325: {
                    326:        if (current_node == NULL)
                    327:                return EMPTY_LIST;
                    328: 
                    329:        if (current_node->n_nitems <= 0)
                    330:                return EMPTY_LIST;
                    331: 
                    332:        if (num < current_node->n_nitems && num >= 0)
                    333:                if (current_node->n_items[num].i_name[0])
                    334:                        current_node->n_selected = num;
                    335: 
                    336:        return 0;
                    337: }
                    338: 
                    339: int next_item(void)
                    340: {
                    341:        if (current_node == NULL)
                    342:                return EMPTY_LIST;
                    343: 
                    344:        if (current_node->n_nitems <= 0)
                    345:                return EMPTY_LIST;
                    346: 
                    347:        if (current_node->n_selected < 0 ||
                    348:                current_node->n_selected >= current_node->n_nitems)
                    349:                return last_item();
                    350:        else {
                    351:                int i;
                    352:                node_t *cn = current_node;
                    353: 
                    354:                for (i = (cn->n_selected + 1); i < cn->n_nitems; i++) {
                    355:                        if (!cn->n_items[i].i_name[0])
                    356:                                continue;
                    357: 
                    358:                        if (cn->n_items[i].i_flags & ITEM_FLAG_IS_CHILD) {
                    359:                                item_t *fi = get_item(cn, cn->n_items[i].i_link);
                    360: 
                    361:                                if (fi->i_flags & ITEM_FLAG_FOLDED)
                    362:                                        continue;
                    363:                        }
                    364: 
                    365:                        cn->n_selected = i;
                    366:                        return 0;
                    367:                }
                    368: 
                    369:                return END_OF_LIST;
                    370:        }
                    371: 
                    372:        return EMPTY_LIST;
                    373: }
                    374: 
                    375: int prev_item(void)
                    376: {
                    377:        if (current_node == NULL)
                    378:                return EMPTY_LIST;
                    379: 
                    380:        if (current_node->n_nitems <= 0)
                    381:                return EMPTY_LIST;
                    382: 
                    383:        if (current_node->n_selected < 0 ||
                    384:                current_node->n_selected >= current_node->n_nitems)
                    385:                return first_item();
                    386:        else {
                    387:                int i;
                    388:                node_t *cn = current_node;
                    389: 
                    390:                for (i = (cn->n_selected - 1); i >= 0; i--) {
                    391:                        if (!cn->n_items[i].i_name[0])
                    392:                                continue;
                    393: 
                    394:                        if (cn->n_items[i].i_flags & ITEM_FLAG_IS_CHILD) {
                    395:                                item_t *fi = get_item(cn, cn->n_items[i].i_link);
                    396: 
                    397:                                if (fi->i_flags & ITEM_FLAG_FOLDED)
                    398:                                        continue;
                    399:                        }
                    400:                        
                    401:                        cn->n_selected = i;
                    402:                        return 0;
                    403:                }
                    404: 
                    405:                return END_OF_LIST;
                    406:        }
                    407: 
                    408:        return EMPTY_LIST;
                    409: }
                    410: 
                    411: static void __init node_init(void)
                    412: {
                    413:        get_node_info();
                    414: }

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