ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/idar/idar.c
Revision: 1.22
Committed: Wed Jun 2 16:06:48 2004 UTC (20 years, 6 months ago) by ats
Content type: text/plain
Branch: MAIN
Changes since 1.21: +2 -0 lines
Log Message:
Fix memory leak.

File Contents

# User Rev Content
1 tdb 1.3 /*
2     * i-scream central monitoring system
3 tdb 1.21 * http://www.i-scream.org
4 tdb 1.3 * 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 tdb 1.20 #include <sys/ioctl.h>
30 pajs 1.1 #include <unistd.h>
31     #include <stdlib.h>
32     #include <ukcprog.h>
33 pajs 1.11 #include <netinet/in.h>
34 pajs 1.10 #include <netdb.h>
35 pajs 1.13 #include <sys/termios.h>
36 pajs 1.15 #include <signal.h>
37     #include <errno.h>
38 pajs 1.1
39     #include <libxml/xmlmemory.h>
40     #include <libxml/parser.h>
41     #include "genmergesort.h"
42 tdb 1.6
43     #ifdef HAVE_NCURSES_H
44     #include <ncurses.h>
45     #else
46 pajs 1.4 #include <curses.h>
47 tdb 1.6 #endif
48 pajs 1.1
49     struct host_line_t{
50     char *hostname;
51     int line;
52    
53     struct host_line_t *next;
54     };
55     typedef struct host_line_t host_line_list_t;
56    
57     struct diskio_data_t{
58     char *name;
59    
60     long long read;
61     long long write;
62    
63     struct diskio_data_t *next;
64     };
65     typedef struct diskio_data_t diskio_data_list_t;
66    
67     struct network_data_t{
68     char *name;
69    
70     long long rx;
71     long long tx;
72    
73     struct network_data_t *next;
74     };
75     typedef struct network_data_t network_data_list_t;
76    
77     /*
78     struct disk_data_t{
79     char *name;
80     char *mount_pnt;
81    
82     long long total_space;
83     long long total_used;
84     long long total_avail;
85     // Other data we are less intrested in are not stored
86    
87     struct disk_data_t *next;
88     };
89     typedef struct disk_data_t disk_data_list_t;
90     */
91     #define MAXHOSTNAMESIZE 10
92     struct machine_data_t{
93    
94     char *name;
95    
96     char sysname[MAXHOSTNAMESIZE+1];
97    
98     double cpu_user;
99     double cpu_idle;
100     double cpu_iowait;
101     double cpu_kernel;
102     double cpu_swap;
103     double cpu_used; /* 100 - idle */
104    
105     long long memory_total;
106     long long memory_free;
107     long long memory_used;
108     double memory_used_pecent;
109    
110     long long swap_total;
111     long long swap_free;
112     long long swap_used;
113     double swap_used_pecent;
114    
115     int pages_in;
116     int pages_out;
117    
118     double load_1;
119     double load_5;
120     double load_15;
121    
122     int processes_total;
123     int processes_sleeping;
124     int processes_cpu;
125     int processes_zombie;
126     int processes_stopped;
127    
128     network_data_list_t *network_data_list;
129     long long network_io_total_tx;
130     long long network_io_total_rx;
131 pajs 1.7 long long network_io_total;
132 pajs 1.1
133     diskio_data_list_t *diskio_data_list;
134     long long disk_io_total_write;
135     long long disk_io_total_read;
136 pajs 1.7 long long disk_io_total;
137 pajs 1.1
138     /* Maybe in the future */
139     /*
140     disk_data_list_t disk_data_list;
141     double disk_total_used;
142     */
143    
144     struct machine_data_t *next;
145     };
146    
147     typedef struct machine_data_t machine_data_list_t;
148    
149 pajs 1.7 #define SORTBYMAXNAME 128
150 pajs 1.1 typedef struct{
151 pajs 1.14 int maxx;
152     int maxy;
153    
154     char units;
155    
156 pajs 1.1 int cpu_user;
157     int cpu_idle;
158     int cpu_iowait;
159     int cpu_kernel;
160     int cpu_swap;
161     int cpu_used;
162    
163     int memory_total;
164     int memory_free;
165     int memory_used;
166     int memory_used_pecent;
167    
168     int swap_total;
169     int swap_free;
170     int swap_used;
171     int swap_used_pecent;
172    
173     int load_1;
174     int load_5;
175     int load_15;
176    
177     int pages_in;
178     int pages_out;
179    
180 pajs 1.15 int processes;
181 pajs 1.1
182     int network_io_total_tx;
183     int network_io_total_rx;
184     int network_all_stats;
185    
186     int disk_io_total_write;
187     int disk_io_total_read;
188     int disk_io_all_stats;
189    
190     int disk_total_used;
191     int disk_all_stats;
192 pajs 1.7
193     char sortby[SORTBYMAXNAME];
194 pajs 1.1 }display_config_t;
195    
196     GENERIC_MERGE_SORT(static, sort_machine_stats, machine_data_list_t, next)
197    
198 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));}
199    
200    
201     int (*sortby_ptr)(machine_data_list_t *a, machine_data_list_t *b);
202    
203     MKCMP(cpu_used)
204     MKCMP(load_1)
205 pajs 1.7 MKCMP(network_io_total)
206 pajs 1.2 MKCMP(network_io_total_tx)
207     MKCMP(network_io_total_rx)
208 pajs 1.7 MKCMP(disk_io_total)
209 pajs 1.2 MKCMP(disk_io_total_write)
210     MKCMP(disk_io_total_read)
211     MKCMP(memory_used_pecent)
212     MKCMP(swap_used_pecent)
213    
214 pajs 1.7 #define CPU_USED "CPU used"
215     #define LOAD "Load (1)"
216     #define NETIORX "total Network RX for all interfaces"
217     #define NETIOTX "total Network TX for all interfaces"
218     #define NETIO "total Network IO for all interfaces (rx+tx)"
219     #define MEM "Memory usage"
220     #define SWAP "Swap usage"
221     #define DISKIOR "DiskIO reads"
222     #define DISKIOW "DiskIO writes"
223     #define DISKIO "Total DiskIO (reads+writes)"
224    
225 pajs 1.15 int sig_winch=0;
226 pajs 1.9
227     #ifndef HAVE_ATOLL
228     long long int atoll (const char *nptr){
229     return strtoll (nptr, (char **) NULL, 10);
230     }
231     #endif
232    
233     #ifndef HAVE_STRLCPY
234     /*
235     * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
236     * All rights reserved.
237     *
238     * Redistribution and use in source and binary forms, with or without
239     * modification, are permitted provided that the following conditions
240     * are met:
241     * 1. Redistributions of source code must retain the above copyright
242     * notice, this list of conditions and the following disclaimer.
243     * 2. Redistributions in binary form must reproduce the above copyright
244     * notice, this list of conditions and the following disclaimer in the
245     * documentation and/or other materials provided with the distribution.
246     * 3. The name of the author may not be used to endorse or promote products
247     * derived from this software without specific prior written permission.
248     *
249     * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
250     * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
251     * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
252     * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
253     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
254     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
255     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
256     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
257     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
258     * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
259     */
260    
261     /*
262     * Copy src to string dst of size siz. At most siz-1 characters
263     * will be copied. Always NUL terminates (unless siz == 0).
264     * Returns strlen(src); if retval >= siz, truncation occurred.
265     */
266     size_t
267     strlcpy(dst, src, siz)
268     char *dst;
269     const char *src;
270     size_t siz;
271     {
272     register char *d = dst;
273     register const char *s = src;
274     register size_t n = siz;
275    
276     /* Copy as many bytes as will fit */
277     if (n != 0 && --n != 0) {
278     do {
279     if ((*d++ = *s++) == 0)
280     break;
281     } while (--n != 0);
282     }
283    
284     /* Not enough room in dst, add NUL and traverse rest of src */
285     if (n == 0) {
286     if (siz != 0)
287     *d = '\0'; /* NUL-terminate dst */
288     while (*s++)
289     ;
290     }
291    
292     return(s - src - 1); /* count does not include NUL */
293     }
294    
295     #endif
296    
297 pajs 1.1
298     FILE *create_tcp_connection(char *hostname, int port){
299     int sock;
300     struct sockaddr_in addr;
301     struct in_addr haddr;
302     FILE *f;
303    
304     if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))<0){
305     return NULL;
306     }
307    
308     if((get_host_addr(hostname, &haddr))!=0){
309     close(sock);
310     return NULL;
311     }
312    
313     memset(&addr, 0, sizeof(addr));
314     addr.sin_family = AF_INET;
315     memcpy(&addr.sin_addr, &haddr, sizeof(haddr));
316     addr.sin_port = htons(port);
317    
318     if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) !=0){
319     close(sock);
320     return NULL;
321     }
322    
323     if((f=fdopen(sock, "r+"))==NULL){
324     close(sock);
325     return NULL;
326     }
327    
328     return f;
329     }
330    
331     int tcp_comm(FILE *f, char *send, char **response, char *expected){
332    
333     if(send!=NULL){
334     fprintf(f, "%s\n", send);
335     }
336     fflush(f);
337     *response=fpgetline(f);
338     fseek(f, 0, SEEK_CUR);
339    
340     if( (*response==NULL) || (strcmp(*response, "ERROR")==0) ) return -1;
341    
342     if(expected==NULL) return 0;
343    
344     if((strcmp(expected, *response))==0) return 0;
345    
346     return -1;
347     }
348    
349     /* Takes a xml char * and a machine_data_list_t. This will parse
350     * the xml and put it into the correct entry of the machine_data
351     * linked list. This will return the number of entries in the linked
352     * list, or -1 on a error.
353     */
354     int parse_xml(char *xml, machine_data_list_t **md){
355     xmlDocPtr doc;
356     xmlNodePtr cur;
357     xmlNodePtr ele;
358     xmlAttr *list;
359    
360     static int num_hosts=0;
361    
362     machine_data_list_t *machine_data_list=*md;
363    
364     int found_host=0;
365    
366     char *hostname=NULL;
367     network_data_list_t *network_data_list=NULL;
368     network_data_list_t *ndl_ptr=NULL;
369     diskio_data_list_t *diskio_data_list=NULL;
370     diskio_data_list_t *didl_ptr=NULL;
371     char *tmp;
372    
373     doc=xmlParseDoc(xml);
374     if(doc==NULL) return -1;
375    
376     cur = xmlDocGetRootElement(doc);
377     if(cur==NULL){
378     xmlFreeDoc(doc);
379     return -1;
380     }
381    
382    
383     /* Get the hostname */
384     list=cur->properties;
385     while(list!=NULL){
386     if((xmlStrcmp(list->name, (const xmlChar *) "machine_name"))==0){
387     hostname = xmlNodeGetContent(list->children);
388     if(hostname==NULL){
389     return -1;
390     }
391     }
392     list=list->next;
393     }
394     if(hostname==NULL){
395     return -1;
396     }
397    
398     /* Get machine_data for host.. Or create if it doesn't have one */
399     while(machine_data_list!=NULL){
400     if((strncmp(machine_data_list->name, hostname, strlen(hostname)))==0){
401     found_host=1;
402     break;
403     }
404     machine_data_list=machine_data_list->next;
405     }
406    
407     if(!found_host){
408     /* We didn't find this host, but we should be at the end of the list */
409     machine_data_list=malloc(sizeof(machine_data_list_t));
410     if(machine_data_list==NULL) return -1;
411     machine_data_list->next=(*md);
412     machine_data_list->name=hostname;
413     machine_data_list->network_data_list=NULL;
414     machine_data_list->diskio_data_list=NULL;
415     *md=machine_data_list;
416     num_hosts++;
417 ats 1.22 } else {
418     xmlFree(hostname);
419 pajs 1.1 }
420    
421     /* Now we want to pull out the data */
422    
423     cur = cur->xmlChildrenNode;
424     while(cur != NULL) {
425     ele=cur->xmlChildrenNode;
426     while(ele != NULL){
427    
428     /* CPU Stats */
429     if(!xmlStrcmp(cur->name, (const xmlChar *) "cpu")){
430     tmp=xmlNodeGetContent(ele);
431     if(!xmlStrcmp(ele->name, (const xmlChar *) "user")){
432     machine_data_list->cpu_user=atof(tmp);
433     }
434     if(!xmlStrcmp(ele->name, (const xmlChar *) "kernel")){
435     machine_data_list->cpu_kernel=atof(tmp);
436     }
437     if(!xmlStrcmp(ele->name, (const xmlChar *) "idle")){
438     machine_data_list->cpu_idle=atof(tmp);
439     }
440     if(!xmlStrcmp(ele->name, (const xmlChar *) "iowait")){
441     machine_data_list->cpu_iowait=atof(tmp);
442     }
443     if(!xmlStrcmp(ele->name, (const xmlChar *) "swap")){
444     machine_data_list->cpu_iowait=atof(tmp);
445     }
446    
447     if(tmp!=NULL) xmlFree(tmp);
448     }
449    
450     /* Memory Stats */
451     if(!xmlStrcmp(cur->name, (const xmlChar *) "memory")){
452     tmp=xmlNodeGetContent(ele);
453     if(!xmlStrcmp(ele->name, (const xmlChar *) "total")){
454     machine_data_list->memory_total=atoll(tmp);
455     }
456     if(!xmlStrcmp(ele->name, (const xmlChar *) "free")){
457     machine_data_list->memory_free=atoll(tmp);
458     }
459     if(!xmlStrcmp(ele->name, (const xmlChar *) "used")){
460     machine_data_list->memory_used=atoll(tmp);
461     }
462    
463     if(tmp!=NULL) xmlFree(tmp);
464     }
465    
466     /* Load Stats */
467     if(!xmlStrcmp(cur->name, (const xmlChar *) "load")){
468     tmp=xmlNodeGetContent(ele);
469     if(!xmlStrcmp(ele->name, (const xmlChar *) "load1")){
470     machine_data_list->load_1=atof(tmp);
471     }
472     if(!xmlStrcmp(ele->name, (const xmlChar *) "load5")){
473     machine_data_list->load_5=atof(tmp);
474     }
475     if(!xmlStrcmp(ele->name, (const xmlChar *) "load15")){
476     machine_data_list->load_15=atof(tmp);
477     }
478    
479     if(tmp!=NULL) xmlFree(tmp);
480     }
481    
482     /* swap stats */
483     if(!xmlStrcmp(cur->name, (const xmlChar *) "swap")){
484     tmp=xmlNodeGetContent(ele);
485     if(!xmlStrcmp(ele->name, (const xmlChar *) "total")){
486     machine_data_list->swap_total=atoll(tmp);
487     }
488     if(!xmlStrcmp(ele->name, (const xmlChar *) "free")){
489     machine_data_list->swap_free=atoll(tmp);
490     }
491     if(!xmlStrcmp(ele->name, (const xmlChar *) "used")){
492     machine_data_list->swap_used=atoll(tmp);
493     }
494    
495     if(tmp!=NULL) xmlFree(tmp);
496     }
497    
498     /* Process stat */
499     if(!xmlStrcmp(cur->name, (const xmlChar *) "processes")){
500     tmp=xmlNodeGetContent(ele);
501     if(!xmlStrcmp(ele->name, (const xmlChar *) "sleeping")){
502     machine_data_list->processes_sleeping=atoi(tmp);
503     }
504     if(!xmlStrcmp(ele->name, (const xmlChar *) "cpu")){
505     machine_data_list->processes_cpu=atoi(tmp);
506     }
507     if(!xmlStrcmp(ele->name, (const xmlChar *) "zombie")){
508     machine_data_list->processes_zombie=atoi(tmp);
509     }
510     if(!xmlStrcmp(ele->name, (const xmlChar *) "total")){
511     machine_data_list->processes_total=atoi(tmp);
512     }
513    
514     if(tmp!=NULL) xmlFree(tmp);
515     }
516    
517     /* paging stats */
518     if(!xmlStrcmp(cur->name, (const xmlChar *) "pages")){
519     tmp=xmlNodeGetContent(ele);
520     if(!xmlStrcmp(ele->name, (const xmlChar *) "pageins")){
521     machine_data_list->pages_in=atoi(tmp);
522     }
523     if(!xmlStrcmp(ele->name, (const xmlChar *) "pageouts")){
524     machine_data_list->pages_out=atoi(tmp);
525     }
526    
527     if(tmp!=NULL) xmlFree(tmp);
528     }
529    
530     /* OS stats */
531     if(!xmlStrcmp(cur->name, (const xmlChar *) "os")){
532     tmp=xmlNodeGetContent(ele);
533     if(!xmlStrcmp(ele->name, (const xmlChar *) "sysname")){
534     strlcpy(machine_data_list->sysname, tmp, MAXHOSTNAMESIZE+1);
535     }
536     if(tmp!=NULL) xmlFree(tmp);
537     }
538    
539     /* Network stats */
540     /* Needs to connect current stat to a previous one. Or create it if new */
541     /* Get name.. Walk list. If match, copy rx/tx values. Else malloc, add to list */
542     if(!xmlStrcmp(cur->name, (const xmlChar *) "net")){
543    
544     list=ele->properties;
545     if(list==NULL) continue;
546     network_data_list=malloc(sizeof(network_data_list_t));
547     if(network_data_list==NULL) return -1;
548     while(list!=NULL){
549     tmp=xmlNodeGetContent(list->children);
550     if(!xmlStrcmp(list->name, (const xmlChar *) "name")){
551     network_data_list->name=strdup(tmp);
552     }
553     if(!xmlStrcmp(list->name, (const xmlChar *) "rx")){
554     network_data_list->rx=atoll(tmp);
555     }
556     if(!xmlStrcmp(list->name, (const xmlChar *) "tx")){
557     network_data_list->tx=atoll(tmp);
558     }
559    
560     xmlFree(tmp);
561     list=list->next;
562     }
563     if(network_data_list->name==NULL) continue;
564     found_host=0;
565     ndl_ptr=machine_data_list->network_data_list;
566     while(ndl_ptr!=NULL){
567     if(!strcmp(ndl_ptr->name, network_data_list->name)){
568     found_host=1;
569     break;
570     }
571     ndl_ptr=ndl_ptr->next;
572     }
573     if(found_host){
574     ndl_ptr->rx=network_data_list->rx;
575     ndl_ptr->tx=network_data_list->tx;
576     free(network_data_list->name);
577     free(network_data_list);
578     }else{
579     network_data_list->next=machine_data_list->network_data_list;
580     machine_data_list->network_data_list=network_data_list;
581     }
582     }
583    
584     /* Disk IO stats */
585     if(!xmlStrcmp(cur->name, (const xmlChar *) "diskio")){
586    
587     list=ele->properties;
588     if(list==NULL) continue;
589     diskio_data_list=malloc(sizeof(diskio_data_list_t));
590     if(diskio_data_list==NULL) return -1;
591     while(list!=NULL){
592     tmp=xmlNodeGetContent(list->children);
593     if(!xmlStrcmp(list->name, (const xmlChar *) "name")){
594     diskio_data_list->name=strdup(tmp);
595     }
596     if(!xmlStrcmp(list->name, (const xmlChar *) "rbytes")){
597     diskio_data_list->read=atoll(tmp);
598     }
599     if(!xmlStrcmp(list->name, (const xmlChar *) "wbytes")){
600     diskio_data_list->write=atoll(tmp);
601     }
602    
603     xmlFree(tmp);
604     list=list->next;
605     }
606     if(diskio_data_list->name==NULL) continue;
607     found_host=0;
608     didl_ptr=machine_data_list->diskio_data_list;
609     while(didl_ptr!=NULL){
610     if(!strcmp(didl_ptr->name, diskio_data_list->name)){
611     found_host=1;
612     break;
613     }
614     didl_ptr=didl_ptr->next;
615     }
616     if(found_host){
617     didl_ptr->read=diskio_data_list->read;
618     didl_ptr->write=diskio_data_list->write;
619     free(diskio_data_list->name);
620     free(diskio_data_list);
621     }else{
622     diskio_data_list->next=machine_data_list->diskio_data_list;
623     machine_data_list->diskio_data_list=diskio_data_list;
624     }
625     }
626    
627    
628    
629     ele=ele->next;
630     }
631     cur=cur->next;
632     }
633    
634     /* Append data we want thats not stored in the server */
635     machine_data_list->cpu_used=100.00-machine_data_list->cpu_idle;
636     machine_data_list->memory_used_pecent=((double)machine_data_list->memory_used / (double)machine_data_list->memory_total) * 100.00;
637     machine_data_list->swap_used_pecent=((double)machine_data_list->swap_used / (double)machine_data_list->swap_total) * 100.00;
638    
639     ndl_ptr=machine_data_list->network_data_list;
640     machine_data_list->network_io_total_tx=0;
641     machine_data_list->network_io_total_rx=0;
642     while(ndl_ptr!=NULL){
643     machine_data_list->network_io_total_tx+=ndl_ptr->tx;
644     machine_data_list->network_io_total_rx+=ndl_ptr->rx;
645     ndl_ptr=ndl_ptr->next;
646     }
647 pajs 1.7 machine_data_list->network_io_total=machine_data_list->network_io_total_rx+machine_data_list->network_io_total_tx;
648 pajs 1.1
649     didl_ptr=machine_data_list->diskio_data_list;
650     machine_data_list->disk_io_total_read=0;
651     machine_data_list->disk_io_total_write=0;
652     while(didl_ptr!=NULL){
653     machine_data_list->disk_io_total_read+=didl_ptr->read;
654     machine_data_list->disk_io_total_write+=didl_ptr->write;
655     didl_ptr=didl_ptr->next;
656     }
657 pajs 1.7 machine_data_list->disk_io_total=machine_data_list->disk_io_total_read+machine_data_list->disk_io_total_write;
658 pajs 1.1
659     xmlFreeDoc(doc);
660    
661     return num_hosts;
662    
663    
664     }
665    
666 pajs 1.14 void display(machine_data_list_t *machine_data_list, display_config_t *display_config, int *title){
667 pajs 1.1 int line_num=4;
668 pajs 1.7 int counter;
669 pajs 1.2 int x=1;
670    
671     if(*title){
672 pajs 1.8 clear();
673 pajs 1.14 move (display_config->maxy-3, 1);
674 pajs 1.7 printw("Sorting by %-64s", display_config->sortby);
675 pajs 1.14 move (display_config->maxy-2, 1);
676     if(display_config->units == 'b'){
677     printw("Units are measured in bytes/sec");
678     }
679     if(display_config->units == 'k'){
680     printw("Units are measured in kilobytes/sec");
681     }
682     if(display_config->units == 'm'){
683     printw("Units are measured in megabytes/sec");
684     }
685 pajs 1.7
686 pajs 1.4 move(1,1);
687     printw("%-11s", "Hostname");
688 pajs 1.2 x=x+11+1;
689 pajs 1.14 if(display_config->cpu_used && (display_config->maxx > x+6)){
690 pajs 1.4 move(1,x);
691     printw("%5s", "CPU");
692     move(2,x);
693     printw("%5s", "used%");
694 pajs 1.2 x+=6;
695     }
696 pajs 1.14 if(display_config->load_1 && (display_config->maxx > x+6)){
697 pajs 1.4 move(1,x);
698     printw("%5s", "Load");
699     move(2,x);
700     printw("%5s", "(1m)");
701 pajs 1.2 x+=6;
702     }
703 pajs 1.15
704 pajs 1.14 if(display_config->pages_in && (display_config->maxx > x+6)){
705 pajs 1.4 move(1,x);
706     printw("%5s", "Page");
707     move(2,x);
708     printw("%5s", "ins");
709 pajs 1.2 x+=6;
710     }
711 pajs 1.15
712 pajs 1.14 if(display_config->pages_out && (display_config->maxx > x+6)){
713 pajs 1.4 move(1,x);
714     printw("%5s", "Page");
715     move(2,x);
716     printw("%5s", "outs");
717 pajs 1.2 x+=6;
718     }
719 pajs 1.15
720 pajs 1.14 if(display_config->memory_used_pecent && (display_config->maxx > x+6)){
721 pajs 1.4 move(1,x);
722     printw("%5s", "Mem");
723     move(2,x);
724     printw("%5s", "used");
725 pajs 1.2 x+=6;
726     }
727 pajs 1.15
728 pajs 1.14 if(display_config->swap_used_pecent && (display_config->maxx > x+6)){
729 pajs 1.4 move(1,x);
730     printw("%5s", "Swap");
731     move(2,x);
732     printw("%5s", "used");
733 pajs 1.2 x+=6;
734     }
735 pajs 1.15
736 pajs 1.14 if(display_config->network_io_total_rx){
737     if(display_config->units=='b' && (display_config->maxx > x+9)){
738     move(1,x);
739     printw("%8s", "Net");
740     move(2,x);
741     printw("%8s", "rx");
742     x+=9;
743     }
744 pajs 1.15
745 pajs 1.14 if(display_config->units=='k' && (display_config->maxx > x+6)){
746     move(1,x);
747     printw("%5s", "Net");
748     move(2,x);
749     printw("%5s", "rx");
750     x+=6;
751     }
752 pajs 1.15
753     if(display_config->units=='m' && (display_config->maxx > x+6)){
754 pajs 1.14 move(1,x);
755 pajs 1.15 printw("%5s", "Net");
756 pajs 1.14 move(2,x);
757 pajs 1.15 printw("%5s", "rx");
758     x+=6;
759 pajs 1.14 }
760 pajs 1.15
761 pajs 1.2 }
762 pajs 1.15
763 pajs 1.2 if(display_config->network_io_total_tx){
764 pajs 1.14 if(display_config->units=='b' && (display_config->maxx > x+9)){
765     move(1,x);
766     printw("%8s", "Net");
767     move(2,x);
768     printw("%8s", "tx");
769     x+=9;
770     }
771 pajs 1.15
772 pajs 1.14 if(display_config->units=='k' && (display_config->maxx > x+6)){
773     move(1,x);
774     printw("%5s", "Net");
775     move(2,x);
776     printw("%5s", "tx");
777     x+=6;
778     }
779 pajs 1.15
780     if(display_config->units=='m' && (display_config->maxx > x+6)){
781 pajs 1.14 move(1,x);
782 pajs 1.15 printw("%5s", "Net");
783 pajs 1.14 move(2,x);
784 pajs 1.15 printw("%5s", "tx");
785     x+=6;
786 pajs 1.14 }
787 pajs 1.15
788 pajs 1.2 }
789 pajs 1.14
790 pajs 1.2 if(display_config->disk_io_total_read){
791 pajs 1.14 if(display_config->units=='b' && (display_config->maxx > x+10)){
792     move(1,x);
793     printw("%9s", "Disk");
794     move(2,x);
795     printw("%9s", "read");
796     x+=10;
797     }
798 pajs 1.15
799 pajs 1.14 if(display_config->units=='k' && (display_config->maxx > x+7)){
800     move(1,x);
801     printw("%6s", "Disk");
802     move(2,x);
803     printw("%6s", "read");
804     x+=7;
805     }
806 pajs 1.15
807     if(display_config->units=='m' && (display_config->maxx > x+7)){
808 pajs 1.14 move(1,x);
809 pajs 1.15 printw("%6s", "Disk");
810 pajs 1.14 move(2,x);
811 pajs 1.15 printw("%6s", "read");
812     x+=7;
813 pajs 1.14 }
814 pajs 1.15
815 pajs 1.2 }
816 pajs 1.14
817 pajs 1.2 if(display_config->disk_io_total_read){
818 pajs 1.14 if(display_config->units=='b' && (display_config->maxx > x+10)){
819     move(1,x);
820     printw("%9s", "Disk");
821     move(2,x);
822     printw("%9s", "write");
823     x+=10;
824     }
825 pajs 1.15
826 pajs 1.14 if(display_config->units=='k' && (display_config->maxx > x+7)){
827     move(1,x);
828     printw("%6s", "Disk");
829     move(2,x);
830     printw("%6s", "write");
831     x+=7;
832     }
833 pajs 1.15
834     if(display_config->units=='m' && (display_config->maxx > x+7)){
835 pajs 1.14 move(1,x);
836 pajs 1.15 printw("%6s", "Disk");
837 pajs 1.14 move(2,x);
838 pajs 1.15 printw("%6s", "write");
839     x+=7;
840 pajs 1.14 }
841 pajs 1.15
842 pajs 1.2 }
843 pajs 1.15
844     if(display_config->processes && (display_config->maxx > x+25)){
845     move(1,x);
846     printw("%-24s", " Number of Process");
847     move(2,x);
848     printw("%-24s", " Run Slep Zomb Stop Tot");
849     x+=25;
850     }
851    
852 pajs 1.2 *title=0;
853     }
854 pajs 1.1
855 pajs 1.7 /* Counter starts at 8, for padding (eg, headers, borders etc) */
856 pajs 1.14 for(counter=8;counter<display_config->maxy;counter++){
857 pajs 1.1 if(machine_data_list==NULL) break;
858 pajs 1.4 move(line_num++, 1);
859     printw("%-11s", machine_data_list->sysname);
860 pajs 1.14 x=13;
861 pajs 1.2
862 pajs 1.14 if(display_config->cpu_used && (display_config->maxx > x+6)){
863     printw(" %5.1f", machine_data_list->cpu_used);
864     x+=6;
865     }
866     if(display_config->load_1 && (display_config->maxx > x+6)){
867     printw(" %5.1f", machine_data_list->load_1);
868     x+=6;
869     }
870     if(display_config->pages_in && (display_config->maxx > x+6)){
871     printw(" %5d", machine_data_list->pages_in);
872     x+=6;
873     }
874     if(display_config->pages_out && (display_config->maxx > x+6)){
875     printw(" %5d", machine_data_list->pages_out);
876     x+=6;
877     }
878     if(display_config->memory_used_pecent && (display_config->maxx > x+6)){
879     printw(" %5.1f", machine_data_list->memory_used_pecent);
880     x+=6;
881     }
882     if(display_config->swap_used_pecent && (display_config->maxx > x+6)){
883     printw(" %5.1f", machine_data_list->swap_used_pecent);
884     x+=6;
885     }
886    
887     if(display_config->network_io_total_rx){
888     if(display_config->units=='b' && (display_config->maxx > x+9)){
889     printw(" %8lld", machine_data_list->network_io_total_rx);
890     x+=9;
891     }
892     if(display_config->units=='k' && (display_config->maxx > x+6)){
893     printw(" %5lld", machine_data_list->network_io_total_rx/1024);
894     x+=6;
895     }
896 pajs 1.15 if(display_config->units=='m' && (display_config->maxx > x+6)){
897     printw(" %5.2f", (double)(machine_data_list->network_io_total_rx/(1024.00*1024.00)));
898     x+=6;
899 pajs 1.14 }
900     }
901    
902     if(display_config->network_io_total_tx){
903     if(display_config->units=='b' && (display_config->maxx > x+9)){
904     printw(" %8lld", machine_data_list->network_io_total_tx);
905     x+=9;
906     }
907     if(display_config->units=='k' && (display_config->maxx > x+6)){
908     printw(" %5lld", machine_data_list->network_io_total_tx/1024);
909     x+=6;
910     }
911 pajs 1.15 if(display_config->units=='m' && (display_config->maxx > x+6)){
912     printw(" %5.2f", (double)(machine_data_list->network_io_total_tx/(1024.00*1024.00)));
913     x+=6;
914 pajs 1.14 }
915     }
916    
917     if(display_config->disk_io_total_read){
918     if(display_config->units=='b' && (display_config->maxx > x+10)){
919     printw(" %9lld", machine_data_list->disk_io_total_read);
920     x+=10;
921     }
922     if(display_config->units=='k' && (display_config->maxx > x+7)){
923     printw(" %6lld", machine_data_list->disk_io_total_read/1024);
924     x+=7;
925     }
926 pajs 1.15 if(display_config->units=='m' && (display_config->maxx > x+7)){
927     printw(" %6.2f", (double)(machine_data_list->disk_io_total_read/(1024.00*1024.00)));
928     x+=7;
929 pajs 1.14 }
930     }
931    
932     if(display_config->disk_io_total_write){
933     if(display_config->units=='b' && (display_config->maxx > x+10)){
934     printw(" %9lld", machine_data_list->disk_io_total_write);
935     x+=10;
936     }
937     if(display_config->units=='k' && (display_config->maxx > x+7)){
938     printw(" %6lld", machine_data_list->disk_io_total_write/1024);
939     x+=7;
940     }
941 pajs 1.15 if(display_config->units=='m' && (display_config->maxx > x+7)){
942     printw(" %6.2f", (double)(machine_data_list->disk_io_total_write/(1024.00*1024.00)));
943     x+=7;
944 pajs 1.14 }
945     }
946 pajs 1.15 if(display_config->processes && display_config->maxx > x+25){
947     printw(" %4d %4d %4d %4d %4d", machine_data_list->processes_cpu, \
948     machine_data_list->processes_sleeping, \
949     machine_data_list->processes_zombie, \
950     machine_data_list->processes_stopped, \
951     machine_data_list->processes_total);
952     x+=25;
953     }
954 pajs 1.2
955 pajs 1.1 machine_data_list=machine_data_list->next;
956     }
957    
958 pajs 1.2
959 pajs 1.4 refresh();
960 pajs 1.1
961     }
962    
963 pajs 1.15 void sig_winch_handler(int sig){
964    
965     sig_winch=1;
966     signal(SIGWINCH, sig_winch_handler);
967     }
968    
969 tdb 1.17 void usage() {
970     printf("Usage: idar [-o order] [-s server] [-p port] [-l list] [-h]\n\n");
971     printf(" -o Sets the initial sort order. Accepted arguments are one of:\n");
972     printf(" cpu load mem swap net disk\n");
973     printf(" -s Specifies the i-scream server to connect to.\n");
974     printf(" default: %s\n", DEF_SERVER_NAME);
975     printf(" -p Specifies the i-scream server port.\n");
976     printf(" default: %d\n", DEF_SERVER_PORT);
977 tdb 1.18 printf(" -l Sets the list of hosts to monitor in a semi-colon separated list.\n");
978 tdb 1.17 printf(" -h Displays this help information.\n");
979     printf("\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
980     exit(1);
981     }
982    
983 pajs 1.1 int main(int argc, char **argv){
984 pajs 1.4 WINDOW *window;
985 pajs 1.5 fd_set infds;
986 pajs 1.13 struct winsize size;
987 pajs 1.4
988 pajs 1.1 FILE *control;
989     FILE *data;
990    
991     char *machine_list=NULL;
992     char *response=NULL;
993    
994 tdb 1.17 char *server_name;
995 pajs 1.1 int server_control_port;
996     int server_data_port;
997    
998     machine_data_list_t *machine_data_list=NULL;
999    
1000     int num_hosts;
1001 pajs 1.7 int title=1;
1002 pajs 1.1
1003     int cmdopt;
1004     extern int optind;
1005     extern char *optarg;
1006 pajs 1.15
1007     extern int errno;
1008 pajs 1.1
1009     display_config_t display_config;
1010 pajs 1.4 char ch;
1011    
1012 pajs 1.5 int data_fileno, stdin_fileno, biggest_fileno;
1013    
1014 pajs 1.4 sortby_ptr=NULL;
1015 pajs 1.1
1016     /* What to display defaults */
1017 pajs 1.14 display_config.units='b';
1018    
1019 pajs 1.1 display_config.cpu_user=0;
1020     display_config.cpu_idle=0;
1021     display_config.cpu_iowait=0;
1022     display_config.cpu_kernel=0;
1023     display_config.cpu_swap=0;
1024     display_config.cpu_used=1;
1025    
1026     display_config.memory_total=0;
1027     display_config.memory_free=0;
1028     display_config.memory_used=0;
1029     display_config.memory_used_pecent=1;
1030    
1031     display_config.swap_total=0;
1032     display_config.swap_free=0;
1033     display_config.swap_used=0;
1034     display_config.swap_used_pecent=1;
1035    
1036     display_config.load_1=1;
1037     display_config.load_5=0;
1038     display_config.load_15=0;
1039    
1040     display_config.pages_in=1;
1041     display_config.pages_out=1;
1042    
1043 pajs 1.15 display_config.processes=1;
1044 pajs 1.1
1045 pajs 1.2 display_config.network_io_total_tx=1;
1046     display_config.network_io_total_rx=1;
1047 pajs 1.8 display_config.network_all_stats=0;
1048 pajs 1.1
1049 pajs 1.8 display_config.disk_io_total_write=1;
1050     display_config.disk_io_total_read=1;
1051 pajs 1.2 display_config.disk_io_all_stats=0;
1052 pajs 1.1
1053     display_config.disk_total_used=0;
1054 pajs 1.15 display_config.disk_all_stats=0;
1055    
1056     signal(SIGWINCH, sig_winch_handler);
1057 pajs 1.1
1058 tdb 1.17 server_name=DEF_SERVER_NAME;
1059     server_control_port=DEF_SERVER_PORT;
1060    
1061     while((cmdopt=getopt(argc, argv, "o:s:p:l:h")) != -1){
1062 pajs 1.1 switch(cmdopt){
1063 tdb 1.17 case 'o':
1064 pajs 1.2 if(!strcmp(optarg, "cpu")){
1065     sortby_ptr=cmp_cpu_used;
1066 pajs 1.7 strlcpy(display_config.sortby, CPU_USED, SORTBYMAXNAME);
1067 pajs 1.2 }
1068     if(!strcmp(optarg, "load")){
1069     sortby_ptr=cmp_load_1;
1070 pajs 1.7 strlcpy(display_config.sortby, LOAD, SORTBYMAXNAME);
1071 pajs 1.2 }
1072     if(!strcmp(optarg, "mem")){
1073     sortby_ptr=cmp_memory_used_pecent;
1074 pajs 1.7 strlcpy(display_config.sortby, MEM, SORTBYMAXNAME);
1075 pajs 1.2 }
1076 pajs 1.7 if(!strcmp(optarg, "swap")){
1077 tdb 1.17 sortby_ptr=cmp_swap_used_pecent;
1078     strlcpy(display_config.sortby, SWAP, SORTBYMAXNAME);
1079     }
1080     if(!strcmp(optarg, "net")){
1081     sortby_ptr=cmp_network_io_total;
1082     strlcpy(display_config.sortby, NETIO, SORTBYMAXNAME);
1083     }
1084     if(!strcmp(optarg, "disk")){
1085     sortby_ptr=cmp_disk_io_total;
1086     strlcpy(display_config.sortby, DISKIO, SORTBYMAXNAME);
1087     }
1088 pajs 1.2 if(sortby_ptr==NULL){
1089 tdb 1.17 errf("Invalid order given.");
1090     usage();
1091 pajs 1.2 }
1092 tdb 1.17 break;
1093     case 's':
1094     server_name=optarg;
1095     break;
1096     case 'p':
1097     server_control_port=atoi(optarg);
1098     break;
1099     case 'l':
1100     /* We've been passed a machine list */
1101     /* list currently needs to be ; seperated */
1102     machine_list=strdup(optarg);
1103     break;
1104     case 'h':
1105 tdb 1.19 default:
1106 tdb 1.17 usage();
1107     break;
1108 pajs 1.1 }
1109     }
1110    
1111 tdb 1.17 /* Don't take any other arguments */
1112     if(argc>optind){
1113     usage();
1114     }
1115    
1116 pajs 1.7 if(sortby_ptr==NULL){
1117     sortby_ptr=cmp_cpu_used;
1118     strlcpy(display_config.sortby, "CPU Used", SORTBYMAXNAME);
1119     }
1120 pajs 1.1
1121 tdb 1.17 control=create_tcp_connection(server_name, server_control_port);
1122 pajs 1.1 if(control==NULL){
1123     errf("Failed to connect (%m)");
1124 pajs 1.12 exit(1);
1125 pajs 1.1 }
1126    
1127     if((tcp_comm(control, NULL, &response, "PROTOCOL 1.1"))!=0){
1128     errf("Incorrect version number (%s)", response);
1129     exit(1);
1130     }
1131    
1132     if((tcp_comm(control, "stattop", &response, "OK"))!=0){
1133     errf("Unexpected response %s", response);
1134     exit(1);
1135     }
1136    
1137     if(machine_list!=NULL){
1138     if((tcp_comm(control, "SETHOSTLIST", &response, "OK"))!=0){
1139     errf("Unexpected response %s", response);
1140     exit(1);
1141     }
1142     if((tcp_comm(control, machine_list, &response, "OK"))!=0){
1143     errf("Unexpected response %s", response);
1144     exit(1);
1145     }
1146     }
1147    
1148     if((tcp_comm(control, "STARTDATA", &response, NULL))!=0){
1149     errf("Unexpected response %s", response);
1150     exit(1);
1151     }
1152    
1153     server_data_port=atoi(response);
1154     if(server_data_port==0){
1155     errf("Unexpected response %s", response);
1156     exit(1);
1157     }
1158    
1159 tdb 1.17 data=create_tcp_connection(server_name, server_data_port);
1160 pajs 1.1 if(data==NULL){
1161 tdb 1.17 errf("Failed to connect to host %s on port %d (%m)",server_name, server_data_port);
1162 pajs 1.13 exit(1);
1163 pajs 1.1 }
1164    
1165 pajs 1.4 initscr();
1166     nonl();
1167     cbreak();
1168 pajs 1.15 noecho();
1169 pajs 1.4 window=newwin(0, 0, 0, 0);
1170 pajs 1.14 getmaxyx(window, display_config.maxy, display_config.maxx);
1171 pajs 1.4
1172 pajs 1.5 stdin_fileno=fileno(stdin);
1173     data_fileno=fileno(data);
1174     biggest_fileno=(data_fileno>stdin_fileno) ? (data_fileno+1) : (stdin_fileno+1);
1175 pajs 1.7
1176 pajs 1.1 for(;;){
1177 pajs 1.5 FD_ZERO(&infds);
1178     FD_SET(stdin_fileno, &infds);
1179     FD_SET(data_fileno, &infds);
1180 pajs 1.13 if((select(biggest_fileno, &infds, NULL, NULL, NULL))==-1){
1181 pajs 1.15 if(errno!=EINTR){
1182     errf("select failed with (%m)");
1183     exit(1);
1184     }
1185     }
1186    
1187     if(sig_winch){
1188 pajs 1.13 if (ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) {
1189     resizeterm(size.ws_row, size.ws_col);
1190     wrefresh(curscr);
1191     }
1192 pajs 1.14 getmaxyx(window, display_config.maxy, display_config.maxx);
1193 pajs 1.13 title=1;
1194 pajs 1.14 display(machine_data_list, &display_config, &title);
1195 pajs 1.13 refresh();
1196 pajs 1.15 sig_winch=0;
1197 pajs 1.13 continue;
1198     }
1199 pajs 1.5
1200     if(FD_ISSET(stdin_fileno, &infds)){
1201    
1202 pajs 1.15 ch=getch();
1203 pajs 1.7 switch(ch){
1204 pajs 1.15 case KEY_RESIZE:
1205     sig_winch=1;
1206     break;
1207 pajs 1.8
1208     /* Quit */
1209 pajs 1.7 case 'Q':
1210     case 'q':
1211     endwin();
1212     exit(0);
1213     break;
1214 pajs 1.14 /* Units */
1215     case 'U':
1216     case 'u':
1217     if(display_config.units == 'b'){
1218     display_config.units = 'k';
1219     }else if(display_config.units == 'k'){
1220     display_config.units = 'm';
1221     }else{
1222     display_config.units = 'b';
1223     }
1224     break;
1225 pajs 1.7
1226 pajs 1.8 /* Sort by */
1227 pajs 1.7 case 'C':
1228     sortby_ptr=cmp_cpu_used;
1229     strlcpy(display_config.sortby, CPU_USED, SORTBYMAXNAME);
1230     break;
1231    
1232     case 'M':
1233     sortby_ptr=cmp_memory_used_pecent;
1234     strlcpy(display_config.sortby, MEM, SORTBYMAXNAME);
1235     break;
1236    
1237     case 'L':
1238     sortby_ptr=cmp_load_1;
1239     strlcpy(display_config.sortby, LOAD, SORTBYMAXNAME);
1240     break;
1241    
1242     case 'S':
1243     sortby_ptr=cmp_swap_used_pecent;
1244     strlcpy(display_config.sortby, SWAP, SORTBYMAXNAME);
1245     break;
1246    
1247     case 'N':
1248     if(sortby_ptr==cmp_network_io_total){
1249     strlcpy(display_config.sortby, NETIORX, SORTBYMAXNAME);
1250     sortby_ptr=cmp_network_io_total_rx;
1251     }else if(sortby_ptr==cmp_network_io_total_rx){
1252     strlcpy(display_config.sortby, NETIOTX, SORTBYMAXNAME);
1253     sortby_ptr=cmp_network_io_total_tx;
1254     }else{
1255     strlcpy(display_config.sortby, NETIO, SORTBYMAXNAME);
1256     sortby_ptr=cmp_network_io_total;
1257     }
1258     break;
1259 pajs 1.8 case 'D':
1260     if(sortby_ptr==cmp_disk_io_total){
1261     strlcpy(display_config.sortby, DISKIOR, SORTBYMAXNAME);
1262     sortby_ptr=cmp_disk_io_total_read;
1263     }else if(sortby_ptr==cmp_disk_io_total_read){
1264     strlcpy(display_config.sortby, DISKIOW, SORTBYMAXNAME);
1265     sortby_ptr=cmp_disk_io_total_write;
1266     }else{
1267     strlcpy(display_config.sortby, DISKIO, SORTBYMAXNAME);
1268     sortby_ptr=cmp_disk_io_total;
1269     }
1270     break;
1271    
1272     /* Display */
1273    
1274     case 'd':
1275     if(display_config.disk_io_total_read){
1276     display_config.disk_io_total_read=0;
1277     display_config.disk_io_total_write=0;
1278     }else{
1279     display_config.disk_io_total_read=1;
1280     display_config.disk_io_total_write=1;
1281     }
1282     break;
1283     case 'n':
1284     if(display_config.network_io_total_rx){
1285     display_config.network_io_total_rx=0;
1286     display_config.network_io_total_tx=0;
1287     }else{
1288     display_config.network_io_total_rx=1;
1289     display_config.network_io_total_tx=1;
1290     }
1291     break;
1292     case 'm':
1293     if(display_config.memory_used_pecent){
1294     display_config.memory_used_pecent=0;
1295     }else{
1296     display_config.memory_used_pecent=1;
1297     }
1298     break;
1299    
1300     case 's':
1301     if(display_config.swap_used_pecent){
1302     display_config.swap_used_pecent=0;
1303     }else{
1304     display_config.swap_used_pecent=1;
1305     }
1306     break;
1307     case 'l':
1308     if(display_config.load_1){
1309     display_config.load_1=0;
1310     }else{
1311     display_config.load_1=1;
1312     }
1313     break;
1314     case 'p':
1315     if(display_config.pages_in){
1316     display_config.pages_in=0;
1317     display_config.pages_out=0;
1318     }else{
1319     display_config.pages_in=1;
1320     display_config.pages_out=1;
1321     }
1322     break;
1323     case 'c':
1324     if(display_config.cpu_used){
1325     display_config.cpu_used=0;
1326     }else{
1327     display_config.cpu_used=1;
1328     }
1329     break;
1330 pajs 1.15 case 'r':
1331     if(display_config.processes){
1332     display_config.processes=0;
1333     }else{
1334     display_config.processes=1;
1335     }
1336     break;
1337 pajs 1.5
1338 pajs 1.8 default:
1339 pajs 1.15 continue;
1340 pajs 1.5 }
1341 pajs 1.8
1342     /* Increment title so it becomes true (and making the screen update */
1343     title++;
1344 pajs 1.7
1345 pajs 1.5 }
1346     if(FD_ISSET(data_fileno, &infds)){
1347     response=fpgetline(data);
1348     if (response==NULL){
1349     errf("Failed to read data (%m)");
1350     exit(1);
1351     }
1352 pajs 1.1 }
1353    
1354 pajs 1.4
1355 pajs 1.1 num_hosts=parse_xml(response, &machine_data_list);
1356     if(num_hosts==-1) continue;
1357 pajs 1.2 machine_data_list=sort_machine_stats(machine_data_list, num_hosts, sortby_ptr);
1358 pajs 1.14 display(machine_data_list, &display_config, &title);
1359 pajs 1.1
1360     }
1361     exit(0);
1362     }