ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/saidar/saidar.c
Revision: 1.8
Committed: Sat Oct 18 14:08:36 2003 UTC (20 years, 7 months ago) by pajs
Content type: text/plain
Branch: MAIN
Changes since 1.7: +3 -1 lines
Log Message:
Brain failure over a confusion with strncpy (thinking it worked like strlcpy)

File Contents

# User Rev Content
1 tdb 1.2 /*
2     * i-scream central monitoring system
3     * http://www.i-scream.org
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/ioctl.h>
28     #include <unistd.h>
29     #include <stdlib.h>
30     #include <sys/termios.h>
31     #include <signal.h>
32     #include <errno.h>
33     #include <statgrab.h>
34     #include <sys/times.h>
35     #include <limits.h>
36     #include <time.h>
37 tdb 1.2
38     #ifdef HAVE_NCURSES_H
39     #include <ncurses.h>
40     #else
41 pajs 1.1 #include <curses.h>
42 tdb 1.2 #endif
43 pajs 1.1
44     typedef struct{
45     cpu_percent_t *cpu_percents;
46     mem_stat_t *mem_stats;
47     swap_stat_t *swap_stats;
48     load_stat_t *load_stats;
49     process_stat_t *process_stats;
50     page_stat_t *page_stats;
51    
52     network_stat_t *network_stats;
53     int network_entries;
54    
55     diskio_stat_t *diskio_stats;
56     int diskio_entries;
57    
58     disk_stat_t *disk_stats;
59     int disk_entries;
60    
61     general_stat_t *general_stats;
62     user_stat_t *user_stats;
63     }stats_t;
64    
65     stats_t stats;
66    
67     char *size_conv(long long number){
68     char type[] = {'B', 'K', 'M', 'G', 'T'};
69     int x=0;
70     static char string[10];
71    
72     for(;x<5;x++){
73     if( (number/1024) < (100)) {
74     break;
75     }
76     number = (number/1024);
77     }
78    
79     snprintf(string, 10, "%lld%c", number, type[x]);
80     return string;
81    
82     }
83    
84     char *hr_uptime(time_t time){
85     int day = 0, hour = 0, min = 0;
86     static char uptime_str[25];
87     int sec = (int) time;
88    
89     day = sec / (24*60*60);
90     sec = sec % (24*60*60);
91     hour = sec / (60*60);
92     sec = sec % (60*60);
93     min = sec / 60;
94     sec = sec % 60;
95    
96     if(day){
97     snprintf(uptime_str, 25, "%dd %02d:%02d:%02d", day, hour, min, sec);
98     }else{
99     snprintf(uptime_str, 25, "%02d:%02d:%02d", hour, min, sec);
100     }
101     return uptime_str;
102     }
103    
104     void display_headings(){
105     move(0,0);
106     printw("Hostname :");
107     move(0,27);
108     printw("Uptime : ");
109     move(0,54);
110     printw("Date : ");
111    
112     /* Load */
113     move(2,0);
114     printw("Load 1 :");
115     move(3,0);
116     printw("Load 5 :");
117     move(4,0);
118     printw("Load 15 :");
119    
120     /* CPU */
121     move(2,21);
122     printw("CPU Idle :");
123     move(3,21);
124     printw("CPU System:");
125     move(4,21);
126     printw("CPU User :");
127    
128     /* Process */
129     move(2, 42);
130     printw("Running :");
131     move(3, 42);
132     printw("Sleeping :");
133     move(4, 42);
134     printw("Stopped :");
135     move(2, 62);
136     printw("Zombie :");
137     move(3, 62);
138     printw("Total :");
139     move(4, 62);
140     printw("No. Users :");
141    
142     /* Mem */
143     move(6, 0);
144     printw("Mem Total :");
145     move(7, 0);
146     printw("Mem Used :");
147     move(8, 0);
148     printw("Mem Free :");
149    
150     /* Swap */
151     move(6, 21);
152     printw("Swap Total:");
153     move(7, 21);
154     printw("Swap Used :");
155     move(8, 21);
156     printw("Swap Free :");
157    
158     /* VM */
159     move(6, 42);
160     printw("Mem Used :");
161     move(7, 42);
162     printw("Swap Used :");
163     move(8, 42);
164     printw("Total Used:");
165    
166     /* Paging */
167     move(6, 62);
168     printw("Paging in :");
169     move(7, 62);
170     printw("Paging out:");
171    
172     /* Disk IO */
173     move(10,0);
174     printw("Disk Name");
175     move(10,15);
176     printw("Read");
177     move(10,28);
178     printw("Write");
179    
180     /* Network IO */
181     move(10, 42);
182     printw("Network Interface");
183     move(10, 67);
184     printw("rx");
185     move(10,77);
186     printw("tx");
187    
188     move(12+stats.network_entries, 42);
189     printw("Mount Point");
190     move(12+stats.network_entries, 65);
191     printw("Free");
192     move(12+stats.network_entries, 75);
193     printw("Used");
194    
195     refresh();
196     }
197    
198     void display_data(){
199     char cur_time[20];
200     struct tm *tm_time;
201     time_t epoc_time;
202     int counter;
203     long long r,w;
204     long long rt, wt;
205     diskio_stat_t *diskio_stat_ptr;
206     network_stat_t *network_stat_ptr;
207     disk_stat_t *disk_stat_ptr;
208 pajs 1.7 /* Size before it will start overwriting "uptime" */
209     char hostname[15];
210     char *ptr;
211 pajs 1.1
212     move(0,12);
213 pajs 1.8 strncpy(hostname, stats.general_stats->hostname, (sizeof(hostname) - 1));
214     /* strncpy does not NULL terminate.. If only strlcpy was on all platforms :) */
215     hostname[14] = '\0';
216 pajs 1.7 ptr=strchr(hostname, '.');
217     /* Some hosts give back a FQDN for hostname. To avoid this, we'll
218     * just blank out everything after the first "."
219     */
220     if (ptr != NULL){
221     *ptr = '\0';
222     }
223     printw("%s", hostname);
224 pajs 1.1 move(0,36);
225     printw("%s", hr_uptime(stats.general_stats->uptime));
226     epoc_time=time(NULL);
227     tm_time = localtime(&epoc_time);
228     strftime(cur_time, 20, "%Y-%m-%d %T", tm_time);
229     move(0,61);
230     printw("%s", cur_time);
231    
232     /* Load */
233     move(2,12);
234     printw("%6.2f", stats.load_stats->min1);
235     move(3,12);
236     printw("%6.2f", stats.load_stats->min5);
237     move(4,12);
238     printw("%6.2f", stats.load_stats->min15);
239    
240     /* CPU */
241     move(2,33);
242     printw("%6.2f%%", stats.cpu_percents->idle);
243     move(3,33);
244     printw("%6.2f%%", (stats.cpu_percents->kernel + stats.cpu_percents->iowait + stats.cpu_percents->swap));
245     move(4,33);
246     printw("%6.2f%%", (stats.cpu_percents->user + stats.cpu_percents->nice));
247    
248     /* Process */
249     move(2, 54);
250     printw("%5d", stats.process_stats->running);
251     move(2,74);
252     printw("%5d", stats.process_stats->zombie);
253     move(3, 54);
254     printw("%5d", stats.process_stats->sleeping);
255     move(3, 74);
256     printw("%5d", stats.process_stats->total);
257     move(4, 54);
258     printw("%5d", stats.process_stats->stopped);
259     move(4,74);
260     printw("%5d", stats.user_stats->num_entries);
261    
262     /* Mem */
263     move(6, 12);
264     printw("%7s", size_conv(stats.mem_stats->total));
265     move(7, 12);
266     printw("%7s", size_conv(stats.mem_stats->used));
267     move(8, 12);
268     printw("%7s", size_conv(stats.mem_stats->free));
269    
270     /* Swap */
271     move(6, 32);
272     printw("%8s", size_conv(stats.swap_stats->total));
273     move(7, 32);
274     printw("%8s", size_conv(stats.swap_stats->used));
275     move(8, 32);
276     printw("%8s", size_conv(stats.swap_stats->free));
277    
278     /* VM */
279     move(6, 54);
280     printw("%5.2f%%", (100.00 * (float)(stats.mem_stats->used)/stats.mem_stats->total));
281     move(7, 54);
282     printw("%5.2f%%", (100.00 * (float)(stats.swap_stats->used)/stats.swap_stats->total));
283     move(8, 54);
284     printw("%5.2f%%", (100.00 * (float)(stats.mem_stats->used+stats.swap_stats->used)/(stats.mem_stats->total+stats.swap_stats->total)));
285    
286     /* Paging */
287     move(6, 74);
288     printw("%5d", (stats.page_stats->systime)? (stats.page_stats->pages_pagein / stats.page_stats->systime): stats.page_stats->pages_pagein);
289     move(7, 74);
290     printw("%5d", (stats.page_stats->systime)? (stats.page_stats->pages_pageout / stats.page_stats->systime) : stats.page_stats->pages_pageout);
291    
292     /* Disk IO */
293     diskio_stat_ptr = stats.diskio_stats;
294     r=0;
295     w=0;
296     for(counter=0;counter<stats.diskio_entries;counter++){
297     move(11+counter, 0);
298     printw("%s", diskio_stat_ptr->disk_name);
299     move(11+counter, 12);
300     rt = (diskio_stat_ptr->systime)? (diskio_stat_ptr->read_bytes/diskio_stat_ptr->systime): diskio_stat_ptr->read_bytes;
301     printw("%7s", size_conv(rt));
302     r+=rt;
303     move(11+counter, 26);
304     wt = (diskio_stat_ptr->systime)? (diskio_stat_ptr->write_bytes/diskio_stat_ptr->systime): diskio_stat_ptr->write_bytes;
305     printw("%7s", size_conv(wt));
306     w+=wt;
307     diskio_stat_ptr++;
308     }
309     move(12+counter, 0);
310     printw("Total");
311     move(12+counter, 12);
312     printw("%7s", size_conv(r));
313     move(12+counter, 26);
314     printw("%7s", size_conv(w));
315    
316     /* Network */
317     network_stat_ptr = stats.network_stats;
318     for(counter=0;counter<stats.network_entries;counter++){
319     move(11+counter, 42);
320     printw("%s", network_stat_ptr->interface_name);
321     move(11+counter, 62);
322     rt = (network_stat_ptr->systime)? (network_stat_ptr->rx / network_stat_ptr->systime): network_stat_ptr->rx;
323     printw("%7s", size_conv(rt));
324     move(11+counter, 72);
325     wt = (network_stat_ptr->systime)? (network_stat_ptr->tx / network_stat_ptr->systime): network_stat_ptr->tx;
326     printw("%7s", size_conv(wt));
327     network_stat_ptr++;
328     }
329    
330 tdb 1.6 /* Disk */
331 pajs 1.1 disk_stat_ptr = stats.disk_stats;
332     for(counter=0;counter<stats.disk_entries;counter++){
333     move(13+stats.network_entries+counter, 42);
334     printw("%s", disk_stat_ptr->mnt_point);
335     move(13+stats.network_entries+counter, 62);
336     printw("%7s", size_conv(disk_stat_ptr->avail));
337     move(13+stats.network_entries+counter, 73);
338 tdb 1.6 printw("%5.2f%%", 100.00 * ((float) (disk_stat_ptr->size - disk_stat_ptr->avail) / (float) disk_stat_ptr->size));
339 pajs 1.1 disk_stat_ptr++;
340     }
341    
342     refresh();
343     }
344    
345     void sig_winch_handler(int sig){
346     clear();
347     display_headings();
348     display_data();
349     signal(SIGWINCH, sig_winch_handler);
350     }
351    
352     int get_stats(){
353     if((stats.cpu_percents = cpu_percent_usage()) == NULL) return 0;
354     if((stats.mem_stats = get_memory_stats()) == NULL) return 0;
355     if((stats.swap_stats = get_swap_stats()) == NULL) return 0;
356     if((stats.load_stats = get_load_stats()) == NULL) return 0;
357     if((stats.process_stats = get_process_stats()) == NULL) return 0;
358     if((stats.page_stats = get_page_stats_diff()) == NULL) return 0;
359     if((stats.network_stats = get_network_stats_diff(&(stats.network_entries))) == NULL) return 0;
360     if((stats.diskio_stats = get_diskio_stats_diff(&(stats.diskio_entries))) == NULL) return 0;
361     if((stats.disk_stats = get_disk_stats(&(stats.disk_entries))) == NULL) return 0;
362     if((stats.general_stats = get_general_stats()) == NULL) return 0;
363     if((stats.user_stats = get_user_stats()) == NULL) return 0;
364    
365     return 1;
366     }
367    
368 pajs 1.3 void version_num(char *progname){
369 pajs 1.5 fprintf(stderr, "%s version %s\n", progname, PACKAGE_VERSION);
370 pajs 1.3 fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
371     exit(1);
372     }
373    
374     void usage(char *progname){
375     fprintf(stderr, "Usage: %s [-d delay] [-v] [-h]\n\n", progname);
376     fprintf(stderr, " -d Sets the update time in seconds\n");
377 pajs 1.4 fprintf(stderr, " -v Prints version number\n");
378 pajs 1.3 fprintf(stderr, " -h Displays this help information.\n");
379     fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
380     exit(1);
381    
382     }
383    
384 pajs 1.1 int main(int argc, char **argv){
385    
386     extern char *optarg;
387     extern int optind;
388     int c;
389    
390     WINDOW *window;
391    
392     int stdin_fileno;
393     fd_set infds;
394     struct timeval timeout;
395    
396     extern int errno;
397     char ch;
398    
399     int delay=2;
400    
401 pajs 1.4 while ((c = getopt(argc, argv, "vhd:")) != EOF){
402 pajs 1.1 switch (c){
403     case 'd':
404     delay = atoi(optarg);
405     if (delay == 0){
406     fprintf(stderr, "Time must be 1 second or greater\n");
407     exit(1);
408     }
409     delay--;
410     break;
411 pajs 1.3 case 'v':
412     version_num(argv[0]);
413     break;
414     case 'h':
415     default:
416     usage(argv[0]);
417     return 1;
418     break;
419    
420 pajs 1.1 }
421     }
422    
423     signal(SIGWINCH, sig_winch_handler);
424     initscr();
425     nonl();
426     cbreak();
427     noecho();
428     window=newwin(0, 0, 0, 0);
429     clear();
430    
431     if(!get_stats()){
432     fprintf(stderr, "Failed to get all the stats. Please check correct permissions\n");
433     endwin();
434     return 1;
435     }
436    
437     display_headings();
438     stdin_fileno=fileno(stdin);
439    
440     for(;;){
441    
442     FD_ZERO(&infds);
443     FD_SET(stdin_fileno, &infds);
444     timeout.tv_sec = delay;
445     timeout.tv_usec = 0;
446    
447     if((select((stdin_fileno+1), &infds, NULL, NULL, &timeout)) == -1){
448     if(errno!=EINTR){
449     perror("select failed");
450     exit(1);
451     }
452     }
453    
454     if(FD_ISSET(stdin_fileno, &infds)){
455     ch=getch();
456     if (ch == 'q'){
457     endwin();
458     return 0;
459     }
460     }
461    
462     get_stats();
463    
464     display_data();
465    
466     /* To keep the numbers slightly accurate we do not want them updating more
467     * frequently than once a second.
468     */
469     sleep(1);
470    
471     }
472    
473    
474    
475     endwin();
476     return 0;
477     }