#include <gxsnmp_smux.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#define TESTMIB 1,3,6,1,4,1,3317,3,1,1
#define LINUXMIB 1,3,6,1,4,1,1575,1,5,2

gulong testoid [] = { TESTMIB };
gulong linuxoid [] = { LINUXMIB };

static unsigned char * linux_objects();

#define LINUXCPU                         1
#define LINUXBOGO                        2
#define LINUXLOADAVG1                    3
#define LINUXLOADAVG5                    4
#define LINUXLOADAVG15                   5

struct gxsnmp_variable linux_variables[] = {
    { LINUXCPU, SNMP_OCTETSTR, RONLY, linux_objects, 1, {1} },
    { LINUXBOGO, SNMP_INTEGER, RONLY, linux_objects, 1, {2} },
    { LINUXLOADAVG1, SNMP_INTEGER, RONLY, linux_objects, 1, {3} },
    { LINUXLOADAVG5, SNMP_INTEGER, RONLY, linux_objects, 1, {4} },
    { LINUXLOADAVG15, SNMP_INTEGER, RONLY, linux_objects, 1, {5} },
};

static unsigned char *
linux_objects(struct gxsnmp_variable *vp,
  gulong        *name,
  guint         *length,
  gboolean       exact,
  guint         *var_len,
  GxsnmpPutVar **write_method)
{
  char buffer [4096], *p;
  int fd, len, i;
  static gulong linuxBogo;
  static gulong linuxLoadAvg1;
  static gulong linuxLoadAvg5;
  static gulong linuxLoadAvg15;
  static gchar  linuxCPU[255];

  if (gxsnmp_header_generic(vp, name, length, exact, var_len, write_method)
    == FALSE)
    return NULL;

  fd = open ("/proc/loadavg", O_RDONLY);
  len = read (fd, buffer, sizeof(buffer)-1);
  close (fd);

  if (len>0)
    {
      buffer[len]=0;
      linuxLoadAvg1 = (float) strtod (buffer, &p) * 100 + 0.5;
      linuxLoadAvg5 = (float) strtod (p, &p) * 100 + 0.5;
      linuxLoadAvg15 = (float) strtod (p, &p) * 100 + 0.5;
    }

  fd = open ("/proc/cpuinfo", O_RDONLY);
  len = read (fd, buffer, sizeof(buffer)-1);
  close (fd);

  if (len>0)
    {
      buffer[len]=0;
      p = strstr(buffer, "model name");
      if (p)
        {
	  p += sizeof("model name");
          while(*p == ' ' || *p == '\t') p++;
          if (*p == ':')
            {
              p++;
              while(*p == ' ' || *p == '\t') p++;
	      i = 0;
              while(*p != '\n' && i < sizeof(linuxCPU))
		linuxCPU[i++] = *p++;
	      linuxCPU[i] = 0;
	    }
	}
      p = strstr(buffer, "bogomips");
      if (p)
        {
	  p += sizeof("bogomips");
          while(*p == ' ' || *p == '\t') p++;
          if (*p == ':')
            {
              p++;
              while(*p == ' ' || *p == '\t') p++;
              linuxBogo = (float) strtod (p, &p) + 0.5;
	    }
	}
    }
  switch (vp->magic)
    {
      case LINUXCPU:
        *var_len = strlen(linuxCPU);
        return (unsigned char *) linuxCPU;

      case LINUXBOGO:
        return (unsigned char *) &linuxBogo;

      case LINUXLOADAVG1:
        return (unsigned char *) &linuxLoadAvg1;

      case LINUXLOADAVG5:
        return (unsigned char *) &linuxLoadAvg5;

      case LINUXLOADAVG15:
        return (unsigned char *) &linuxLoadAvg15;

      default:
        return NULL;
    }
  return NULL;
}

void main()
{
  GxsnmpSmux *smux;
  GMainLoop  *loop;

  smux = gxsnmp_smux_new();
  gxsnmp_smux_connect(smux, "localhost", testoid, 
		sizeof(testoid)/sizeof(gulong), "pass");
  gxsnmp_smux_register(smux, linux_variables,
		sizeof(struct gxsnmp_variable),
		sizeof(linux_variables)/sizeof(struct gxsnmp_variable),
		linuxoid, sizeof(linuxoid)/sizeof(gulong));
  loop = g_main_new(TRUE);
  while(g_main_is_running(loop))
    g_main_run(loop);
  gxsnmp_smux_destroy(smux);
}
