ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/saidar/saidar.c
Revision: 1.40
Committed: Sun Dec 17 01:06:16 2006 UTC (17 years, 11 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.39: +2 -1 lines
Log Message:
Hide cursor when possible.

File Contents

# User Rev Content
1 tdb 1.2 /*
2 tdb 1.28 * i-scream libstatgrab
3 tdb 1.2 * http://www.i-scream.org
4 tdb 1.23 * Copyright (C) 2000-2004 i-scream
5 tdb 1.2 *
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 tdb 1.24 *
20 tdb 1.40 * $Id: saidar.c,v 1.39 2006/12/01 14:21:17 tdb Exp $
21 tdb 1.2 */
22    
23     #ifdef HAVE_CONFIG_H
24     #include "config.h"
25     #endif
26    
27 pajs 1.1 #include <stdio.h>
28     #include <string.h>
29     #include <sys/ioctl.h>
30     #include <unistd.h>
31     #include <stdlib.h>
32     #include <sys/termios.h>
33     #include <signal.h>
34     #include <errno.h>
35     #include <statgrab.h>
36     #include <sys/times.h>
37     #include <limits.h>
38     #include <time.h>
39 tdb 1.36 #include <math.h>
40 tdb 1.2
41     #ifdef HAVE_NCURSES_H
42 tdb 1.38 #define COLOR_SUPPORT
43 tdb 1.2 #endif
44 tdb 1.39 #include CURSES_HEADER_FILE
45 pajs 1.1
46 tdb 1.36 #define THRESHOLD_LOAD 1.0
47    
48     #define THRESHOLD_WARN_ZMB 0
49    
50     #define THRESHOLD_WARN_CPU 60.0
51     #define THRESHOLD_ALERT_CPU 90.0
52    
53     #define THRESHOLD_WARN_SWAP 75.0
54     #define THRESHOLD_ALERT_SWAP 90.0
55    
56     #define THRESHOLD_WARN_MEM 75.0
57     #define THRESHOLD_ALERT_MEM 90.0
58    
59     #define THRESHOLD_WARN_DISK 75.0
60     #define THRESHOLD_ALERT_DISK 90.0
61    
62 pajs 1.1 typedef struct{
63 ats 1.27 sg_cpu_percents *cpu_percents;
64     sg_mem_stats *mem_stats;
65     sg_swap_stats *swap_stats;
66     sg_load_stats *load_stats;
67     sg_process_count *process_count;
68     sg_page_stats *page_stats;
69    
70     sg_network_io_stats *network_io_stats;
71     int network_io_entries;
72 pajs 1.1
73 ats 1.27 sg_disk_io_stats *disk_io_stats;
74     int disk_io_entries;
75 pajs 1.1
76 ats 1.27 sg_fs_stats *fs_stats;
77     int fs_entries;
78 pajs 1.1
79 ats 1.27 sg_host_info *host_info;
80     sg_user_stats *user_stats;
81 pajs 1.1 }stats_t;
82 tdb 1.35
83 pajs 1.1 stats_t stats;
84    
85     char *size_conv(long long number){
86     char type[] = {'B', 'K', 'M', 'G', 'T'};
87     int x=0;
88 tdb 1.33 int sign=1;
89 pajs 1.1 static char string[10];
90    
91 tdb 1.33 if(number < 0){
92     sign=-1;
93     number=-number;
94     }
95    
96 pajs 1.1 for(;x<5;x++){
97     if( (number/1024) < (100)) {
98     break;
99     }
100     number = (number/1024);
101     }
102    
103 tdb 1.33 number = number*sign;
104    
105     snprintf(string, 10, "%lld%c", number, type[x]);
106 pajs 1.1 return string;
107 tdb 1.35
108 pajs 1.1 }
109    
110     char *hr_uptime(time_t time){
111     int day = 0, hour = 0, min = 0;
112     static char uptime_str[25];
113     int sec = (int) time;
114 tdb 1.35
115 pajs 1.1 day = sec / (24*60*60);
116     sec = sec % (24*60*60);
117     hour = sec / (60*60);
118     sec = sec % (60*60);
119     min = sec / 60;
120     sec = sec % 60;
121    
122     if(day){
123     snprintf(uptime_str, 25, "%dd %02d:%02d:%02d", day, hour, min, sec);
124     }else{
125     snprintf(uptime_str, 25, "%02d:%02d:%02d", hour, min, sec);
126     }
127     return uptime_str;
128     }
129    
130     void display_headings(){
131 ats 1.11 int line;
132    
133 pajs 1.1 move(0,0);
134     printw("Hostname :");
135     move(0,27);
136     printw("Uptime : ");
137     move(0,54);
138     printw("Date : ");
139    
140     /* Load */
141     move(2,0);
142     printw("Load 1 :");
143     move(3,0);
144     printw("Load 5 :");
145     move(4,0);
146     printw("Load 15 :");
147    
148     /* CPU */
149     move(2,21);
150     printw("CPU Idle :");
151     move(3,21);
152     printw("CPU System:");
153     move(4,21);
154     printw("CPU User :");
155    
156     /* Process */
157     move(2, 42);
158     printw("Running :");
159     move(3, 42);
160     printw("Sleeping :");
161     move(4, 42);
162     printw("Stopped :");
163     move(2, 62);
164     printw("Zombie :");
165     move(3, 62);
166     printw("Total :");
167     move(4, 62);
168     printw("No. Users :");
169    
170     /* Mem */
171     move(6, 0);
172     printw("Mem Total :");
173     move(7, 0);
174     printw("Mem Used :");
175     move(8, 0);
176     printw("Mem Free :");
177    
178     /* Swap */
179 tdb 1.29 move(6, 21);
180     printw("Swap Total:");
181     move(7, 21);
182     printw("Swap Used :");
183     move(8, 21);
184     printw("Swap Free :");
185 pajs 1.1
186     /* VM */
187     move(6, 42);
188     printw("Mem Used :");
189     move(7, 42);
190     printw("Swap Used :");
191     move(8, 42);
192     printw("Total Used:");
193    
194     /* Paging */
195     move(6, 62);
196     printw("Paging in :");
197     move(7, 62);
198     printw("Paging out:");
199    
200     /* Disk IO */
201     move(10,0);
202     printw("Disk Name");
203     move(10,15);
204     printw("Read");
205     move(10,28);
206 tdb 1.35 printw("Write");
207 pajs 1.1
208 ats 1.11 line = 10;
209 ats 1.27 if (stats.network_io_stats != NULL) {
210 ats 1.11 /* Network IO */
211     move(line, 42);
212     printw("Network Interface");
213     move(line, 67);
214     printw("rx");
215     move(line, 77);
216     printw("tx");
217 ats 1.27 line += 2 + stats.network_io_entries;
218 ats 1.11 }
219 pajs 1.1
220 ats 1.11 move(line, 42);
221 pajs 1.1 printw("Mount Point");
222 ats 1.11 move(line, 65);
223 pajs 1.1 printw("Free");
224 ats 1.11 move(line, 75);
225 pajs 1.1 printw("Used");
226    
227     refresh();
228     }
229    
230 tdb 1.36 void display_data(int colors){
231 pajs 1.1 char cur_time[20];
232     struct tm *tm_time;
233     time_t epoc_time;
234 ats 1.11 int counter, line;
235 pajs 1.1 long long r,w;
236     long long rt, wt;
237 ats 1.27 sg_disk_io_stats *disk_io_stat_ptr;
238     sg_network_io_stats *network_stat_ptr;
239     sg_fs_stats *disk_stat_ptr;
240 pajs 1.7 /* Size before it will start overwriting "uptime" */
241     char hostname[15];
242     char *ptr;
243 pajs 1.1
244 ats 1.27 if (stats.host_info != NULL) {
245 ats 1.11 move(0,12);
246 ats 1.27 strncpy(hostname, stats.host_info->hostname, (sizeof(hostname) - 1));
247 ats 1.11 /* strncpy does not NULL terminate.. If only strlcpy was on all platforms :) */
248     hostname[14] = '\0';
249     ptr=strchr(hostname, '.');
250     /* Some hosts give back a FQDN for hostname. To avoid this, we'll
251     * just blank out everything after the first "."
252     */
253     if (ptr != NULL){
254     *ptr = '\0';
255 tdb 1.35 }
256 tdb 1.36 if (colors) {
257     attron(COLOR_PAIR(1));
258     }
259 ats 1.11 printw("%s", hostname);
260     move(0,36);
261 ats 1.27 printw("%s", hr_uptime(stats.host_info->uptime));
262 ats 1.11 epoc_time=time(NULL);
263     tm_time = localtime(&epoc_time);
264     strftime(cur_time, 20, "%Y-%m-%d %T", tm_time);
265     move(0,61);
266     printw("%s", cur_time);
267 tdb 1.36 if (colors) {
268     attroff(COLOR_PAIR(1));
269     }
270 ats 1.11 }
271 pajs 1.1
272 ats 1.11 if (stats.load_stats != NULL) {
273     /* Load */
274 tdb 1.36 if (colors) {
275     attron(COLOR_PAIR(6));
276     }
277 ats 1.11 move(2,12);
278 tdb 1.36 if (colors && fabs(stats.load_stats->min1 - stats.load_stats->min5) > THRESHOLD_LOAD) {
279     attron(A_BOLD);
280     }
281 ats 1.11 printw("%6.2f", stats.load_stats->min1);
282 tdb 1.36 if (colors) {
283     attroff(A_BOLD);
284     }
285 ats 1.11 move(3,12);
286 tdb 1.36 if (colors && fabs(stats.load_stats->min5 - stats.load_stats->min15) > THRESHOLD_LOAD) {
287     attron(A_BOLD);
288     }
289 ats 1.11 printw("%6.2f", stats.load_stats->min5);
290 tdb 1.36 if (colors) {
291     attroff(A_BOLD);
292     }
293 ats 1.11 move(4,12);
294 tdb 1.36 if (colors && fabs(stats.load_stats->min1 - stats.load_stats->min15) > THRESHOLD_LOAD) {
295     attron(A_BOLD);
296     }
297 ats 1.11 printw("%6.2f", stats.load_stats->min15);
298 tdb 1.36 if (colors) {
299     attroff(A_BOLD);
300     }
301 ats 1.11 }
302 pajs 1.1
303 ats 1.11 if (stats.cpu_percents != NULL) {
304     /* CPU */
305     move(2,33);
306     printw("%6.2f%%", stats.cpu_percents->idle);
307     move(3,33);
308     printw("%6.2f%%", (stats.cpu_percents->kernel + stats.cpu_percents->iowait + stats.cpu_percents->swap));
309     move(4,33);
310 tdb 1.36 if (colors && stats.cpu_percents->user + stats.cpu_percents->nice > THRESHOLD_ALERT_CPU) {
311     attron(A_STANDOUT);
312 tdb 1.37 attron(A_BOLD);
313 tdb 1.36 }
314     else if (colors && stats.cpu_percents->user + stats.cpu_percents->nice > THRESHOLD_WARN_CPU) {
315     attron(A_BOLD);
316     }
317 ats 1.11 printw("%6.2f%%", (stats.cpu_percents->user + stats.cpu_percents->nice));
318 tdb 1.36 if(colors) {
319     attroff(A_BOLD);
320     attroff(A_STANDOUT);
321     attron(COLOR_PAIR(6));
322     }
323 ats 1.11 }
324 pajs 1.1
325 ats 1.27 if (stats.process_count != NULL) {
326 ats 1.11 /* Process */
327     move(2, 54);
328 ats 1.27 printw("%5d", stats.process_count->running);
329 ats 1.11 move(2,74);
330 tdb 1.36 if (colors && stats.process_count->zombie > THRESHOLD_WARN_ZMB) {
331     attron(A_STANDOUT);
332 tdb 1.37 attron(A_BOLD);
333 tdb 1.36 }
334 ats 1.27 printw("%5d", stats.process_count->zombie);
335 tdb 1.36 if(colors) {
336     attroff(A_STANDOUT);
337 tdb 1.37 attroff(A_BOLD);
338 tdb 1.36 }
339 ats 1.11 move(3, 54);
340 ats 1.27 printw("%5d", stats.process_count->sleeping);
341 ats 1.11 move(3, 74);
342 ats 1.27 printw("%5d", stats.process_count->total);
343 ats 1.11 move(4, 54);
344 ats 1.27 printw("%5d", stats.process_count->stopped);
345 ats 1.11 }
346     if (stats.user_stats != NULL) {
347     move(4,74);
348     printw("%5d", stats.user_stats->num_entries);
349     }
350 pajs 1.1
351 tdb 1.36 if(colors) {
352     attroff(COLOR_PAIR(6));
353     attron(COLOR_PAIR(5));
354     }
355 ats 1.11 if (stats.mem_stats != NULL) {
356     /* Mem */
357     move(6, 12);
358 tdb 1.35 printw("%7s", size_conv(stats.mem_stats->total));
359 ats 1.11 move(7, 12);
360 tdb 1.35 printw("%7s", size_conv(stats.mem_stats->used));
361 ats 1.11 move(8, 12);
362     printw("%7s", size_conv(stats.mem_stats->free));
363     }
364 tdb 1.35
365     if (stats.swap_stats != NULL) {
366 ats 1.11 /* Swap */
367     move(6, 32);
368     printw("%8s", size_conv(stats.swap_stats->total));
369     move(7, 32);
370     printw("%8s", size_conv(stats.swap_stats->used));
371     move(8, 32);
372     printw("%8s", size_conv(stats.swap_stats->free));
373     }
374    
375 tdb 1.12 /* VM */
376 tdb 1.35 if (stats.mem_stats != NULL && stats.mem_stats->total != 0) {
377 tdb 1.36 float f = 100.00 * (float)(stats.mem_stats->used)/stats.mem_stats->total;
378     if (colors && f > THRESHOLD_ALERT_MEM) {
379     attron(A_STANDOUT);
380 tdb 1.37 attron(A_BOLD);
381 tdb 1.36 }
382     else if (colors && f > THRESHOLD_WARN_MEM) {
383     attron(A_BOLD);
384     }
385 ats 1.11 move(6, 54);
386 tdb 1.36 printw("%5.2f%%", f);
387     if (colors) {
388     attroff(A_STANDOUT);
389     attroff(A_BOLD);
390     attron(COLOR_PAIR(5));
391     }
392 tdb 1.12 }
393 tdb 1.35 if (stats.swap_stats != NULL && stats.swap_stats->total != 0) {
394 tdb 1.36 float f = 100.00 * (float)(stats.swap_stats->used)/stats.swap_stats->total;
395     if (colors && f > THRESHOLD_ALERT_SWAP) {
396     attron(A_STANDOUT);
397 tdb 1.37 attron(A_BOLD);
398 tdb 1.36 }
399     else if (colors && f > THRESHOLD_WARN_SWAP) {
400     attron(A_BOLD);
401     }
402 ats 1.11 move(7, 54);
403 tdb 1.36 printw("%5.2f%%", f);
404     if (colors) {
405     attroff(A_STANDOUT);
406     attroff(A_BOLD);
407     attron(COLOR_PAIR(5));
408     }
409 tdb 1.12 }
410 tdb 1.13 if (stats.mem_stats != NULL && stats.swap_stats != NULL &&
411 tdb 1.35 stats.mem_stats->total != 0 && stats.swap_stats->total != 0) {
412 ats 1.11 move(8, 54);
413     printw("%5.2f%%", (100.00 * (float)(stats.mem_stats->used+stats.swap_stats->used)/(stats.mem_stats->total+stats.swap_stats->total)));
414     }
415    
416 tdb 1.35 if (stats.page_stats != NULL) {
417 ats 1.11 /* Paging */
418     move(6, 74);
419     printw("%5d", (stats.page_stats->systime)? (stats.page_stats->pages_pagein / stats.page_stats->systime): stats.page_stats->pages_pagein);
420     move(7, 74);
421     printw("%5d", (stats.page_stats->systime)? (stats.page_stats->pages_pageout / stats.page_stats->systime) : stats.page_stats->pages_pageout);
422     }
423 tdb 1.36 if (colors) {
424     attroff(COLOR_PAIR(5));
425     }
426 pajs 1.1
427 ats 1.11 line = 11;
428 tdb 1.35 if (stats.disk_io_stats != NULL) {
429 ats 1.11 /* Disk IO */
430 ats 1.27 disk_io_stat_ptr = stats.disk_io_stats;
431 ats 1.11 r=0;
432     w=0;
433 ats 1.27 for(counter=0;counter<stats.disk_io_entries;counter++){
434 tdb 1.34 char name[12];
435     strncpy(name, disk_io_stat_ptr->disk_name, sizeof(name));
436     name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */
437 ats 1.11 move(line, 0);
438 tdb 1.34 printw("%s", name);
439 ats 1.11 move(line, 12);
440 ats 1.27 rt = (disk_io_stat_ptr->systime)? (disk_io_stat_ptr->read_bytes/disk_io_stat_ptr->systime): disk_io_stat_ptr->read_bytes;
441 tdb 1.36 if(colors) {
442     attron(COLOR_PAIR(4));
443     }
444 ats 1.11 printw("%7s", size_conv(rt));
445     r+=rt;
446     move(line, 26);
447 ats 1.27 wt = (disk_io_stat_ptr->systime)? (disk_io_stat_ptr->write_bytes/disk_io_stat_ptr->systime): disk_io_stat_ptr->write_bytes;
448 ats 1.11 printw("%7s", size_conv(wt));
449     w+=wt;
450 ats 1.27 disk_io_stat_ptr++;
451 ats 1.11 line++;
452 tdb 1.36 if(colors) {
453     attroff(COLOR_PAIR(4));
454     }
455 ats 1.11 }
456     line++;
457     move(line, 0);
458     printw("Total");
459     move(line, 12);
460 tdb 1.36 if(colors) {
461     attron(COLOR_PAIR(4));
462     }
463 ats 1.11 printw("%7s", size_conv(r));
464     move(line, 26);
465     printw("%7s", size_conv(w));
466 tdb 1.36 if(colors) {
467     attroff(COLOR_PAIR(4));
468     }
469 ats 1.11 }
470 pajs 1.1
471 ats 1.11 line = 11;
472 tdb 1.35 if (stats.network_io_stats != NULL) {
473 ats 1.11 /* Network */
474 ats 1.27 network_stat_ptr = stats.network_io_stats;
475     for(counter=0;counter<stats.network_io_entries;counter++){
476 tdb 1.34 char name[20];
477     strncpy(name, network_stat_ptr->interface_name, sizeof(name));
478     name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */
479 tdb 1.29 move(line, 42);
480 tdb 1.34 printw("%s", name);
481 ats 1.11 move(line, 62);
482     rt = (network_stat_ptr->systime)? (network_stat_ptr->rx / network_stat_ptr->systime): network_stat_ptr->rx;
483 tdb 1.36 if(colors) {
484     attron(COLOR_PAIR(4));
485     }
486 ats 1.11 printw("%7s", size_conv(rt));
487     move(line, 72);
488 tdb 1.35 wt = (network_stat_ptr->systime)? (network_stat_ptr->tx / network_stat_ptr->systime): network_stat_ptr->tx;
489 ats 1.11 printw("%7s", size_conv(wt));
490     network_stat_ptr++;
491     line++;
492 tdb 1.36 if(colors) {
493     attroff(COLOR_PAIR(4));
494     }
495 ats 1.11 }
496     line += 2;
497     }
498 pajs 1.1
499 tdb 1.35 if (stats.fs_stats != NULL) {
500 ats 1.11 /* Disk */
501 ats 1.27 disk_stat_ptr = stats.fs_stats;
502     for(counter=0;counter<stats.fs_entries;counter++){
503 tdb 1.34 char name[20];
504     strncpy(name, disk_stat_ptr->mnt_point, sizeof(name));
505     name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */
506 ats 1.11 move(line, 42);
507 tdb 1.34 printw("%s", name);
508 ats 1.11 move(line, 62);
509 tdb 1.36 if(colors) {
510     attron(COLOR_PAIR(2));
511     }
512 ats 1.11 printw("%7s", size_conv(disk_stat_ptr->avail));
513     move(line, 73);
514 tdb 1.36 if(colors && 100.00 * ((float) disk_stat_ptr->used / (float) (disk_stat_ptr->used + disk_stat_ptr->avail)) > THRESHOLD_ALERT_DISK) {
515     attron(A_STANDOUT);
516 tdb 1.37 attron(A_BOLD);
517 tdb 1.36 } else if (colors && 100.00 * ((float) disk_stat_ptr->used / (float) (disk_stat_ptr->used + disk_stat_ptr->avail)) > THRESHOLD_WARN_DISK) {
518     attron(A_BOLD);
519     }
520 tdb 1.30 printw("%6.2f%%", 100.00 * ((float) disk_stat_ptr->used / (float) (disk_stat_ptr->used + disk_stat_ptr->avail)));
521 ats 1.11 disk_stat_ptr++;
522     line++;
523 tdb 1.36 if(colors) {
524     attroff(COLOR_PAIR(2));
525     attroff(A_STANDOUT);
526     attroff(A_BOLD);
527     }
528 ats 1.11 }
529 pajs 1.1 }
530    
531     refresh();
532     }
533    
534 ats 1.32 void sig_winch_handler(int dummy){
535 pajs 1.1 clear();
536     display_headings();
537 tdb 1.36 display_data(0);
538 tdb 1.29 signal(SIGWINCH, sig_winch_handler);
539 pajs 1.1 }
540    
541     int get_stats(){
542 ats 1.27 stats.cpu_percents = sg_get_cpu_percents();
543     stats.mem_stats = sg_get_mem_stats();
544     stats.swap_stats = sg_get_swap_stats();
545     stats.load_stats = sg_get_load_stats();
546     stats.process_count = sg_get_process_count();
547     stats.page_stats = sg_get_page_stats_diff();
548     stats.network_io_stats = sg_get_network_io_stats_diff(&(stats.network_io_entries));
549     stats.disk_io_stats = sg_get_disk_io_stats_diff(&(stats.disk_io_entries));
550     stats.fs_stats = sg_get_fs_stats(&(stats.fs_entries));
551     stats.host_info = sg_get_host_info();
552     stats.user_stats = sg_get_user_stats();
553 pajs 1.1
554 ats 1.11 return 1;
555 pajs 1.1 }
556    
557 pajs 1.3 void version_num(char *progname){
558 pajs 1.5 fprintf(stderr, "%s version %s\n", progname, PACKAGE_VERSION);
559 pajs 1.3 fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
560     exit(1);
561     }
562    
563     void usage(char *progname){
564 tdb 1.38 #ifdef COLOR_SUPPORT
565 tdb 1.36 fprintf(stderr, "Usage: %s [-d delay] [-c] [-v] [-h]\n\n", progname);
566 tdb 1.38 #else
567     fprintf(stderr, "Usage: %s [-d delay] [-v] [-h]\n\n", progname);
568     #endif
569 tdb 1.29 fprintf(stderr, " -d Sets the update time in seconds\n");
570 tdb 1.38 #ifdef COLOR_SUPPORT
571 tdb 1.36 fprintf(stderr, " -c Enables coloured output\n");
572 tdb 1.38 #endif
573 pajs 1.4 fprintf(stderr, " -v Prints version number\n");
574 tdb 1.29 fprintf(stderr, " -h Displays this help information.\n");
575     fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
576     exit(1);
577 pajs 1.3 }
578    
579 pajs 1.1 int main(int argc, char **argv){
580 tdb 1.29 extern char *optarg;
581     int c;
582 tdb 1.36 int colouron = 0;
583 pajs 1.1
584 ats 1.17 time_t last_update = 0;
585    
586 pajs 1.1 WINDOW *window;
587    
588     extern int errno;
589    
590     int delay=2;
591 ats 1.21
592 ats 1.27 sg_init();
593     if(sg_drop_privileges() != 0){
594 ats 1.22 fprintf(stderr, "Failed to drop setuid/setgid privileges\n");
595 pajs 1.10 return 1;
596     }
597 tdb 1.35
598 tdb 1.38 #ifdef COLOR_SUPPORT
599 tdb 1.36 while ((c = getopt(argc, argv, "d:cvh")) != -1){
600 tdb 1.38 #else
601     while ((c = getopt(argc, argv, "d:vh")) != -1){
602     #endif
603 tdb 1.29 switch (c){
604     case 'd':
605     delay = atoi(optarg);
606 tdb 1.25 if (delay < 1){
607 pajs 1.1 fprintf(stderr, "Time must be 1 second or greater\n");
608     exit(1);
609     }
610 tdb 1.29 break;
611 tdb 1.38 #ifdef COLOR_SUPPORT
612 tdb 1.36 case 'c':
613     colouron = 1;
614     break;
615 tdb 1.38 #endif
616 pajs 1.3 case 'v':
617 tdb 1.35 version_num(argv[0]);
618 pajs 1.3 break;
619     case 'h':
620     default:
621     usage(argv[0]);
622     return 1;
623     break;
624 tdb 1.29 }
625     }
626 pajs 1.1
627     signal(SIGWINCH, sig_winch_handler);
628 tdb 1.29 initscr();
629 tdb 1.38 #ifdef COLOR_SUPPORT
630 tdb 1.36 /* turn on colour */
631     if (colouron) {
632     if (has_colors()) {
633     start_color();
634     use_default_colors();
635     init_pair(1,COLOR_RED,-1);
636     init_pair(2,COLOR_GREEN,-1);
637     init_pair(3,COLOR_YELLOW,-1);
638     init_pair(4,COLOR_BLUE,-1);
639     init_pair(5,COLOR_MAGENTA,-1);
640     init_pair(6,COLOR_CYAN,-1);
641     } else {
642     fprintf(stderr, "Colour support disabled: your terminal does not support colour.");
643     colouron = 0;
644     }
645     }
646 tdb 1.38 #endif
647 tdb 1.29 nonl();
648 tdb 1.40 curs_set(0);
649 tdb 1.29 cbreak();
650     noecho();
651 ats 1.14 timeout(delay * 1000);
652 tdb 1.29 window=newwin(0, 0, 0, 0);
653 pajs 1.1 clear();
654    
655     if(!get_stats()){
656     fprintf(stderr, "Failed to get all the stats. Please check correct permissions\n");
657     endwin();
658     return 1;
659     }
660    
661     display_headings();
662    
663     for(;;){
664 ats 1.17 time_t now;
665 ats 1.15 int ch = getch();
666 ats 1.17
667 ats 1.14 if (ch == 'q'){
668 ats 1.18 break;
669 pajs 1.1 }
670    
671 ats 1.17 /* To keep the numbers slightly accurate we do not want them
672     * updating more frequently than once a second.
673     */
674     now = time(NULL);
675     if ((now - last_update) >= 1) {
676     get_stats();
677     }
678     last_update = now;
679 pajs 1.1
680 tdb 1.36 display_data(colouron);
681 tdb 1.35 }
682 pajs 1.1
683     endwin();
684     return 0;
685 tdb 1.35 }