ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/saidar/saidar.c
Revision: 1.42
Committed: Sun Oct 3 18:35:58 2010 UTC (13 years, 7 months ago) by tdb
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.41: +6 -2 lines
Log Message:
Add support for AIX 5.x - 9.x.

Many thanks to Jens Rehsack <rehsack@googlemail.com> for providing the
patch for this work. Thanks!

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