source: npl/mediabox/lcdproc_edwin/src/old/stat.c @ c5c522c

gcc484ntopperl-5.22
Last change on this file since c5c522c was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100644
File size: 14.7 KB
Line 
1#include <stdlib.h>
2#include <stdio.h>
3#include <string.h>
4#include <fcntl.h>
5#include <unistd.h>
6#include <sys/time.h>
7#include <sys/utsname.h>
8#include "stat.h"
9#include "lcd.h"
10
11
12/*
13  Don't use this yet!  It's barely even started...
14 */
15
16
17
18struct load { unsigned long total, user, system, nice, idle; };
19struct meminfo { int total, cache, buffers, free, shared; };
20static char buffer[1024];
21
22// Nothing else can see these...
23static int meminfo_fd, load_fd, loadavg_fd, uptime_fd;
24
25static char kver[SYS_NMLN];
26static char sysname[SYS_NMLN];
27
28static void reread(int f, char *errmsg);
29static int getentry(const char *tag, const char *bufptr);
30static void get_mem_info(struct meminfo *result);
31static double get_loadavg(void);
32static double get_uptime(void);
33static void get_load(struct load * result);
34
35
36
37int stat_init()
38{
39  struct utsname *unamebuf =
40    (struct utsname *) malloc( sizeof(struct utsname) );
41
42  meminfo_fd = open("/proc/meminfo",O_RDONLY);
43  loadavg_fd = open("/proc/loadavg",O_RDONLY);
44  load_fd = open("/proc/stat",O_RDONLY);
45  uptime_fd = open("/proc/uptime",O_RDONLY);
46
47#if 0
48  kversion_fd = open("/proc/sys/kernel/osrelease",O_RDONLY);
49
50  reread(kversion_fd, "main:");
51  sscanf(buffer, "%s", kver);
52
53  close(kversion_fd);
54# endif
55
56  /* Get OS name and version from uname() */
57  if( uname( unamebuf ) != 0 ) {
58    perror( "Error calling uname:" );
59  }
60  strcpy( kver, unamebuf->release );
61  strcpy( sysname, unamebuf->sysname );
62
63  return 0;
64}
65
66void stat_close()
67{
68  close(meminfo_fd);
69  close(loadavg_fd);
70  close(load_fd);
71  close(uptime_fd);
72}
73
74
75static void reread(int f, char *errmsg)
76{
77  if (lseek(f, 0L, 0) == 0 && read(f, buffer, sizeof(buffer) - 1 ) > 0 )
78    return;
79  perror(errmsg);
80  exit(1);
81}
82
83static int getentry(const char *tag, const char *bufptr)
84{
85  char *tail;
86  int retval, len = strlen(tag);
87
88  while (bufptr)
89  {
90    if (*bufptr == '\n') bufptr++;
91    if (!strncmp(tag, bufptr, len))
92    {
93      retval = strtol(bufptr + len, &tail, 10);
94      if (tail == bufptr + len) return -1;
95      else return retval;
96    }
97    bufptr = strchr( bufptr, '\n');
98  }
99  return -1;
100}
101
102static void get_mem_info(struct meminfo *result)
103{
104//  int i, res; char *bufptr;
105
106  reread(meminfo_fd, "get_meminfo:");
107  result[0].total   = getentry("MemTotal:", buffer);
108  result[0].free    = getentry("MemFree:", buffer);
109  result[0].shared  = getentry("MemShared:", buffer);
110  result[0].buffers = getentry("Buffers:", buffer);
111  result[0].cache   = getentry("Cached:", buffer);
112  result[1].total   = getentry("SwapTotal:", buffer);
113  result[1].free    = getentry("SwapFree:", buffer);
114}
115
116static double get_loadavg(void)
117{
118  double load;
119
120  reread(loadavg_fd, "get_load:");
121  sscanf(buffer, "%lf", &load);
122  return load;
123}
124
125static double get_uptime(void)
126{
127  double uptime;
128
129  reread(uptime_fd, "get_uptime:");
130  sscanf(buffer, "%lf", &uptime);
131  return uptime;
132}
133
134static void get_load(struct load * result)
135{
136  static struct load last_load = { 0, 0, 0, 0, 0 }; struct load curr_load;
137
138  reread(load_fd, "get_load:");
139  sscanf(buffer, "%*s %lu %lu %lu %lu\n",
140         &curr_load.user, &curr_load.nice, &curr_load.system, &curr_load.idle);
141  curr_load.total = curr_load.user + curr_load.nice
142                  + curr_load.system + curr_load.idle;
143  result->total  = curr_load.total  - last_load.total;
144  result->user   = curr_load.user   - last_load.user;
145  result->nice   = curr_load.nice   - last_load.nice;
146  result->system = curr_load.system - last_load.system;
147  result->idle   = curr_load.idle   - last_load.idle;
148  last_load.total  = curr_load.total;
149  last_load.user   = curr_load.user;
150  last_load.nice   = curr_load.nice;
151  last_load.system = curr_load.system;
152  last_load.idle   = curr_load.idle;
153}
154
155
156static char tmp[256];
157
158// A couple of tables for later use...
159static char *days[] = {
160  "Sunday,   ",
161  "Monday,   ",
162  "Tuesday,  ",
163  "Wednesday,",
164  "Thursday, ",
165  "Friday,   ",
166  "Saturday, ",
167};
168
169static char *months[] = {
170  "  January",
171  " February",
172  "    March",
173  "    April",
174  "      May",
175  "     June",
176  "     July",
177  "   August",
178  "September",
179  "  October",
180  " November",
181  " December",
182};
183
184
185//////////////////////////////////////////////////////////////////////////
186// CPU screen shows info about percentage of the CPU being used
187//
188int cpu_screen(int rep)
189{
190#undef CPU_BUF_SIZE
191#define CPU_BUF_SIZE 4
192  int i, j, n;
193  float value;
194  static float cpu[CPU_BUF_SIZE + 1][5];// last buffer is scratch
195  struct load load;
196
197
198
199  get_load(&load);
200
201  // Shift values over by one
202  for(i=0; i<(CPU_BUF_SIZE-1); i++)
203    for(j=0; j<5; j++)
204      cpu[i][j] = cpu[i+1][j];
205
206  // Read new data
207  cpu[CPU_BUF_SIZE-1][0] = ((float)load.user / (float)load.total) * 100.0;
208  cpu[CPU_BUF_SIZE-1][1] = ((float)load.system / (float)load.total) * 100.0;
209  cpu[CPU_BUF_SIZE-1][2] = ((float)load.nice / (float)load.total) * 100.0;
210  cpu[CPU_BUF_SIZE-1][3] = ((float)load.idle / (float)load.total) * 100.0;
211  cpu[CPU_BUF_SIZE-1][4] = (((float)load.user + (float)load.system +
212  (float)load.nice) / (float)load.total) * 100.0;
213
214  // Only clear on first display...
215  if(!rep)
216  {
217    lcd.clear();
218    lcd.init_hbar();
219
220    sprintf(tmp, "%c%c CPU LOAD       %c%c", PAD, PAD, PAD, PAD);
221
222    lcd.string(1, 1, tmp);
223    lcd.string(1, 2, "Usr  0.0% Nice  0.0%");
224    lcd.string(1, 3, "Sys  0.0% Idle  0.0%");
225    lcd.string(1, 4, "0%              100%");
226
227    // Make all the same, if this is the first time...
228    for(i=0; i<CPU_BUF_SIZE-1; i++)
229      for(j=0; j<5; j++)
230        cpu[i][j] = cpu[CPU_BUF_SIZE-1][j];
231  }
232
233
234
235  // Average values for final result
236  for(i=0; i<5; i++)
237  {
238    value = 0;
239    for(j=0; j<CPU_BUF_SIZE; j++)
240    {
241      value += cpu[j][i];
242    }
243    value /= CPU_BUF_SIZE;
244    cpu[CPU_BUF_SIZE][i] = value;
245  }
246
247
248  value = cpu[CPU_BUF_SIZE][4];
249  n = (int)(value * 70.0);
250  if (value >= 99.9) { lcd.string(13, 1, " 100%"); }
251  else { sprintf(tmp, "%4.1f%%", value); lcd.string(13, 1, tmp); }
252
253  value = cpu[CPU_BUF_SIZE][0];
254  if (value >= 99.9) { lcd.string(5, 2, " 100%"); }
255  else { sprintf(tmp, "%4.1f%%", value); lcd.string(5, 2, tmp); }
256
257  value = cpu[CPU_BUF_SIZE][1];
258  if (value >= 99.9) { lcd.string(5, 3, " 100%"); }
259  else { sprintf(tmp, "%4.1f%%", value); lcd.string(5, 3, tmp); }
260
261  value = cpu[CPU_BUF_SIZE][2];
262  if (value >= 99.9) { lcd.string(16, 2, " 100%"); }
263  else { sprintf(tmp, "%4.1f%%", value); lcd.string(16, 2, tmp); }
264
265  value = cpu[CPU_BUF_SIZE][3];
266  if (value >= 99.9) { lcd.string(16, 3, " 100%"); }
267  else { sprintf(tmp, "%4.1f%%", value); lcd.string(16, 3, tmp); }
268
269  value = cpu[CPU_BUF_SIZE][4];
270  n = (int)(value * 70.0 / 100.0);
271  lcd.string(1, 4, "0%              100%");
272  lcd.hbar(3, 4, n);
273
274  return 0;
275} // End cpu_screen()
276
277
278
279//////////////////////////////////////////////////////////////////////////
280// Cpu Graph Screen shows a quick-moving histogram of CPU use.
281//
282int cpu_graph_screen(int rep)
283{
284  int i, j, n;
285  float value, maxload;
286#undef CPU_BUF_SIZE
287#define CPU_BUF_SIZE 2
288  static float cpu[CPU_BUF_SIZE + 1];// last buffer is scratch
289  static float cpu_past[LCD_MAX_WIDTH];
290  struct load load;
291  int status=0;
292  char out[LCD_MAX_WIDTH];
293 
294
295
296  get_load(&load);
297
298  // Shift values over by one
299  for(i=0; i<(CPU_BUF_SIZE-1); i++)
300      cpu[i] = cpu[i+1];
301
302  // Read new data
303  cpu[CPU_BUF_SIZE-1] = ((float)load.user + (float)load.system
304                      + (float)load.nice) / (float)load.total;
305
306
307  // Only clear on first display...
308  if(!rep)
309  {
310    lcd.init_vbar();
311
312    // Make all the same, if this is the first time...
313    for(i=0; i<CPU_BUF_SIZE-1; i++)
314        cpu[i] = cpu[CPU_BUF_SIZE-1];
315
316  }
317
318  //lcd.clear();
319  for(i=2; i<=lcd.hgt; i++)
320    lcd.string(1,i,"                    ");
321 
322
323  // Average values for final result
324  value = 0;
325  for(j=0; j<CPU_BUF_SIZE; j++)
326  {
327    value += cpu[j];
328  }
329  value /= (float)CPU_BUF_SIZE;
330  cpu[CPU_BUF_SIZE] = value;
331
332
333  maxload=0;
334  for(i=0; i<lcd.wid-1; i++)
335  {
336    cpu_past[i] = cpu_past[i+1];
337    lcd.vbar(i+1, cpu_past[i]);
338    if(cpu_past[i] > maxload) maxload = cpu_past[i];
339  }
340
341  value = cpu[CPU_BUF_SIZE];
342  n = (int)(value * 8.0 * (float)(lcd.hgt-1));
343
344  cpu_past[lcd.wid-1] = n;
345  lcd.vbar(lcd.wid, cpu_past[lcd.wid-1]);
346
347    sprintf(out, "%c%c CPU GRAPH %c%c%c%c%c%c", PAD,PAD,
348            PAD,PAD,PAD,PAD,PAD,PAD);
349    lcd.string(1,1,out);
350   
351
352
353  if(n > maxload) maxload = n;
354
355  if(cpu_past[lcd.wid-1] > 0 ) status = BACKLIGHT_ON; 
356  if(maxload < 1) status = BACKLIGHT_OFF;
357
358//  return status;
359  return 0;
360} // End cpu_graph_screen()
361
362
363
364//////////////////////////////////////////////////////////////////////
365// Clock Screen displays current time and date...
366//
367// TODO: 24-hour time, if desired.
368int clock_screen(int rep)
369{
370  char hr[8], min[8], sec[8], ampm[8];
371  char day[16], month[16];
372  time_t thetime;
373  struct tm *rtime;
374  int i;
375
376
377  if(!rep)
378  {
379    lcd.clear();
380    sprintf(tmp, "%c%c DATE & TIME %c%c%c%c%c", PAD, PAD, PAD, PAD, PAD, PAD, PAD);
381    lcd.string(1, 1, tmp);
382  }
383
384  time(&thetime);
385  rtime = localtime(&thetime);
386
387  strcpy(day, days[rtime->tm_wday]);
388
389  if (rtime->tm_hour > 12) { i = 1; sprintf(hr, "%02d", (rtime->tm_hour - 12)); }
390  else { i = 0; sprintf(hr, "%02d", rtime->tm_hour); }
391  if(rtime->tm_hour == 12) i=1;
392  sprintf(min, "%02d", rtime->tm_min);
393  sprintf(sec, "%02d", rtime->tm_sec);
394  if (i == 1) { sprintf(ampm, "%s", "P"); }
395  else { sprintf(ampm, "%s", "A"); }
396  if (rep & 1) { sprintf(tmp, "%s:%s:%s%s %s", hr, min, sec, ampm, day); }
397  else { sprintf(tmp, "%s %s %s%s %s", hr, min, sec, ampm, day); }
398
399  strcpy(month, months[rtime->tm_mon]);
400
401  lcd.string(1, 3, tmp);
402
403  sprintf(tmp, "%s %d, %d", month, rtime->tm_mday, (rtime->tm_year + 1900));
404  lcd.string(2, 4, tmp);
405
406  return 0;
407} // End clock_screen()
408
409
410/////////////////////////////////////////////////////////////////////////
411// Mem Screen displays info about memory and swap usage...
412//
413int mem_screen(int rep)
414{
415  int n;
416  struct meminfo mem[2];
417
418
419  if(!rep)
420  {
421    lcd.clear();
422    lcd.init_hbar();
423    sprintf(tmp, "%c%c%c MEM %c%c%c%c SWAP %c%c",
424      PAD,PAD,PAD,PAD,PAD,PAD,PAD,PAD,PAD);
425    lcd.string(1, 1, tmp);
426    lcd.string(9, 2, "Totl");
427    lcd.string(9, 3, "Free");
428    lcd.string(1, 4, "E       F  E       F");
429  }
430
431  get_mem_info(mem);
432  sprintf(tmp, "%6dk", mem[0].total);
433  lcd.string(1, 2, tmp);
434  sprintf(tmp, "%6dk", mem[0].free);
435  lcd.string(1, 3, tmp);
436  sprintf(tmp, "%6dk", mem[1].total);
437  lcd.string(14, 2, tmp);
438  sprintf(tmp, "%6dk", mem[1].free);
439  lcd.string(14, 3, tmp);
440
441// This gives just main memory usage
442//  n = (int)(50.0 - (float)mem[0].free / (float)mem[0].total * 50.0);
443// This uses main + swap usage...
444
445  lcd.string(1, 4, "E       F  E       F");
446
447  n = (int)(35.0 -
448              (float)mem[0].free / (float)mem[0].total
449            * 35.0);
450  lcd.hbar(2, 4, n);
451
452  n = (int)(35.0 -
453              (float)mem[1].free / (float)mem[1].total
454            * 35.0);
455  lcd.hbar(13, 4, n);
456
457
458/*
459  {
460    int i;
461    for(i=0; i<100; i++)
462    {
463      lcd.hbar(1,1,i);
464      lcd.hbar(1,2,i);
465      lcd.hbar(1,3,i);
466      lcd.hbar(1,4,i);
467      usleep(100000);
468    }
469  }
470*/
471
472  return 0;
473} // End mem_screen()
474
475
476////////////////////////////////////////////////////////////////////
477// Uptime Screen shows info about system uptime and OS version
478//
479int uptime_screen(int rep)
480{
481  int i;
482  char date[16], hour[8], min[8], sec[8];
483  double uptime;
484
485
486  if(!rep)
487  {
488    lcd.clear();
489    sprintf(tmp, "%c%c SYSTEM UPTIME %c%c%c", PAD, PAD, PAD, PAD, PAD);
490    lcd.string(1, 1, tmp);
491
492    sprintf(tmp, "%s %s", sysname, kver);
493    lcd.string(5, 4, tmp);
494  }
495
496  uptime = get_uptime();
497  i = (int)uptime / 86400;
498  sprintf(date, "%d day%s,", i, (i != 1 ? "s" : ""));
499  i = ((int)uptime % 86400) / 60 / 60;
500  sprintf(hour, "%02i",i);
501  i = (((int)uptime % 86400) % 3600) / 60;
502  sprintf(min, "%02i",i);
503  i = ((int)uptime % 60);
504  sprintf(sec, "%02i",i);
505  if (rep & 1)
506    sprintf(tmp, "%s %s:%s:%s", date, hour, min, sec);
507  else
508    sprintf(tmp, "%s %s %s %s", date, hour, min, sec);
509  i = ((20 - strlen(tmp)) / 2) + 1;
510  lcd.string(i, 3, tmp);
511
512
513  return 0;
514} // End uptime_screen()
515
516
517///////////////////////////////////////////////////////////////////////////
518// Shows a display very similar to "xload"'s histogram.
519//
520
521int xload_screen(int rep)
522{
523  static float loads[LCD_MAX_WIDTH];
524  static int first_time=1;
525  int n;
526  float loadmax=0, factor, x;
527  int status = 0;
528
529 
530  if(first_time)  // Only the first time this is ever called...
531  {
532    memset(loads, 0, sizeof(float)*LCD_MAX_WIDTH);
533    first_time = 0;
534  }
535
536  if(!rep)
537  {
538    lcd.clear();
539  }
540
541
542  for(n=0; n<(lcd.wid-2); n++) loads[n] = loads[n+1];
543  loads[lcd.wid-2] = get_loadavg();
544
545  for(n=0; n<lcd.wid-1; n++)
546    if(loads[n] > loadmax) loadmax = loads[n];
547
548  lcd.string(20, 4, "0");
549  n = (int)loadmax;
550  if ((float)n < loadmax) { n++; }
551  sprintf(tmp, "%i", n); lcd.string(20, 2, tmp);
552
553  if (loadmax < 1.0) factor = 24.0;
554  else factor = 24 / (float)n;
555
556  for(n=0; n<lcd.wid-1; n++)
557  {
558    x = (loads[n] * factor);
559    lcd.vbar(n+1, (int)x);
560  }
561
562  if(loadmax < 0.05) status = BACKLIGHT_OFF;
563  if(loadmax > 0.05) status = BACKLIGHT_ON;
564  if(loads[lcd.wid-2] > LOAD_THRESHOLD) status = BLINK_ON;
565
566  // This must be drawn *after* the vertical bars...  (?)
567  sprintf(tmp, "%c%c LOAD AVG %2.2f %c%c", PAD, PAD, loads[lcd.wid-2], PAD, PAD);
568  lcd.string(1, 1, tmp);
569
570  if(!rep)
571    lcd.init_vbar();
572
573
574  return status;
575} // End xload_screen()
576
577
578
579////////////////////////////////////////////////////////////////////////
580// Credit Screen shows who wrote this...
581//
582int credit_screen(int rep)
583{
584
585  if(!rep)
586  {
587    lcd.clear();
588    sprintf(tmp, "%c%c LCDPROC %s %c%c%c%c",
589            PAD, PAD, version, PAD, PAD, PAD, PAD);
590    lcd.string(1, 1, tmp);
591    lcd.string(1, 2, "     for Linux      ");
592    lcd.string(1, 3, " by William Ferrell ");
593    lcd.string(1, 4, " and Scott Scriven  ");
594  }
595
596  return 0;
597} // End credit_screen()
598
599
600//////////////////////////////////////////////////////////////////////
601// This is mostly for debugging.  It should never show up.
602//
603int dumbass_screen(int rep)
604{
605
606  lcd.string(1,1, "---=== Haha... ==---");
607  lcd.string(1,2, "  You specified an  ");
608  lcd.string(1,3, "   INVALID MODE!!!  ");
609  lcd.string(1,4, "---== Ya LOSER! ==--");
610/*
611  lcd.string(1,1, "--===GO AWAY!!!===--");
612  lcd.string(1,2, "   You're a slimy,  ");
613  lcd.string(1,3, "     mold-ridden    ");
614  lcd.string(1,4, "      pop-tart!     ");
615*/
616
617  return BLINK_ON;
618}
619
620
621//////////////////////////////////////////////////////////////////////////
622// This gets called upon program exit, to say "goodbye"
623//
624int goodbye_screen(int rep)
625{
626
627  lcd.clear();
628/*
629  lcd.string(1,1, "---===SHUTDOWN===---");
630  lcd.string(1,2, "    DANGER, WILL    ");
631  lcd.string(1,3, "      ROBINSON!     ");
632  lcd.string(1,4, "---===EJECT!!!===---");
633  usleep(250000);
634*/
635
636  lcd.string(1,1, "                    ");
637  lcd.string(1,2, "  Thanks for using  ");
638  lcd.string(1,3, " LCDproc and Linux! ");
639  lcd.string(1,4, "                    ");
640
641  return 0;
642}
643
644
Note: See TracBrowser for help on using the repository browser.