ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/idar/idar.c
Revision: 1.4
Committed: Sun Mar 30 01:14:49 2003 UTC (21 years, 9 months ago) by pajs
Content type: text/plain
Branch: MAIN
Changes since 1.3: +79 -41 lines
Log Message:
Now uses ncurses. Not complete, but more infustructure layed down.

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 pajs 1.4 #include <curses.h>
37 pajs 1.1
38     struct host_line_t{
39     char *hostname;
40     int line;
41    
42     struct host_line_t *next;
43     };
44     typedef struct host_line_t host_line_list_t;
45    
46     struct diskio_data_t{
47     char *name;
48    
49     long long read;
50     long long write;
51    
52     struct diskio_data_t *next;
53     };
54     typedef struct diskio_data_t diskio_data_list_t;
55    
56     struct network_data_t{
57     char *name;
58    
59     long long rx;
60     long long tx;
61    
62     struct network_data_t *next;
63     };
64     typedef struct network_data_t network_data_list_t;
65    
66     /*
67     struct disk_data_t{
68     char *name;
69     char *mount_pnt;
70    
71     long long total_space;
72     long long total_used;
73     long long total_avail;
74     // Other data we are less intrested in are not stored
75    
76     struct disk_data_t *next;
77     };
78     typedef struct disk_data_t disk_data_list_t;
79     */
80     #define MAXHOSTNAMESIZE 10
81     struct machine_data_t{
82    
83     char *name;
84    
85     char sysname[MAXHOSTNAMESIZE+1];
86    
87     double cpu_user;
88     double cpu_idle;
89     double cpu_iowait;
90     double cpu_kernel;
91     double cpu_swap;
92     double cpu_used; /* 100 - idle */
93    
94     long long memory_total;
95     long long memory_free;
96     long long memory_used;
97     double memory_used_pecent;
98    
99     long long swap_total;
100     long long swap_free;
101     long long swap_used;
102     double swap_used_pecent;
103    
104     int pages_in;
105     int pages_out;
106    
107     double load_1;
108     double load_5;
109     double load_15;
110    
111     int processes_total;
112     int processes_sleeping;
113     int processes_cpu;
114     int processes_zombie;
115     int processes_stopped;
116    
117     network_data_list_t *network_data_list;
118     long long network_io_total_tx;
119     long long network_io_total_rx;
120    
121     diskio_data_list_t *diskio_data_list;
122     long long disk_io_total_write;
123     long long disk_io_total_read;
124    
125     /* Maybe in the future */
126     /*
127     disk_data_list_t disk_data_list;
128     double disk_total_used;
129     */
130    
131     struct machine_data_t *next;
132     };
133    
134     typedef struct machine_data_t machine_data_list_t;
135    
136     typedef struct{
137     int cpu_user;
138     int cpu_idle;
139     int cpu_iowait;
140     int cpu_kernel;
141     int cpu_swap;
142     int cpu_used;
143    
144     int memory_total;
145     int memory_free;
146     int memory_used;
147     int memory_used_pecent;
148    
149     int swap_total;
150     int swap_free;
151     int swap_used;
152     int swap_used_pecent;
153    
154     int load_1;
155     int load_5;
156     int load_15;
157    
158     int pages_in;
159     int pages_out;
160    
161     int processes_total;
162     int processes_sleeping;
163     int processes_cpu;
164     int processes_zombie;
165     int processes_stopped;
166    
167     int network_io_total_tx;
168     int network_io_total_rx;
169     int network_all_stats;
170    
171     int disk_io_total_write;
172     int disk_io_total_read;
173     int disk_io_all_stats;
174    
175     int disk_total_used;
176     int disk_all_stats;
177     }display_config_t;
178    
179     GENERIC_MERGE_SORT(static, sort_machine_stats, machine_data_list_t, next)
180    
181 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));}
182    
183    
184     int (*sortby_ptr)(machine_data_list_t *a, machine_data_list_t *b);
185    
186     MKCMP(cpu_used)
187     MKCMP(load_1)
188     MKCMP(network_io_total_tx)
189     MKCMP(network_io_total_rx)
190     MKCMP(disk_io_total_write)
191     MKCMP(disk_io_total_read)
192     MKCMP(memory_used_pecent)
193     MKCMP(swap_used_pecent)
194    
195     /*
196 pajs 1.1 int cmp_cpu(machine_data_list_t *a, machine_data_list_t *b){
197    
198     if(a->cpu_used == b->cpu_used){
199     if(a->load_1 == b->load_1) return 0;
200     if(a->load_1 > b->load_1){
201     return -1;
202     }else{
203     return 1;
204     }
205     }
206    
207     if((a->cpu_used) > (b->cpu_used)){
208     return -1;
209     }else{
210     return 1;
211     }
212     }
213 pajs 1.2 */
214 pajs 1.1
215     FILE *create_tcp_connection(char *hostname, int port){
216     int sock;
217     struct sockaddr_in addr;
218     struct in_addr haddr;
219     FILE *f;
220    
221     if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))<0){
222     return NULL;
223     }
224    
225     if((get_host_addr(hostname, &haddr))!=0){
226     close(sock);
227     return NULL;
228     }
229    
230     memset(&addr, 0, sizeof(addr));
231     addr.sin_family = AF_INET;
232     memcpy(&addr.sin_addr, &haddr, sizeof(haddr));
233     addr.sin_port = htons(port);
234    
235     if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) !=0){
236     close(sock);
237     return NULL;
238     }
239    
240     if((f=fdopen(sock, "r+"))==NULL){
241     close(sock);
242     return NULL;
243     }
244    
245     return f;
246     }
247    
248     int tcp_comm(FILE *f, char *send, char **response, char *expected){
249    
250     if(send!=NULL){
251     fprintf(f, "%s\n", send);
252     }
253     fflush(f);
254     *response=fpgetline(f);
255     fseek(f, 0, SEEK_CUR);
256    
257     if( (*response==NULL) || (strcmp(*response, "ERROR")==0) ) return -1;
258    
259     if(expected==NULL) return 0;
260    
261     if((strcmp(expected, *response))==0) return 0;
262    
263     return -1;
264     }
265    
266     /* Takes a xml char * and a machine_data_list_t. This will parse
267     * the xml and put it into the correct entry of the machine_data
268     * linked list. This will return the number of entries in the linked
269     * list, or -1 on a error.
270     */
271     int parse_xml(char *xml, machine_data_list_t **md){
272     xmlDocPtr doc;
273     xmlNodePtr cur;
274     xmlNodePtr ele;
275     xmlAttr *list;
276    
277     static int num_hosts=0;
278    
279     machine_data_list_t *machine_data_list=*md;
280    
281     int found_host=0;
282    
283     char *hostname=NULL;
284     network_data_list_t *network_data_list=NULL;
285     network_data_list_t *ndl_ptr=NULL;
286     diskio_data_list_t *diskio_data_list=NULL;
287     diskio_data_list_t *didl_ptr=NULL;
288     char *tmp;
289    
290     doc=xmlParseDoc(xml);
291     if(doc==NULL) return -1;
292    
293     cur = xmlDocGetRootElement(doc);
294     if(cur==NULL){
295     xmlFreeDoc(doc);
296     return -1;
297     }
298    
299    
300     /* Get the hostname */
301     list=cur->properties;
302     while(list!=NULL){
303     if((xmlStrcmp(list->name, (const xmlChar *) "machine_name"))==0){
304     hostname = xmlNodeGetContent(list->children);
305     if(hostname==NULL){
306     return -1;
307     }
308     }
309     list=list->next;
310     }
311     if(hostname==NULL){
312     return -1;
313     }
314    
315     /* Get machine_data for host.. Or create if it doesn't have one */
316     while(machine_data_list!=NULL){
317     if((strncmp(machine_data_list->name, hostname, strlen(hostname)))==0){
318     found_host=1;
319     break;
320     }
321     machine_data_list=machine_data_list->next;
322     }
323    
324     if(!found_host){
325     /* We didn't find this host, but we should be at the end of the list */
326     machine_data_list=malloc(sizeof(machine_data_list_t));
327     if(machine_data_list==NULL) return -1;
328     machine_data_list->next=(*md);
329     machine_data_list->name=hostname;
330     machine_data_list->network_data_list=NULL;
331     machine_data_list->diskio_data_list=NULL;
332     *md=machine_data_list;
333     num_hosts++;
334     }
335    
336     /* Now we want to pull out the data */
337    
338     cur = cur->xmlChildrenNode;
339     while(cur != NULL) {
340     ele=cur->xmlChildrenNode;
341     while(ele != NULL){
342    
343     /* CPU Stats */
344     if(!xmlStrcmp(cur->name, (const xmlChar *) "cpu")){
345     tmp=xmlNodeGetContent(ele);
346     if(!xmlStrcmp(ele->name, (const xmlChar *) "user")){
347     machine_data_list->cpu_user=atof(tmp);
348     }
349     if(!xmlStrcmp(ele->name, (const xmlChar *) "kernel")){
350     machine_data_list->cpu_kernel=atof(tmp);
351     }
352     if(!xmlStrcmp(ele->name, (const xmlChar *) "idle")){
353     machine_data_list->cpu_idle=atof(tmp);
354     }
355     if(!xmlStrcmp(ele->name, (const xmlChar *) "iowait")){
356     machine_data_list->cpu_iowait=atof(tmp);
357     }
358     if(!xmlStrcmp(ele->name, (const xmlChar *) "swap")){
359     machine_data_list->cpu_iowait=atof(tmp);
360     }
361    
362     if(tmp!=NULL) xmlFree(tmp);
363     }
364    
365     /* Memory Stats */
366     if(!xmlStrcmp(cur->name, (const xmlChar *) "memory")){
367     tmp=xmlNodeGetContent(ele);
368     if(!xmlStrcmp(ele->name, (const xmlChar *) "total")){
369     machine_data_list->memory_total=atoll(tmp);
370     }
371     if(!xmlStrcmp(ele->name, (const xmlChar *) "free")){
372     machine_data_list->memory_free=atoll(tmp);
373     }
374     if(!xmlStrcmp(ele->name, (const xmlChar *) "used")){
375     machine_data_list->memory_used=atoll(tmp);
376     }
377    
378     if(tmp!=NULL) xmlFree(tmp);
379     }
380    
381     /* Load Stats */
382     if(!xmlStrcmp(cur->name, (const xmlChar *) "load")){
383     tmp=xmlNodeGetContent(ele);
384     if(!xmlStrcmp(ele->name, (const xmlChar *) "load1")){
385     machine_data_list->load_1=atof(tmp);
386     }
387     if(!xmlStrcmp(ele->name, (const xmlChar *) "load5")){
388     machine_data_list->load_5=atof(tmp);
389     }
390     if(!xmlStrcmp(ele->name, (const xmlChar *) "load15")){
391     machine_data_list->load_15=atof(tmp);
392     }
393    
394     if(tmp!=NULL) xmlFree(tmp);
395     }
396    
397     /* swap stats */
398     if(!xmlStrcmp(cur->name, (const xmlChar *) "swap")){
399     tmp=xmlNodeGetContent(ele);
400     if(!xmlStrcmp(ele->name, (const xmlChar *) "total")){
401     machine_data_list->swap_total=atoll(tmp);
402     }
403     if(!xmlStrcmp(ele->name, (const xmlChar *) "free")){
404     machine_data_list->swap_free=atoll(tmp);
405     }
406     if(!xmlStrcmp(ele->name, (const xmlChar *) "used")){
407     machine_data_list->swap_used=atoll(tmp);
408     }
409    
410     if(tmp!=NULL) xmlFree(tmp);
411     }
412    
413     /* Process stat */
414     if(!xmlStrcmp(cur->name, (const xmlChar *) "processes")){
415     tmp=xmlNodeGetContent(ele);
416     if(!xmlStrcmp(ele->name, (const xmlChar *) "sleeping")){
417     machine_data_list->processes_sleeping=atoi(tmp);
418     }
419     if(!xmlStrcmp(ele->name, (const xmlChar *) "cpu")){
420     machine_data_list->processes_cpu=atoi(tmp);
421     }
422     if(!xmlStrcmp(ele->name, (const xmlChar *) "zombie")){
423     machine_data_list->processes_zombie=atoi(tmp);
424     }
425     if(!xmlStrcmp(ele->name, (const xmlChar *) "total")){
426     machine_data_list->processes_total=atoi(tmp);
427     }
428    
429     if(tmp!=NULL) xmlFree(tmp);
430     }
431    
432     /* paging stats */
433     if(!xmlStrcmp(cur->name, (const xmlChar *) "pages")){
434     tmp=xmlNodeGetContent(ele);
435     if(!xmlStrcmp(ele->name, (const xmlChar *) "pageins")){
436     machine_data_list->pages_in=atoi(tmp);
437     }
438     if(!xmlStrcmp(ele->name, (const xmlChar *) "pageouts")){
439     machine_data_list->pages_out=atoi(tmp);
440     }
441    
442     if(tmp!=NULL) xmlFree(tmp);
443     }
444    
445     /* OS stats */
446     if(!xmlStrcmp(cur->name, (const xmlChar *) "os")){
447     tmp=xmlNodeGetContent(ele);
448     if(!xmlStrcmp(ele->name, (const xmlChar *) "sysname")){
449     strlcpy(machine_data_list->sysname, tmp, MAXHOSTNAMESIZE+1);
450     }
451     if(tmp!=NULL) xmlFree(tmp);
452     }
453    
454     /* Network stats */
455     /* Needs to connect current stat to a previous one. Or create it if new */
456     /* Get name.. Walk list. If match, copy rx/tx values. Else malloc, add to list */
457     if(!xmlStrcmp(cur->name, (const xmlChar *) "net")){
458    
459     list=ele->properties;
460     if(list==NULL) continue;
461     network_data_list=malloc(sizeof(network_data_list_t));
462     if(network_data_list==NULL) return -1;
463     while(list!=NULL){
464     tmp=xmlNodeGetContent(list->children);
465     if(!xmlStrcmp(list->name, (const xmlChar *) "name")){
466     network_data_list->name=strdup(tmp);
467     }
468     if(!xmlStrcmp(list->name, (const xmlChar *) "rx")){
469     network_data_list->rx=atoll(tmp);
470     }
471     if(!xmlStrcmp(list->name, (const xmlChar *) "tx")){
472     network_data_list->tx=atoll(tmp);
473     }
474    
475     xmlFree(tmp);
476     list=list->next;
477     }
478     if(network_data_list->name==NULL) continue;
479     found_host=0;
480     ndl_ptr=machine_data_list->network_data_list;
481     while(ndl_ptr!=NULL){
482     if(!strcmp(ndl_ptr->name, network_data_list->name)){
483     found_host=1;
484     break;
485     }
486     ndl_ptr=ndl_ptr->next;
487     }
488     if(found_host){
489     ndl_ptr->rx=network_data_list->rx;
490     ndl_ptr->tx=network_data_list->tx;
491     free(network_data_list->name);
492     free(network_data_list);
493     }else{
494     network_data_list->next=machine_data_list->network_data_list;
495     machine_data_list->network_data_list=network_data_list;
496     }
497     }
498    
499     /* Disk IO stats */
500     if(!xmlStrcmp(cur->name, (const xmlChar *) "diskio")){
501    
502     list=ele->properties;
503     if(list==NULL) continue;
504     diskio_data_list=malloc(sizeof(diskio_data_list_t));
505     if(diskio_data_list==NULL) return -1;
506     while(list!=NULL){
507     tmp=xmlNodeGetContent(list->children);
508     if(!xmlStrcmp(list->name, (const xmlChar *) "name")){
509     diskio_data_list->name=strdup(tmp);
510     }
511     if(!xmlStrcmp(list->name, (const xmlChar *) "rbytes")){
512     diskio_data_list->read=atoll(tmp);
513     }
514     if(!xmlStrcmp(list->name, (const xmlChar *) "wbytes")){
515     diskio_data_list->write=atoll(tmp);
516     }
517    
518     xmlFree(tmp);
519     list=list->next;
520     }
521     if(diskio_data_list->name==NULL) continue;
522     found_host=0;
523     didl_ptr=machine_data_list->diskio_data_list;
524     while(didl_ptr!=NULL){
525     if(!strcmp(didl_ptr->name, diskio_data_list->name)){
526     found_host=1;
527     break;
528     }
529     didl_ptr=didl_ptr->next;
530     }
531     if(found_host){
532     didl_ptr->read=diskio_data_list->read;
533     didl_ptr->write=diskio_data_list->write;
534     free(diskio_data_list->name);
535     free(diskio_data_list);
536     }else{
537     diskio_data_list->next=machine_data_list->diskio_data_list;
538     machine_data_list->diskio_data_list=diskio_data_list;
539     }
540     }
541    
542    
543    
544     ele=ele->next;
545     }
546     cur=cur->next;
547     }
548    
549     /* Append data we want thats not stored in the server */
550     machine_data_list->cpu_used=100.00-machine_data_list->cpu_idle;
551     machine_data_list->memory_used_pecent=((double)machine_data_list->memory_used / (double)machine_data_list->memory_total) * 100.00;
552     machine_data_list->swap_used_pecent=((double)machine_data_list->swap_used / (double)machine_data_list->swap_total) * 100.00;
553    
554     ndl_ptr=machine_data_list->network_data_list;
555     machine_data_list->network_io_total_tx=0;
556     machine_data_list->network_io_total_rx=0;
557     while(ndl_ptr!=NULL){
558     machine_data_list->network_io_total_tx+=ndl_ptr->tx;
559     machine_data_list->network_io_total_rx+=ndl_ptr->rx;
560     ndl_ptr=ndl_ptr->next;
561     }
562    
563     didl_ptr=machine_data_list->diskio_data_list;
564     machine_data_list->disk_io_total_read=0;
565     machine_data_list->disk_io_total_write=0;
566     while(didl_ptr!=NULL){
567     machine_data_list->disk_io_total_read+=didl_ptr->read;
568     machine_data_list->disk_io_total_write+=didl_ptr->write;
569     didl_ptr=didl_ptr->next;
570     }
571    
572     xmlFreeDoc(doc);
573    
574     return num_hosts;
575    
576    
577     }
578    
579 pajs 1.2 void display(machine_data_list_t *machine_data_list, display_config_t *display_config, int num_lines, int *title){
580 pajs 1.1 int line_num=4;
581 pajs 1.2 int x=1;
582    
583     if(*title){
584 pajs 1.4 // printf("\033[2J");
585 pajs 1.2 // printf("\033[1;1HHostname CPU Load Page Page Mem Swap Net Net Disk Disk");
586 pajs 1.4 // printw("\033[2;1H used%% (1m) ins outs used used rx tx read write");
587     move(1,1);
588     printw("%-11s", "Hostname");
589 pajs 1.2 x=x+11+1;
590     if(display_config->cpu_used){
591 pajs 1.4 move(1,x);
592     printw("%5s", "CPU");
593     move(2,x);
594     printw("%5s", "used%");
595 pajs 1.2 x+=6;
596     }
597     if(display_config->load_1){
598 pajs 1.4 move(1,x);
599     printw("%5s", "Load");
600     move(2,x);
601     printw("%5s", "(1m)");
602 pajs 1.2 x+=6;
603     }
604     if(display_config->pages_in){
605 pajs 1.4 move(1,x);
606     printw("%5s", "Page");
607     move(2,x);
608     printw("%5s", "ins");
609 pajs 1.2 x+=6;
610     }
611     if(display_config->pages_out){
612 pajs 1.4 move(1,x);
613     printw("%5s", "Page");
614     move(2,x);
615     printw("%5s", "outs");
616 pajs 1.2 x+=6;
617     }
618     if(display_config->memory_used_pecent){
619 pajs 1.4 move(1,x);
620     printw("%5s", "Mem");
621     move(2,x);
622     printw("%5s", "used");
623 pajs 1.2 x+=6;
624     }
625     if(display_config->swap_used_pecent){
626 pajs 1.4 move(1,x);
627     printw("%5s", "Swap");
628     move(2,x);
629     printw("%5s", "used");
630 pajs 1.2 x+=6;
631     }
632     if(display_config->network_io_total_rx){
633 pajs 1.4 move(1,x);
634     printw("%8s", "Net");
635     move(2,x);
636     printw("%8s", "rx");
637 pajs 1.2 x+=9;
638     }
639     if(display_config->network_io_total_tx){
640 pajs 1.4 move(1,x);
641     printw("%8s", "Net");
642     move(2,x);
643     printw("%8s", "tx");
644 pajs 1.2 x+=9;
645     }
646     if(display_config->disk_io_total_read){
647 pajs 1.4 move(1,x);
648     printw("%9s", "Disk");
649     move(2,x);
650     printw("%9s", "read");
651 pajs 1.2 x+=10;
652     }
653     if(display_config->disk_io_total_read){
654 pajs 1.4 move(1,x);
655     printw("%9s", "Disk");
656     move(2,x);
657     printw("%9s", "write");
658 pajs 1.2 x+=10;
659     }
660    
661     *title=0;
662     }
663 pajs 1.1
664     for(;num_lines;num_lines--){
665     if(machine_data_list==NULL) break;
666 pajs 1.4 move(line_num++, 1);
667     printw("%-11s", machine_data_list->sysname);
668 pajs 1.2
669 pajs 1.4 if(display_config->cpu_used) printw(" %5.1f", machine_data_list->cpu_used);
670     if(display_config->load_1) printw(" %5.1f", machine_data_list->load_1);
671     if(display_config->pages_in) printw(" %5d", machine_data_list->pages_in);
672     if(display_config->pages_out) printw(" %5d", machine_data_list->pages_out);
673     if(display_config->memory_used_pecent) printw(" %5.1f", machine_data_list->memory_used_pecent);
674     if(display_config->swap_used_pecent) printw(" %5.1f", machine_data_list->swap_used_pecent);
675     if(display_config->network_io_total_rx) printw(" %8lld", machine_data_list->network_io_total_rx);
676     if(display_config->network_io_total_tx) printw(" %8lld", machine_data_list->network_io_total_tx);
677     if(display_config->disk_io_total_read) printw(" %9lld", machine_data_list->disk_io_total_read);
678     if(display_config->disk_io_total_write) printw(" %9lld", machine_data_list->disk_io_total_write);
679 pajs 1.2
680 pajs 1.1 machine_data_list=machine_data_list->next;
681     }
682    
683 pajs 1.2
684 pajs 1.4 refresh();
685 pajs 1.1
686     }
687    
688     int main(int argc, char **argv){
689 pajs 1.4 WINDOW *window;
690    
691 pajs 1.1 FILE *control;
692     FILE *data;
693    
694     char *machine_list=NULL;
695     char *response=NULL;
696    
697     char *servername;
698     int server_control_port;
699     int server_data_port;
700    
701     machine_data_list_t *machine_data_list=NULL;
702    
703     int num_hosts;
704     int max_display=0;
705 pajs 1.2 int title;
706 pajs 1.1
707     int cmdopt;
708     extern int optind;
709     extern char *optarg;
710    
711     display_config_t display_config;
712 pajs 1.4 char ch;
713    
714     sortby_ptr=NULL;
715 pajs 1.1
716     /* What to display defaults */
717     display_config.cpu_user=0;
718     display_config.cpu_idle=0;
719     display_config.cpu_iowait=0;
720     display_config.cpu_kernel=0;
721     display_config.cpu_swap=0;
722     display_config.cpu_used=1;
723    
724     display_config.memory_total=0;
725     display_config.memory_free=0;
726     display_config.memory_used=0;
727     display_config.memory_used_pecent=1;
728    
729     display_config.swap_total=0;
730     display_config.swap_free=0;
731     display_config.swap_used=0;
732     display_config.swap_used_pecent=1;
733    
734     display_config.load_1=1;
735     display_config.load_5=0;
736     display_config.load_15=0;
737    
738     display_config.pages_in=1;
739     display_config.pages_out=1;
740    
741     display_config.processes_total=0;
742     display_config.processes_sleeping=0;
743     display_config.processes_cpu=0;
744     display_config.processes_zombie=0;
745     display_config.processes_stopped=0;
746    
747 pajs 1.2 display_config.network_io_total_tx=1;
748     display_config.network_io_total_rx=1;
749 pajs 1.1 display_config.network_all_stats=1;
750    
751 pajs 1.4 display_config.disk_io_total_write=0;
752     display_config.disk_io_total_read=0;
753 pajs 1.2 display_config.disk_io_all_stats=0;
754 pajs 1.1
755     display_config.disk_total_used=0;
756     display_config.disk_all_stats=0;
757    
758 pajs 1.2 while((cmdopt=getopt(argc, argv, "d:s:")) != -1){
759 pajs 1.1 switch(cmdopt){
760     case 'd':
761     max_display=atoi(optarg);
762     break;
763 pajs 1.2 case 's':
764     if(!strcmp(optarg, "cpu")){
765     sortby_ptr=cmp_cpu_used;
766     }
767     if(!strcmp(optarg, "load")){
768     sortby_ptr=cmp_load_1;
769     }
770     if(!strcmp(optarg, "mem")){
771     sortby_ptr=cmp_memory_used_pecent;
772     }
773     if(sortby_ptr==NULL){
774     errf("Invalid sort type");
775     exit(1);
776     }
777     break;
778 pajs 1.1 }
779     }
780    
781 pajs 1.2 if(sortby_ptr==NULL) sortby_ptr=cmp_cpu_used;
782 pajs 1.1
783     if(argc<(optind+2)){
784     printf("Usage is %s <-d lines> hostname port <machine list>\n", argv[0]);
785     exit(1);
786     }
787    
788     servername=argv[optind];
789     server_control_port=atoi(argv[optind+1]);
790    
791     control=create_tcp_connection(servername, server_control_port);
792     if(control==NULL){
793     errf("Failed to connect (%m)");
794     }
795    
796     if(argc==4){
797     /* We've been passed a machine list */
798     /* list currently needs to be ; seperated */
799     machine_list=strdup(argv[3]);
800     }
801    
802     if((tcp_comm(control, NULL, &response, "PROTOCOL 1.1"))!=0){
803     errf("Incorrect version number (%s)", response);
804     exit(1);
805     }
806    
807     if((tcp_comm(control, "stattop", &response, "OK"))!=0){
808     errf("Unexpected response %s", response);
809     exit(1);
810     }
811    
812     if(machine_list!=NULL){
813     if((tcp_comm(control, "SETHOSTLIST", &response, "OK"))!=0){
814     errf("Unexpected response %s", response);
815     exit(1);
816     }
817     if((tcp_comm(control, machine_list, &response, "OK"))!=0){
818     errf("Unexpected response %s", response);
819     exit(1);
820     }
821     }
822    
823     if((tcp_comm(control, "STARTDATA", &response, NULL))!=0){
824     errf("Unexpected response %s", response);
825     exit(1);
826     }
827    
828     server_data_port=atoi(response);
829     if(server_data_port==0){
830     errf("Unexpected response %s", response);
831     exit(1);
832     }
833    
834     data=create_tcp_connection(servername, server_data_port);
835     if(data==NULL){
836     errf("Failed to connect to host %s on port %d (%m)",servername, server_data_port);
837     }
838    
839 pajs 1.2 /*
840 pajs 1.1 printf("\033[2J");
841     printf("\033[1;1HHostname CPU Load Page Page Mem Swap Net Net Disk Disk");
842     printf("\033[2;1H used%% (1m) ins outs used used rx tx read write");
843 pajs 1.2 */
844 pajs 1.4
845     initscr();
846     nonl();
847     cbreak();
848     echo();
849     window=newwin(0, 0, 0, 0);
850    
851 pajs 1.1 for(;;){
852     response=fpgetline(data);
853     if (response==NULL){
854     errf("Failed to read data (%m)");
855     exit(1);
856     }
857    
858 pajs 1.4 /* ch=getc(stdin);
859    
860     if(ch=='q'){
861     endwin();
862     exit(0);
863     }
864     */
865 pajs 1.1 num_hosts=parse_xml(response, &machine_data_list);
866     if(num_hosts==-1) continue;
867 pajs 1.2 machine_data_list=sort_machine_stats(machine_data_list, num_hosts, sortby_ptr);
868 pajs 1.1 if(max_display==0){
869 pajs 1.2 display(machine_data_list, &display_config, num_hosts, &title);
870 pajs 1.1 }else{
871 pajs 1.2 display(machine_data_list, &display_config, max_display, &title);
872 pajs 1.1 }
873    
874     }
875     exit(0);
876     }