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

# Content
1 /*
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 #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
38 #ifdef HAVE_NCURSES_H
39 #include <ncurses.h>
40 #else
41 #include <curses.h>
42 #endif
43
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 /* Size before it will start overwriting "uptime" */
209 char hostname[15];
210 char *ptr;
211
212 move(0,12);
213 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 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 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 /* Disk */
331 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 printw("%5.2f%%", 100.00 * ((float) (disk_stat_ptr->size - disk_stat_ptr->avail) / (float) disk_stat_ptr->size));
339 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 void version_num(char *progname){
369 fprintf(stderr, "%s version %s\n", progname, PACKAGE_VERSION);
370 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 fprintf(stderr, " -v Prints version number\n");
378 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 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 while ((c = getopt(argc, argv, "vhd:")) != EOF){
402 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 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 }
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 }