ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/idar/idar.c
Revision: 1.17
Committed: Thu Aug 21 13:51:19 2003 UTC (20 years, 9 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.16: +56 -26 lines
Log Message:
Tidy up of my previous commit to make the command line arguments optional.

- Made the default hostname 'i-scream'. Users could have this in their
  hosts file, or they might have a CNAME to their server.
- Added a usage function listing new command line arguments.
- Made the server name and port be options (-s and -p) instead of args.
- Changed the sort option from -s to -o (order).
- Made the host list an option (-l) instead of an argument.
- Added sort options for net and disk io.

This should be slightly tidier than before, and more useful.

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