/* loadavgLED.c -- show loadaverage in RS 6000 3 digit LED display
 *
 * Copyright 1994 Jussi M{ki. All Rights reserved.
 * NON-COMMERCIAL USE ALLOWED. YOU MAY USE, COPY AND DISTRIBUTE 
 * THIS PROGRAM FREELY AS LONG AS ORIGINAL COPYRIGHTS ARE LEFT
 * AS THEY ARE.
 */

#include <fcntl.h>
#include <signal.h>

static int nvram_fd = -1;

/* in case of signal, clear LED and exit gracefully */
sighandler(int signum)
{
  printf("signal %d occured\n",signum);
  ioctl (nvram_fd, 0xc, 0xfff);
  printf("Clearing 3 digit LED display, exiting...\n");
  exit(1);
}


main(argc,argv)
int argc;
char *argv[];
{
  double loadavgs[3];
  signal(SIGHUP, sighandler);
  signal(SIGINT, sighandler);
  signal(SIGTERM, sighandler);
  signal(SIGQUIT, sighandler);
  /* After AIX 3.2.5 one has to use /dev/nvram instead of /dev/nvram/0 
   */
  if ((nvram_fd = open("/dev/nvram", O_RDONLY))==-1)
    nvram_fd = open("/dev/nvram/0", O_RDONLY);

  while (1) {
    getloadavg(loadavgs, 3);
    display_loadavg(loadavgs[0]);
    sleep(10);
  }
}

display_loadavg(double loadavg1)
{
  int x;
  static int led_point=0xa;

  if (nvram_fd < 0)
    return;

#ifdef ORIGINAL_LED
  x = (int)(loadavg1*100.0);
#ifdef DEBUG
  fprintf (stderr, "loadavg = %3.5f\n", loadavg1);
  fprintf (stderr, "x = %d\n", x);
#endif
  if (x >= 1000)
    x = 0x999;
  else
    x = (x%10) | (((x/10)%10)<<4) | ((x/100)<<8);
#else
  x = (int)(loadavg1*100.0);

  if (loadavg1<1.0) { x = (led_point<<8) | (((x/10)%10)<<4) | (x%10);    }
  else if (loadavg1<10.0) { x= ((x/100)<<8) | (led_point<<4) | ((x/10)%10); }
  else if (loadavg1<100.0) { x=((x/1000)<<8 | ((x/100)%10)<<4) | (led_point);}
  else x = 0x990|led_point;
  led_point = (led_point==0xa)?0xb:0xa;
#endif
#ifdef DEBUG
  fprintf (stderr, "y = %x\n", x);
#endif
  ioctl (nvram_fd, 0xc, x);
}

