--- projects/cms/source/idar/idar.c 2003/03/30 01:14:49 1.4 +++ projects/cms/source/idar/idar.c 2003/04/02 15:41:01 1.10 @@ -29,11 +29,17 @@ #include #include #include +#include #include #include #include "genmergesort.h" + +#ifdef HAVE_NCURSES_H +#include +#else #include +#endif struct host_line_t{ char *hostname; @@ -117,10 +123,12 @@ struct machine_data_t{ network_data_list_t *network_data_list; long long network_io_total_tx; long long network_io_total_rx; + long long network_io_total; diskio_data_list_t *diskio_data_list; long long disk_io_total_write; long long disk_io_total_read; + long long disk_io_total; /* Maybe in the future */ /* @@ -133,6 +141,7 @@ struct machine_data_t{ typedef struct machine_data_t machine_data_list_t; +#define SORTBYMAXNAME 128 typedef struct{ int cpu_user; int cpu_idle; @@ -174,6 +183,8 @@ typedef struct{ int disk_total_used; int disk_all_stats; + + char sortby[SORTBYMAXNAME]; }display_config_t; GENERIC_MERGE_SORT(static, sort_machine_stats, machine_data_list_t, next) @@ -185,13 +196,27 @@ int (*sortby_ptr)(machine_data_list_t *a, machine_data MKCMP(cpu_used) MKCMP(load_1) +MKCMP(network_io_total) MKCMP(network_io_total_tx) MKCMP(network_io_total_rx) +MKCMP(disk_io_total) MKCMP(disk_io_total_write) MKCMP(disk_io_total_read) MKCMP(memory_used_pecent) MKCMP(swap_used_pecent) +#define CPU_USED "CPU used" +#define LOAD "Load (1)" +#define NETIORX "total Network RX for all interfaces" +#define NETIOTX "total Network TX for all interfaces" +#define NETIO "total Network IO for all interfaces (rx+tx)" +#define MEM "Memory usage" +#define SWAP "Swap usage" +#define DISKIOR "DiskIO reads" +#define DISKIOW "DiskIO writes" +#define DISKIO "Total DiskIO (reads+writes)" + + /* int cmp_cpu(machine_data_list_t *a, machine_data_list_t *b){ @@ -211,6 +236,77 @@ int cmp_cpu(machine_data_list_t *a, machine_data_list_ } } */ + +#ifndef HAVE_ATOLL +long long int atoll (const char *nptr){ + return strtoll (nptr, (char **) NULL, 10); +} +#endif + +#ifndef HAVE_STRLCPY +/* + * Copyright (c) 1998 Todd C. Miller + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t +strlcpy(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +#endif + FILE *create_tcp_connection(char *hostname, int port){ int sock; @@ -559,6 +655,7 @@ int parse_xml(char *xml, machine_data_list_t **md){ machine_data_list->network_io_total_rx+=ndl_ptr->rx; ndl_ptr=ndl_ptr->next; } + machine_data_list->network_io_total=machine_data_list->network_io_total_rx+machine_data_list->network_io_total_tx; didl_ptr=machine_data_list->diskio_data_list; machine_data_list->disk_io_total_read=0; @@ -568,6 +665,7 @@ int parse_xml(char *xml, machine_data_list_t **md){ machine_data_list->disk_io_total_write+=didl_ptr->write; didl_ptr=didl_ptr->next; } + machine_data_list->disk_io_total=machine_data_list->disk_io_total_read+machine_data_list->disk_io_total_write; xmlFreeDoc(doc); @@ -578,12 +676,14 @@ int parse_xml(char *xml, machine_data_list_t **md){ void display(machine_data_list_t *machine_data_list, display_config_t *display_config, int num_lines, int *title){ int line_num=4; + int counter; int x=1; if(*title){ -// printf("\033[2J"); - // printf("\033[1;1HHostname CPU Load Page Page Mem Swap Net Net Disk Disk"); - // printw("\033[2;1H used%% (1m) ins outs used used rx tx read write"); + clear(); + move (num_lines-3, 1); + printw("Sorting by %-64s", display_config->sortby); + move(1,1); printw("%-11s", "Hostname"); x=x+11+1; @@ -661,7 +761,8 @@ void display(machine_data_list_t *machine_data_list, d *title=0; } - for(;num_lines;num_lines--){ + /* Counter starts at 8, for padding (eg, headers, borders etc) */ + for(counter=8;countersysname); @@ -687,6 +788,8 @@ void display(machine_data_list_t *machine_data_list, d int main(int argc, char **argv){ WINDOW *window; + fd_set infds; + int maxx, maxy; FILE *control; FILE *data; @@ -702,7 +805,7 @@ int main(int argc, char **argv){ int num_hosts; int max_display=0; - int title; + int title=1; int cmdopt; extern int optind; @@ -711,6 +814,8 @@ int main(int argc, char **argv){ display_config_t display_config; char ch; + int data_fileno, stdin_fileno, biggest_fileno; + sortby_ptr=NULL; /* What to display defaults */ @@ -746,10 +851,10 @@ int main(int argc, char **argv){ display_config.network_io_total_tx=1; display_config.network_io_total_rx=1; - display_config.network_all_stats=1; + display_config.network_all_stats=0; - display_config.disk_io_total_write=0; - display_config.disk_io_total_read=0; + display_config.disk_io_total_write=1; + display_config.disk_io_total_read=1; display_config.disk_io_all_stats=0; display_config.disk_total_used=0; @@ -763,13 +868,20 @@ int main(int argc, char **argv){ case 's': if(!strcmp(optarg, "cpu")){ sortby_ptr=cmp_cpu_used; + strlcpy(display_config.sortby, CPU_USED, SORTBYMAXNAME); } if(!strcmp(optarg, "load")){ sortby_ptr=cmp_load_1; + strlcpy(display_config.sortby, LOAD, SORTBYMAXNAME); } if(!strcmp(optarg, "mem")){ sortby_ptr=cmp_memory_used_pecent; + strlcpy(display_config.sortby, MEM, SORTBYMAXNAME); } + if(!strcmp(optarg, "swap")){ + sortby_ptr=cmp_swap_used_pecent; + strlcpy(display_config.sortby, SWAP, SORTBYMAXNAME); + } if(sortby_ptr==NULL){ errf("Invalid sort type"); exit(1); @@ -778,7 +890,10 @@ int main(int argc, char **argv){ } } - if(sortby_ptr==NULL) sortby_ptr=cmp_cpu_used; + if(sortby_ptr==NULL){ + sortby_ptr=cmp_cpu_used; + strlcpy(display_config.sortby, "CPU Used", SORTBYMAXNAME); + } if(argc<(optind+2)){ printf("Usage is %s <-d lines> hostname port \n", argv[0]); @@ -847,26 +962,161 @@ int main(int argc, char **argv){ cbreak(); echo(); window=newwin(0, 0, 0, 0); + getmaxyx(window, maxy, maxx); + stdin_fileno=fileno(stdin); + data_fileno=fileno(data); + biggest_fileno=(data_fileno>stdin_fileno) ? (data_fileno+1) : (stdin_fileno+1); + for(;;){ - response=fpgetline(data); - if (response==NULL){ - errf("Failed to read data (%m)"); - exit(1); - } + FD_ZERO(&infds); + FD_SET(stdin_fileno, &infds); + FD_SET(data_fileno, &infds); + select(biggest_fileno, &infds, NULL, NULL, NULL); + + if(FD_ISSET(stdin_fileno, &infds)){ + + ch=getc(stdin); + switch(ch){ -/* ch=getc(stdin); + /* Quit */ + case 'Q': + case 'q': + endwin(); + exit(0); + break; - if(ch=='q'){ - endwin(); - exit(0); + /* Sort by */ + case 'C': + sortby_ptr=cmp_cpu_used; + strlcpy(display_config.sortby, CPU_USED, SORTBYMAXNAME); + break; + + case 'M': + sortby_ptr=cmp_memory_used_pecent; + strlcpy(display_config.sortby, MEM, SORTBYMAXNAME); + break; + + case 'L': + sortby_ptr=cmp_load_1; + strlcpy(display_config.sortby, LOAD, SORTBYMAXNAME); + break; + + case 'S': + sortby_ptr=cmp_swap_used_pecent; + strlcpy(display_config.sortby, SWAP, SORTBYMAXNAME); + break; + + case 'N': + if(sortby_ptr==cmp_network_io_total){ + strlcpy(display_config.sortby, NETIORX, SORTBYMAXNAME); + sortby_ptr=cmp_network_io_total_rx; + }else if(sortby_ptr==cmp_network_io_total_rx){ + strlcpy(display_config.sortby, NETIOTX, SORTBYMAXNAME); + sortby_ptr=cmp_network_io_total_tx; + }else{ + strlcpy(display_config.sortby, NETIO, SORTBYMAXNAME); + sortby_ptr=cmp_network_io_total; + } + break; + case 'D': + if(sortby_ptr==cmp_disk_io_total){ + strlcpy(display_config.sortby, DISKIOR, SORTBYMAXNAME); + sortby_ptr=cmp_disk_io_total_read; + }else if(sortby_ptr==cmp_disk_io_total_read){ + strlcpy(display_config.sortby, DISKIOW, SORTBYMAXNAME); + sortby_ptr=cmp_disk_io_total_write; + }else{ + strlcpy(display_config.sortby, DISKIO, SORTBYMAXNAME); + sortby_ptr=cmp_disk_io_total; + } + break; + + /* Display */ + + case 'd': + if(display_config.disk_io_total_read){ + display_config.disk_io_total_read=0; + display_config.disk_io_total_write=0; + }else{ + display_config.disk_io_total_read=1; + display_config.disk_io_total_write=1; + } + break; + case 'n': + if(display_config.network_io_total_rx){ + display_config.network_io_total_rx=0; + display_config.network_io_total_tx=0; + }else{ + display_config.network_io_total_rx=1; + display_config.network_io_total_tx=1; + } + break; + case 'm': + if(display_config.memory_used_pecent){ + display_config.memory_used_pecent=0; + }else{ + display_config.memory_used_pecent=1; + } + break; + + case 's': + if(display_config.swap_used_pecent){ + display_config.swap_used_pecent=0; + }else{ + display_config.swap_used_pecent=1; + } + break; + case 'l': + if(display_config.load_1){ + display_config.load_1=0; + }else{ + display_config.load_1=1; + } + break; + case 'p': + if(display_config.pages_in){ + display_config.pages_in=0; + display_config.pages_out=0; + }else{ + display_config.pages_in=1; + display_config.pages_out=1; + } + break; + case 'c': + if(display_config.cpu_used){ + display_config.cpu_used=0; + }else{ + display_config.cpu_used=1; + } + break; + + default: + /* Invalid key.. Ignore.. Set Title to -1, as the + * title++ will then make that "0" (false) so a + * screen redraw will not happen */ + title=-1; + break; + } + + /* Increment title so it becomes true (and making the screen update */ + title++; + } -*/ + if(FD_ISSET(data_fileno, &infds)){ + response=fpgetline(data); + if (response==NULL){ + errf("Failed to read data (%m)"); + exit(1); + } + } + + num_hosts=parse_xml(response, &machine_data_list); if(num_hosts==-1) continue; machine_data_list=sort_machine_stats(machine_data_list, num_hosts, sortby_ptr); if(max_display==0){ - display(machine_data_list, &display_config, num_hosts, &title); + display(machine_data_list, &display_config, maxy, &title); }else{ display(machine_data_list, &display_config, max_display, &title); }