ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/idar/idar.c
Revision: 1.8
Committed: Sun Mar 30 23:21:55 2003 UTC (21 years, 8 months ago) by pajs
Content type: text/plain
Branch: MAIN
Changes since 1.7: +87 -5 lines
Log Message:
Now allows the user to choose whats being displayed. Currently only allows
the toggling of what we display by default, but its minor work adding the
others. I think may need to change the display structure, as i dont think
i will end up implementing like my original plan was.

Currently it does
'm' (memory)
's' (swap)
'l' (load)
'd' (disk_io)
'n' (network)
'p' (paging)
'c' (cpu)

File Contents

# User Rev Content
1 tdb 1.3 /*
2     * i-scream central monitoring system
3     * http://www.i-scream.org.uk
4     * Copyright (C) 2000-2002 i-scream
5     *
6     * This program is free software; you can redistribute it and/or
7     * modify it under the terms of the GNU General Public License
8     * as published by the Free Software Foundation; either version 2
9     * of the License, or (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19     */
20    
21     #ifdef HAVE_CONFIG_H
22     #include "config.h"
23     #endif
24    
25 pajs 1.1 #include <stdio.h>
26     #include <string.h>
27     #include <sys/types.h>
28     #include <sys/socket.h>
29     #include <unistd.h>
30     #include <stdlib.h>
31     #include <ukcprog.h>
32    
33     #include <libxml/xmlmemory.h>
34     #include <libxml/parser.h>
35     #include "genmergesort.h"
36 tdb 1.6
37     #ifdef HAVE_NCURSES_H
38     #include <ncurses.h>
39     #else
40 pajs 1.4 #include <curses.h>
41 tdb 1.6 #endif
42 pajs 1.1
43     struct host_line_t{
44     char *hostname;
45     int line;
46    
47     struct host_line_t *next;
48     };
49     typedef struct host_line_t host_line_list_t;
50    
51     struct diskio_data_t{
52     char *name;
53    
54     long long read;
55     long long write;
56    
57     struct diskio_data_t *next;
58     };
59     typedef struct diskio_data_t diskio_data_list_t;
60    
61     struct network_data_t{
62     char *name;
63    
64     long long rx;
65     long long tx;
66    
67     struct network_data_t *next;
68     };
69     typedef struct network_data_t network_data_list_t;
70    
71     /*
72     struct disk_data_t{
73     char *name;
74     char *mount_pnt;
75    
76     long long total_space;
77     long long total_used;
78     long long total_avail;
79     // Other data we are less intrested in are not stored
80    
81     struct disk_data_t *next;
82     };
83     typedef struct disk_data_t disk_data_list_t;
84     */
85     #define MAXHOSTNAMESIZE 10
86     struct machine_data_t{
87    
88     char *name;
89    
90     char sysname[MAXHOSTNAMESIZE+1];
91    
92     double cpu_user;
93     double cpu_idle;
94     double cpu_iowait;
95     double cpu_kernel;
96     double cpu_swap;
97     double cpu_used; /* 100 - idle */
98    
99     long long memory_total;
100     long long memory_free;
101     long long memory_used;
102     double memory_used_pecent;
103    
104     long long swap_total;
105     long long swap_free;
106     long long swap_used;
107     double swap_used_pecent;
108    
109     int pages_in;
110     int pages_out;
111    
112     double load_1;
113     double load_5;
114     double load_15;
115    
116     int processes_total;
117     int processes_sleeping;
118     int processes_cpu;
119     int processes_zombie;
120     int processes_stopped;
121    
122     network_data_list_t *network_data_list;
123     long long network_io_total_tx;
124     long long network_io_total_rx;
125 pajs 1.7 long long network_io_total;
126 pajs 1.1
127     diskio_data_list_t *diskio_data_list;
128     long long disk_io_total_write;
129     long long disk_io_total_read;
130 pajs 1.7 long long disk_io_total;
131 pajs 1.1
132     /* Maybe in the future */
133     /*
134     disk_data_list_t disk_data_list;
135     double disk_total_used;
136     */
137    
138     struct machine_data_t *next;
139     };
140    
141     typedef struct machine_data_t machine_data_list_t;
142    
143 pajs 1.7 #define SORTBYMAXNAME 128
144 pajs 1.1 typedef struct{
145     int cpu_user;
146     int cpu_idle;
147     int cpu_iowait;
148     int cpu_kernel;
149     int cpu_swap;
150     int cpu_used;
151    
152     int memory_total;
153     int memory_free;
154     int memory_used;
155     int memory_used_pecent;
156    
157     int swap_total;
158     int swap_free;
159     int swap_used;
160     int swap_used_pecent;
161    
162     int load_1;
163     int load_5;
164     int load_15;
165    
166     int pages_in;
167     int pages_out;
168    
169     int processes_total;
170     int processes_sleeping;
171     int processes_cpu;
172     int processes_zombie;
173     int processes_stopped;
174    
175     int network_io_total_tx;
176     int network_io_total_rx;
177     int network_all_stats;
178    
179     int disk_io_total_write;
180     int disk_io_total_read;
181     int disk_io_all_stats;
182    
183     int disk_total_used;
184     int disk_all_stats;
185 pajs 1.7
186     char sortby[SORTBYMAXNAME];
187 pajs 1.1 }display_config_t;
188    
189     GENERIC_MERGE_SORT(static, sort_machine_stats, machine_data_list_t, next)
190    
191 pajs 1.2 #define MKCMP(x) int cmp_##x(machine_data_list_t *a, machine_data_list_t *b){return ((a->x) == (b->x)? 0 : (((a->x) > (b->x))? -1 : 1));}
192    
193    
194     int (*sortby_ptr)(machine_data_list_t *a, machine_data_list_t *b);
195    
196     MKCMP(cpu_used)
197     MKCMP(load_1)
198 pajs 1.7 MKCMP(network_io_total)
199 pajs 1.2 MKCMP(network_io_total_tx)
200     MKCMP(network_io_total_rx)
201 pajs 1.7 MKCMP(disk_io_total)
202 pajs 1.2 MKCMP(disk_io_total_write)
203     MKCMP(disk_io_total_read)
204     MKCMP(memory_used_pecent)
205     MKCMP(swap_used_pecent)
206    
207 pajs 1.7 #define CPU_USED "CPU used"
208     #define LOAD "Load (1)"
209     #define NETIORX "total Network RX for all interfaces"
210     #define NETIOTX "total Network TX for all interfaces"
211     #define NETIO "total Network IO for all interfaces (rx+tx)"
212     #define MEM "Memory usage"
213     #define SWAP "Swap usage"
214     #define DISKIOR "DiskIO reads"
215     #define DISKIOW "DiskIO writes"
216     #define DISKIO "Total DiskIO (reads+writes)"
217    
218    
219 pajs 1.2 /*
220 pajs 1.1 int cmp_cpu(machine_data_list_t *a, machine_data_list_t *b){
221    
222     if(a->cpu_used == b->cpu_used){
223     if(a->load_1 == b->load_1) return 0;
224     if(a->load_1 > b->load_1){
225     return -1;
226     }else{
227     return 1;
228     }
229     }
230    
231     if((a->cpu_used) > (b->cpu_used)){
232     return -1;
233     }else{
234     return 1;
235     }
236     }
237 pajs 1.2 */
238 pajs 1.1
239     FILE *create_tcp_connection(char *hostname, int port){
240     int sock;
241     struct sockaddr_in addr;
242     struct in_addr haddr;
243     FILE *f;
244    
245     if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))<0){
246     return NULL;
247     }
248    
249     if((get_host_addr(hostname, &haddr))!=0){
250     close(sock);
251     return NULL;
252     }
253    
254     memset(&addr, 0, sizeof(addr));
255     addr.sin_family = AF_INET;
256     memcpy(&addr.sin_addr, &haddr, sizeof(haddr));
257     addr.sin_port = htons(port);
258    
259     if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) !=0){
260     close(sock);
261     return NULL;
262     }
263    
264     if((f=fdopen(sock, "r+"))==NULL){
265     close(sock);
266     return NULL;
267     }
268    
269     return f;
270     }
271    
272     int tcp_comm(FILE *f, char *send, char **response, char *expected){
273    
274     if(send!=NULL){
275     fprintf(f, "%s\n", send);
276     }
277     fflush(f);
278     *response=fpgetline(f);
279     fseek(f, 0, SEEK_CUR);
280    
281     if( (*response==NULL) || (strcmp(*response, "ERROR")==0) ) return -1;
282    
283     if(expected==NULL) return 0;
284    
285     if((strcmp(expected, *response))==0) return 0;
286    
287     return -1;
288     }
289    
290     /* Takes a xml char * and a machine_data_list_t. This will parse
291     * the xml and put it into the correct entry of the machine_data
292     * linked list. This will return the number of entries in the linked
293     * list, or -1 on a error.
294     */
295     int parse_xml(char *xml, machine_data_list_t **md){
296     xmlDocPtr doc;
297     xmlNodePtr cur;
298     xmlNodePtr ele;
299     xmlAttr *list;
300    
301     static int num_hosts=0;
302    
303     machine_data_list_t *machine_data_list=*md;
304    
305     int found_host=0;
306    
307     char *hostname=NULL;
308     network_data_list_t *network_data_list=NULL;
309     network_data_list_t *ndl_ptr=NULL;
310     diskio_data_list_t *diskio_data_list=NULL;
311     diskio_data_list_t *didl_ptr=NULL;
312     char *tmp;
313    
314     doc=xmlParseDoc(xml);
315     if(doc==NULL) return -1;
316    
317     cur = xmlDocGetRootElement(doc);
318     if(cur==NULL){
319     xmlFreeDoc(doc);
320     return -1;
321     }
322    
323    
324     /* Get the hostname */
325     list=cur->properties;
326     while(list!=NULL){
327     if((xmlStrcmp(list->name, (const xmlChar *) "machine_name"))==0){
328     hostname = xmlNodeGetContent(list->children);
329     if(hostname==NULL){
330     return -1;
331     }
332     }
333     list=list->next;
334     }
335     if(hostname==NULL){
336     return -1;
337     }
338    
339     /* Get machine_data for host.. Or create if it doesn't have one */
340     while(machine_data_list!=NULL){
341     if((strncmp(machine_data_list->name, hostname, strlen(hostname)))==0){
342     found_host=1;
343     break;
344     }
345     machine_data_list=machine_data_list->next;
346     }
347    
348     if(!found_host){
349     /* We didn't find this host, but we should be at the end of the list */
350     machine_data_list=malloc(sizeof(machine_data_list_t));
351     if(machine_data_list==NULL) return -1;
352     machine_data_list->next=(*md);
353     machine_data_list->name=hostname;
354     machine_data_list->network_data_list=NULL;
355     machine_data_list->diskio_data_list=NULL;
356     *md=machine_data_list;
357     num_hosts++;
358     }
359    
360     /* Now we want to pull out the data */
361    
362     cur = cur->xmlChildrenNode;
363     while(cur != NULL) {
364     ele=cur->xmlChildrenNode;
365     while(ele != NULL){
366    
367     /* CPU Stats */
368     if(!xmlStrcmp(cur->name, (const xmlChar *) "cpu")){
369     tmp=xmlNodeGetContent(ele);
370     if(!xmlStrcmp(ele->name, (const xmlChar *) "user")){
371     machine_data_list->cpu_user=atof(tmp);
372     }
373     if(!xmlStrcmp(ele->name, (const xmlChar *) "kernel")){
374     machine_data_list->cpu_kernel=atof(tmp);
375     }
376     if(!xmlStrcmp(ele->name, (const xmlChar *) "idle")){
377     machine_data_list->cpu_idle=atof(tmp);
378     }
379     if(!xmlStrcmp(ele->name, (const xmlChar *) "iowait")){
380     machine_data_list->cpu_iowait=atof(tmp);
381     }
382     if(!xmlStrcmp(ele->name, (const xmlChar *) "swap")){
383     machine_data_list->cpu_iowait=atof(tmp);
384     }
385    
386     if(tmp!=NULL) xmlFree(tmp);
387     }
388    
389     /* Memory Stats */
390     if(!xmlStrcmp(cur->name, (const xmlChar *) "memory")){
391     tmp=xmlNodeGetContent(ele);
392     if(!xmlStrcmp(ele->name, (const xmlChar *) "total")){
393     machine_data_list->memory_total=atoll(tmp);
394     }
395     if(!xmlStrcmp(ele->name, (const xmlChar *) "free")){
396     machine_data_list->memory_free=atoll(tmp);
397     }
398     if(!xmlStrcmp(ele->name, (const xmlChar *) "used")){
399     machine_data_list->memory_used=atoll(tmp);
400     }
401    
402     if(tmp!=NULL) xmlFree(tmp);
403     }
404    
405     /* Load Stats */
406     if(!xmlStrcmp(cur->name, (const xmlChar *) "load")){
407     tmp=xmlNodeGetContent(ele);
408     if(!xmlStrcmp(ele->name, (const xmlChar *) "load1")){
409     machine_data_list->load_1=atof(tmp);
410     }
411     if(!xmlStrcmp(ele->name, (const xmlChar *) "load5")){
412     machine_data_list->load_5=atof(tmp);
413     }
414     if(!xmlStrcmp(ele->name, (const xmlChar *) "load15")){
415     machine_data_list->load_15=atof(tmp);
416     }
417    
418     if(tmp!=NULL) xmlFree(tmp);
419     }
420    
421     /* swap stats */
422     if(!xmlStrcmp(cur->name, (const xmlChar *) "swap")){
423     tmp=xmlNodeGetContent(ele);
424     if(!xmlStrcmp(ele->name, (const xmlChar *) "total")){
425     machine_data_list->swap_total=atoll(tmp);
426     }
427     if(!xmlStrcmp(ele->name, (const xmlChar *) "free")){
428     machine_data_list->swap_free=atoll(tmp);
429     }
430     if(!xmlStrcmp(ele->name, (const xmlChar *) "used")){
431     machine_data_list->swap_used=atoll(tmp);
432     }
433    
434     if(tmp!=NULL) xmlFree(tmp);
435     }
436    
437     /* Process stat */
438     if(!xmlStrcmp(cur->name, (const xmlChar *) "processes")){
439     tmp=xmlNodeGetContent(ele);
440     if(!xmlStrcmp(ele->name, (const xmlChar *) "sleeping")){
441     machine_data_list->processes_sleeping=atoi(tmp);
442     }
443     if(!xmlStrcmp(ele->name, (const xmlChar *) "cpu")){
444     machine_data_list->processes_cpu=atoi(tmp);
445     }
446     if(!xmlStrcmp(ele->name, (const xmlChar *) "zombie")){
447     machine_data_list->processes_zombie=atoi(tmp);
448     }
449     if(!xmlStrcmp(ele->name, (const xmlChar *) "total")){
450     machine_data_list->processes_total=atoi(tmp);
451     }
452    
453     if(tmp!=NULL) xmlFree(tmp);
454     }
455    
456     /* paging stats */
457     if(!xmlStrcmp(cur->name, (const xmlChar *) "pages")){
458     tmp=xmlNodeGetContent(ele);
459     if(!xmlStrcmp(ele->name, (const xmlChar *) "pageins")){
460     machine_data_list->pages_in=atoi(tmp);
461     }
462     if(!xmlStrcmp(ele->name, (const xmlChar *) "pageouts")){
463     machine_data_list->pages_out=atoi(tmp);
464     }
465    
466     if(tmp!=NULL) xmlFree(tmp);
467     }
468    
469     /* OS stats */
470     if(!xmlStrcmp(cur->name, (const xmlChar *) "os")){
471     tmp=xmlNodeGetContent(ele);
472     if(!xmlStrcmp(ele->name, (const xmlChar *) "sysname")){
473     strlcpy(machine_data_list->sysname, tmp, MAXHOSTNAMESIZE+1);
474     }
475     if(tmp!=NULL) xmlFree(tmp);
476     }
477    
478     /* Network stats */
479     /* Needs to connect current stat to a previous one. Or create it if new */
480     /* Get name.. Walk list. If match, copy rx/tx values. Else malloc, add to list */
481     if(!xmlStrcmp(cur->name, (const xmlChar *) "net")){
482    
483     list=ele->properties;
484     if(list==NULL) continue;
485     network_data_list=malloc(sizeof(network_data_list_t));
486     if(network_data_list==NULL) return -1;
487     while(list!=NULL){
488     tmp=xmlNodeGetContent(list->children);
489     if(!xmlStrcmp(list->name, (const xmlChar *) "name")){
490     network_data_list->name=strdup(tmp);
491     }
492     if(!xmlStrcmp(list->name, (const xmlChar *) "rx")){
493     network_data_list->rx=atoll(tmp);
494     }
495     if(!xmlStrcmp(list->name, (const xmlChar *) "tx")){
496     network_data_list->tx=atoll(tmp);
497     }
498    
499     xmlFree(tmp);
500     list=list->next;
501     }
502     if(network_data_list->name==NULL) continue;
503     found_host=0;
504     ndl_ptr=machine_data_list->network_data_list;
505     while(ndl_ptr!=NULL){
506     if(!strcmp(ndl_ptr->name, network_data_list->name)){
507     found_host=1;
508     break;
509     }
510     ndl_ptr=ndl_ptr->next;
511     }
512     if(found_host){
513     ndl_ptr->rx=network_data_list->rx;
514     ndl_ptr->tx=network_data_list->tx;
515     free(network_data_list->name);
516     free(network_data_list);
517     }else{
518     network_data_list->next=machine_data_list->network_data_list;
519     machine_data_list->network_data_list=network_data_list;
520     }
521     }
522    
523     /* Disk IO stats */
524     if(!xmlStrcmp(cur->name, (const xmlChar *) "diskio")){
525    
526     list=ele->properties;
527     if(list==NULL) continue;
528     diskio_data_list=malloc(sizeof(diskio_data_list_t));
529     if(diskio_data_list==NULL) return -1;
530     while(list!=NULL){
531     tmp=xmlNodeGetContent(list->children);
532     if(!xmlStrcmp(list->name, (const xmlChar *) "name")){
533     diskio_data_list->name=strdup(tmp);
534     }
535     if(!xmlStrcmp(list->name, (const xmlChar *) "rbytes")){
536     diskio_data_list->read=atoll(tmp);
537     }
538     if(!xmlStrcmp(list->name, (const xmlChar *) "wbytes")){
539     diskio_data_list->write=atoll(tmp);
540     }
541    
542     xmlFree(tmp);
543     list=list->next;
544     }
545     if(diskio_data_list->name==NULL) continue;
546     found_host=0;
547     didl_ptr=machine_data_list->diskio_data_list;
548     while(didl_ptr!=NULL){
549     if(!strcmp(didl_ptr->name, diskio_data_list->name)){
550     found_host=1;
551     break;
552     }
553     didl_ptr=didl_ptr->next;
554     }
555     if(found_host){
556     didl_ptr->read=diskio_data_list->read;
557     didl_ptr->write=diskio_data_list->write;
558     free(diskio_data_list->name);
559     free(diskio_data_list);
560     }else{
561     diskio_data_list->next=machine_data_list->diskio_data_list;
562     machine_data_list->diskio_data_list=diskio_data_list;
563     }
564     }
565    
566    
567    
568     ele=ele->next;
569     }
570     cur=cur->next;
571     }
572    
573     /* Append data we want thats not stored in the server */
574     machine_data_list->cpu_used=100.00-machine_data_list->cpu_idle;
575     machine_data_list->memory_used_pecent=((double)machine_data_list->memory_used / (double)machine_data_list->memory_total) * 100.00;
576     machine_data_list->swap_used_pecent=((double)machine_data_list->swap_used / (double)machine_data_list->swap_total) * 100.00;
577    
578     ndl_ptr=machine_data_list->network_data_list;
579     machine_data_list->network_io_total_tx=0;
580     machine_data_list->network_io_total_rx=0;
581     while(ndl_ptr!=NULL){
582     machine_data_list->network_io_total_tx+=ndl_ptr->tx;
583     machine_data_list->network_io_total_rx+=ndl_ptr->rx;
584     ndl_ptr=ndl_ptr->next;
585     }
586 pajs 1.7 machine_data_list->network_io_total=machine_data_list->network_io_total_rx+machine_data_list->network_io_total_tx;
587 pajs 1.1
588     didl_ptr=machine_data_list->diskio_data_list;
589     machine_data_list->disk_io_total_read=0;
590     machine_data_list->disk_io_total_write=0;
591     while(didl_ptr!=NULL){
592     machine_data_list->disk_io_total_read+=didl_ptr->read;
593     machine_data_list->disk_io_total_write+=didl_ptr->write;
594     didl_ptr=didl_ptr->next;
595     }
596 pajs 1.7 machine_data_list->disk_io_total=machine_data_list->disk_io_total_read+machine_data_list->disk_io_total_write;
597 pajs 1.1
598     xmlFreeDoc(doc);
599    
600     return num_hosts;
601    
602    
603     }
604    
605 pajs 1.2 void display(machine_data_list_t *machine_data_list, display_config_t *display_config, int num_lines, int *title){
606 pajs 1.1 int line_num=4;
607 pajs 1.7 int counter;
608 pajs 1.2 int x=1;
609    
610     if(*title){
611 pajs 1.8 clear();
612 pajs 1.7 move (num_lines-3, 1);
613     printw("Sorting by %-64s", display_config->sortby);
614    
615 pajs 1.4 move(1,1);
616     printw("%-11s", "Hostname");
617 pajs 1.2 x=x+11+1;
618     if(display_config->cpu_used){
619 pajs 1.4 move(1,x);
620     printw("%5s", "CPU");
621     move(2,x);
622     printw("%5s", "used%");
623 pajs 1.2 x+=6;
624     }
625     if(display_config->load_1){
626 pajs 1.4 move(1,x);
627     printw("%5s", "Load");
628     move(2,x);
629     printw("%5s", "(1m)");
630 pajs 1.2 x+=6;
631     }
632     if(display_config->pages_in){
633 pajs 1.4 move(1,x);
634     printw("%5s", "Page");
635     move(2,x);
636     printw("%5s", "ins");
637 pajs 1.2 x+=6;
638     }
639     if(display_config->pages_out){
640 pajs 1.4 move(1,x);
641     printw("%5s", "Page");
642     move(2,x);
643     printw("%5s", "outs");
644 pajs 1.2 x+=6;
645     }
646     if(display_config->memory_used_pecent){
647 pajs 1.4 move(1,x);
648     printw("%5s", "Mem");
649     move(2,x);
650     printw("%5s", "used");
651 pajs 1.2 x+=6;
652     }
653     if(display_config->swap_used_pecent){
654 pajs 1.4 move(1,x);
655     printw("%5s", "Swap");
656     move(2,x);
657     printw("%5s", "used");
658 pajs 1.2 x+=6;
659     }
660     if(display_config->network_io_total_rx){
661 pajs 1.4 move(1,x);
662     printw("%8s", "Net");
663     move(2,x);
664     printw("%8s", "rx");
665 pajs 1.2 x+=9;
666     }
667     if(display_config->network_io_total_tx){
668 pajs 1.4 move(1,x);
669     printw("%8s", "Net");
670     move(2,x);
671     printw("%8s", "tx");
672 pajs 1.2 x+=9;
673     }
674     if(display_config->disk_io_total_read){
675 pajs 1.4 move(1,x);
676     printw("%9s", "Disk");
677     move(2,x);
678     printw("%9s", "read");
679 pajs 1.2 x+=10;
680     }
681     if(display_config->disk_io_total_read){
682 pajs 1.4 move(1,x);
683     printw("%9s", "Disk");
684     move(2,x);
685     printw("%9s", "write");
686 pajs 1.2 x+=10;
687     }
688    
689     *title=0;
690     }
691 pajs 1.1
692 pajs 1.7 /* Counter starts at 8, for padding (eg, headers, borders etc) */
693     for(counter=8;counter<num_lines;counter++){
694 pajs 1.1 if(machine_data_list==NULL) break;
695 pajs 1.4 move(line_num++, 1);
696     printw("%-11s", machine_data_list->sysname);
697 pajs 1.2
698 pajs 1.4 if(display_config->cpu_used) printw(" %5.1f", machine_data_list->cpu_used);
699     if(display_config->load_1) printw(" %5.1f", machine_data_list->load_1);
700     if(display_config->pages_in) printw(" %5d", machine_data_list->pages_in);
701     if(display_config->pages_out) printw(" %5d", machine_data_list->pages_out);
702     if(display_config->memory_used_pecent) printw(" %5.1f", machine_data_list->memory_used_pecent);
703     if(display_config->swap_used_pecent) printw(" %5.1f", machine_data_list->swap_used_pecent);
704     if(display_config->network_io_total_rx) printw(" %8lld", machine_data_list->network_io_total_rx);
705     if(display_config->network_io_total_tx) printw(" %8lld", machine_data_list->network_io_total_tx);
706     if(display_config->disk_io_total_read) printw(" %9lld", machine_data_list->disk_io_total_read);
707     if(display_config->disk_io_total_write) printw(" %9lld", machine_data_list->disk_io_total_write);
708 pajs 1.2
709 pajs 1.1 machine_data_list=machine_data_list->next;
710     }
711    
712 pajs 1.2
713 pajs 1.4 refresh();
714 pajs 1.1
715     }
716    
717     int main(int argc, char **argv){
718 pajs 1.4 WINDOW *window;
719 pajs 1.5 fd_set infds;
720 pajs 1.7 int maxx, maxy;
721 pajs 1.4
722 pajs 1.1 FILE *control;
723     FILE *data;
724    
725     char *machine_list=NULL;
726     char *response=NULL;
727    
728     char *servername;
729     int server_control_port;
730     int server_data_port;
731    
732     machine_data_list_t *machine_data_list=NULL;
733    
734     int num_hosts;
735     int max_display=0;
736 pajs 1.7 int title=1;
737 pajs 1.1
738     int cmdopt;
739     extern int optind;
740     extern char *optarg;
741    
742     display_config_t display_config;
743 pajs 1.4 char ch;
744    
745 pajs 1.5 int data_fileno, stdin_fileno, biggest_fileno;
746    
747 pajs 1.4 sortby_ptr=NULL;
748 pajs 1.1
749     /* What to display defaults */
750     display_config.cpu_user=0;
751     display_config.cpu_idle=0;
752     display_config.cpu_iowait=0;
753     display_config.cpu_kernel=0;
754     display_config.cpu_swap=0;
755     display_config.cpu_used=1;
756    
757     display_config.memory_total=0;
758     display_config.memory_free=0;
759     display_config.memory_used=0;
760     display_config.memory_used_pecent=1;
761    
762     display_config.swap_total=0;
763     display_config.swap_free=0;
764     display_config.swap_used=0;
765     display_config.swap_used_pecent=1;
766    
767     display_config.load_1=1;
768     display_config.load_5=0;
769     display_config.load_15=0;
770    
771     display_config.pages_in=1;
772     display_config.pages_out=1;
773    
774     display_config.processes_total=0;
775     display_config.processes_sleeping=0;
776     display_config.processes_cpu=0;
777     display_config.processes_zombie=0;
778     display_config.processes_stopped=0;
779    
780 pajs 1.2 display_config.network_io_total_tx=1;
781     display_config.network_io_total_rx=1;
782 pajs 1.8 display_config.network_all_stats=0;
783 pajs 1.1
784 pajs 1.8 display_config.disk_io_total_write=1;
785     display_config.disk_io_total_read=1;
786 pajs 1.2 display_config.disk_io_all_stats=0;
787 pajs 1.1
788     display_config.disk_total_used=0;
789     display_config.disk_all_stats=0;
790    
791 pajs 1.2 while((cmdopt=getopt(argc, argv, "d:s:")) != -1){
792 pajs 1.1 switch(cmdopt){
793     case 'd':
794     max_display=atoi(optarg);
795     break;
796 pajs 1.2 case 's':
797     if(!strcmp(optarg, "cpu")){
798     sortby_ptr=cmp_cpu_used;
799 pajs 1.7 strlcpy(display_config.sortby, CPU_USED, SORTBYMAXNAME);
800 pajs 1.2 }
801     if(!strcmp(optarg, "load")){
802     sortby_ptr=cmp_load_1;
803 pajs 1.7 strlcpy(display_config.sortby, LOAD, SORTBYMAXNAME);
804 pajs 1.2 }
805     if(!strcmp(optarg, "mem")){
806     sortby_ptr=cmp_memory_used_pecent;
807 pajs 1.7 strlcpy(display_config.sortby, MEM, SORTBYMAXNAME);
808 pajs 1.2 }
809 pajs 1.7 if(!strcmp(optarg, "swap")){
810     sortby_ptr=cmp_swap_used_pecent;
811     strlcpy(display_config.sortby, SWAP, SORTBYMAXNAME);
812     }
813 pajs 1.2 if(sortby_ptr==NULL){
814     errf("Invalid sort type");
815     exit(1);
816     }
817     break;
818 pajs 1.1 }
819     }
820    
821 pajs 1.7 if(sortby_ptr==NULL){
822     sortby_ptr=cmp_cpu_used;
823     strlcpy(display_config.sortby, "CPU Used", SORTBYMAXNAME);
824     }
825 pajs 1.1
826     if(argc<(optind+2)){
827     printf("Usage is %s <-d lines> hostname port <machine list>\n", argv[0]);
828     exit(1);
829     }
830    
831     servername=argv[optind];
832     server_control_port=atoi(argv[optind+1]);
833    
834     control=create_tcp_connection(servername, server_control_port);
835     if(control==NULL){
836     errf("Failed to connect (%m)");
837     }
838    
839     if(argc==4){
840     /* We've been passed a machine list */
841     /* list currently needs to be ; seperated */
842     machine_list=strdup(argv[3]);
843     }
844    
845     if((tcp_comm(control, NULL, &response, "PROTOCOL 1.1"))!=0){
846     errf("Incorrect version number (%s)", response);
847     exit(1);
848     }
849    
850     if((tcp_comm(control, "stattop", &response, "OK"))!=0){
851     errf("Unexpected response %s", response);
852     exit(1);
853     }
854    
855     if(machine_list!=NULL){
856     if((tcp_comm(control, "SETHOSTLIST", &response, "OK"))!=0){
857     errf("Unexpected response %s", response);
858     exit(1);
859     }
860     if((tcp_comm(control, machine_list, &response, "OK"))!=0){
861     errf("Unexpected response %s", response);
862     exit(1);
863     }
864     }
865    
866     if((tcp_comm(control, "STARTDATA", &response, NULL))!=0){
867     errf("Unexpected response %s", response);
868     exit(1);
869     }
870    
871     server_data_port=atoi(response);
872     if(server_data_port==0){
873     errf("Unexpected response %s", response);
874     exit(1);
875     }
876    
877     data=create_tcp_connection(servername, server_data_port);
878     if(data==NULL){
879     errf("Failed to connect to host %s on port %d (%m)",servername, server_data_port);
880     }
881    
882 pajs 1.2 /*
883 pajs 1.1 printf("\033[2J");
884     printf("\033[1;1HHostname CPU Load Page Page Mem Swap Net Net Disk Disk");
885     printf("\033[2;1H used%% (1m) ins outs used used rx tx read write");
886 pajs 1.2 */
887 pajs 1.4
888     initscr();
889     nonl();
890     cbreak();
891     echo();
892     window=newwin(0, 0, 0, 0);
893 pajs 1.7 getmaxyx(window, maxy, maxx);
894 pajs 1.4
895 pajs 1.5 stdin_fileno=fileno(stdin);
896     data_fileno=fileno(data);
897     biggest_fileno=(data_fileno>stdin_fileno) ? (data_fileno+1) : (stdin_fileno+1);
898 pajs 1.7
899 pajs 1.1 for(;;){
900 pajs 1.5 FD_ZERO(&infds);
901     FD_SET(stdin_fileno, &infds);
902     FD_SET(data_fileno, &infds);
903     select(biggest_fileno, &infds, NULL, NULL, NULL);
904    
905     if(FD_ISSET(stdin_fileno, &infds)){
906    
907     ch=getc(stdin);
908 pajs 1.7 switch(ch){
909 pajs 1.8
910     /* Quit */
911 pajs 1.7 case 'Q':
912     case 'q':
913     endwin();
914     exit(0);
915     break;
916    
917 pajs 1.8 /* Sort by */
918 pajs 1.7 case 'C':
919     sortby_ptr=cmp_cpu_used;
920     strlcpy(display_config.sortby, CPU_USED, SORTBYMAXNAME);
921     break;
922    
923     case 'M':
924     sortby_ptr=cmp_memory_used_pecent;
925     strlcpy(display_config.sortby, MEM, SORTBYMAXNAME);
926     break;
927    
928     case 'L':
929     sortby_ptr=cmp_load_1;
930     strlcpy(display_config.sortby, LOAD, SORTBYMAXNAME);
931     break;
932    
933     case 'S':
934     sortby_ptr=cmp_swap_used_pecent;
935     strlcpy(display_config.sortby, SWAP, SORTBYMAXNAME);
936     break;
937    
938     case 'N':
939     if(sortby_ptr==cmp_network_io_total){
940     strlcpy(display_config.sortby, NETIORX, SORTBYMAXNAME);
941     sortby_ptr=cmp_network_io_total_rx;
942     }else if(sortby_ptr==cmp_network_io_total_rx){
943     strlcpy(display_config.sortby, NETIOTX, SORTBYMAXNAME);
944     sortby_ptr=cmp_network_io_total_tx;
945     }else{
946     strlcpy(display_config.sortby, NETIO, SORTBYMAXNAME);
947     sortby_ptr=cmp_network_io_total;
948     }
949     break;
950 pajs 1.8 case 'D':
951     if(sortby_ptr==cmp_disk_io_total){
952     strlcpy(display_config.sortby, DISKIOR, SORTBYMAXNAME);
953     sortby_ptr=cmp_disk_io_total_read;
954     }else if(sortby_ptr==cmp_disk_io_total_read){
955     strlcpy(display_config.sortby, DISKIOW, SORTBYMAXNAME);
956     sortby_ptr=cmp_disk_io_total_write;
957     }else{
958     strlcpy(display_config.sortby, DISKIO, SORTBYMAXNAME);
959     sortby_ptr=cmp_disk_io_total;
960     }
961     break;
962    
963     /* Display */
964    
965     case 'd':
966     if(display_config.disk_io_total_read){
967     display_config.disk_io_total_read=0;
968     display_config.disk_io_total_write=0;
969     }else{
970     display_config.disk_io_total_read=1;
971     display_config.disk_io_total_write=1;
972     }
973     break;
974     case 'n':
975     if(display_config.network_io_total_rx){
976     display_config.network_io_total_rx=0;
977     display_config.network_io_total_tx=0;
978     }else{
979     display_config.network_io_total_rx=1;
980     display_config.network_io_total_tx=1;
981     }
982     break;
983     case 'm':
984     if(display_config.memory_used_pecent){
985     display_config.memory_used_pecent=0;
986     }else{
987     display_config.memory_used_pecent=1;
988     }
989     break;
990    
991     case 's':
992     if(display_config.swap_used_pecent){
993     display_config.swap_used_pecent=0;
994     }else{
995     display_config.swap_used_pecent=1;
996     }
997     break;
998     case 'l':
999     if(display_config.load_1){
1000     display_config.load_1=0;
1001     }else{
1002     display_config.load_1=1;
1003     }
1004     break;
1005     case 'p':
1006     if(display_config.pages_in){
1007     display_config.pages_in=0;
1008     display_config.pages_out=0;
1009     }else{
1010     display_config.pages_in=1;
1011     display_config.pages_out=1;
1012     }
1013     break;
1014     case 'c':
1015     if(display_config.cpu_used){
1016     display_config.cpu_used=0;
1017     }else{
1018     display_config.cpu_used=1;
1019     }
1020     break;
1021 pajs 1.5
1022 pajs 1.8 default:
1023     /* Invalid key.. Ignore.. Set Title to -1, as the
1024     * title++ will then make that "0" (false) so a
1025     * screen redraw will not happen */
1026     title=-1;
1027     break;
1028 pajs 1.5 }
1029 pajs 1.8
1030     /* Increment title so it becomes true (and making the screen update */
1031     title++;
1032 pajs 1.7
1033 pajs 1.5 }
1034     if(FD_ISSET(data_fileno, &infds)){
1035     response=fpgetline(data);
1036     if (response==NULL){
1037     errf("Failed to read data (%m)");
1038     exit(1);
1039     }
1040 pajs 1.1 }
1041    
1042 pajs 1.4
1043 pajs 1.1 num_hosts=parse_xml(response, &machine_data_list);
1044     if(num_hosts==-1) continue;
1045 pajs 1.2 machine_data_list=sort_machine_stats(machine_data_list, num_hosts, sortby_ptr);
1046 pajs 1.1 if(max_display==0){
1047 pajs 1.7 display(machine_data_list, &display_config, maxy, &title);
1048 pajs 1.1 }else{
1049 pajs 1.2 display(machine_data_list, &display_config, max_display, &title);
1050 pajs 1.1 }
1051    
1052     }
1053     exit(0);
1054     }