#include <X11/Intrinsic.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#include <math.h>

#ifndef SEEK_END
#define SEEK_END 2
#endif

extern void GetLoadPoint();

extern char *ProgramName;

static FILE *fp, *fpo;
static int avgB[8], avgC[8], iavg = -1, totavgB, totavgC;

void GetLoadPointA( w, closure, call_data )
     Widget	w;		/* unused */
     caddr_t	closure;	/* unused */
     caddr_t	call_data;	/* pointer to (double) return value */
{
  GetLoadPoint(w, closure, call_data);
  fprintf(fpo, "%lu %lf %lf %lf\n", time(0), *(double*)call_data,
	  (double)totavgB/80.0, (double)totavgC/800000.0);
  fflush(fpo);
}

void InitLoadPointBC(void)
{
  fp = fopen("/var/local/www/logs/xload2.pid", "w");
  fprintf(fp, "%lu\n", getpid());
  fclose(fp);
  fpo = fopen("/var/local/www/logs/xload2.log", "a");
  if (!(fp = fopen("/var/local/www/logs/access_log","r")))
  {
    fprintf(stderr,
	    "%s: can't open /var/local/www/logs/access_log for reading\n",
	    ProgramName);
    exit(1);
  }
  fseek(fp, 0L, SEEK_END);
}

void GetLoadPointB( w, closure, call_data )
     Widget	w;		/* unused */
     caddr_t	closure;	/* unused */
     caddr_t	call_data;	/* pointer to (double) return value */
{
  double *ret = (double *)call_data;
  int ch, space=0, i=0, lines = 0;
  char circbuf[16];
  long bytes = 0;

  clearerr(fp);
  while ((ch = getc(fp)) != EOF)
  {
    if (ch == ' ' && space==4)
    {
      circbuf[i] = 0;
      bytes += atol(circbuf);
      space=0;
      lines++;
    }
    else if (ch == '"') {
	 space++;
	 i = 0;
    }
    else if (ch == ' ' && space>=2){
	 space++;
	 i=0;
    }
    else if (ch == '\n'){
	 space=0;
    }
    else
    {
      circbuf[i] = ch;
      i = (i+1) & 0x0f;
    }
  }
  if (iavg == -1)
  {
    for (iavg = 0; iavg < 8; iavg++)
    {
      avgB[iavg] = lines;
      avgC[iavg] = bytes;
    }
    totavgB = lines << 3;
    totavgC = bytes << 3;
    iavg = 0;
  }
  else
  {
    totavgB -= avgB[iavg];
    avgB[iavg] = lines;
    totavgB += lines;
    totavgC -= avgC[iavg];
    avgC[iavg] = bytes;
    totavgC += bytes;
    iavg = (iavg+1) & 7;
  }
  *ret = (double)totavgB / 80.0;
}

void GetLoadPointC( w, closure, call_data )
     Widget	w;		/* unused */
     caddr_t	closure;	/* unused */
     caddr_t	call_data;	/* pointer to (double) return value */
{
  *(double *)call_data = 3.0 * log(((double)totavgC / 800000.0) + 1.0);
}
