/*
 * $Id: proc_loadavg.c,v 1.1 2001/03/15 22:16:13 jpormann Exp jpormann $
 *
 * procstatd - Copyright (c) 1999 by Robert G. Brown, rgb@phy.duke.edu
 *         GPL version 2b (b for beverage) granted.
 *
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 *
 * procstatd - A daemon to extract statistics from /proc/stat and publish them
 *         on demand via a socket connection or broadcast.
 */

#include "procstatd.h"

/*
 * All code to handle PROC_LOADAVG
 */

void init_proc_loadavg()
{

 int i,numfields;

 /* 
  * Open /proc/loadavg.
  */
 stat_fd[PROC_LOADAVG] = fopen("/proc/loadavg","r");

 /*
  * If the open succeeded, the file descriptor is nonzero.  We then
  * initialize all stats derived from /proc/loadavg.  Put values into
  * stats[FIELD].{name,source,avail,current,previous,rate}
  */

 /* /proc/loadavg */
 if(stat_fd[PROC_LOADAVG]){
   /* Only contains one line, so not much to parse */
   fgets(statbuf,BUFLEN,stat_fd[PROC_LOADAVG]);
   /* parse the line into fields */
   numfields = parse(statbuf,fields,MAXFIELDNUMBER,BUFLEN);

   /* LOAD1 */
   sprintf(stats[LOAD1].name,"load1");		/* Label it. */
   stats[LOAD1].source = PROC_LOADAVG;		/* Tag its source for xref */
   stats[LOAD1].avail = 1;			/* Yes, we found it */
   stats[LOAD1].current = atof(fields[0]);	/* current value */
   /* LOAD5 */
   sprintf(stats[LOAD5].name,"load5");		/* Label it. */
   stats[LOAD5].source = PROC_LOADAVG;		/* Tag its source for xref */
   stats[LOAD5].avail = 1;			/* Yes, we found it */
   stats[LOAD5].current = atof(fields[1]);	/* current value */
   /* LOAD15 */
   sprintf(stats[LOAD15].name,"load15");	/* Label it. */
   stats[LOAD15].source = PROC_LOADAVG;		/* Tag its source for xref */
   stats[LOAD15].avail = 1;			/* Yes, we found it */
   stats[LOAD15].current = atof(fields[2]);	/* current value */

 }

} /* End init_proc_loadavg.  Leave stat_fd[PROC_LOADAVG] open */

/* Get PROC_LOADAVG stats */
void get_proc_loadavg()
{

 int i,numfields;

 errno = 0;
 if(stat_fd[PROC_LOADAVG]){
   /* 
    * For no good reason that I can see, a one line /proc file won't rewind
    * correctly.  So we close and reopen it.
    */
   fclose(stat_fd[PROC_LOADAVG]); 
   stat_fd[PROC_LOADAVG] = fopen("/proc/loadavg","r");
 } else {
   return;
 }

 /* Only contains one line, so not much to parse */
 fgets(statbuf,BUFLEN,stat_fd[PROC_LOADAVG]);

 /* parse the line into fields */
 numfields = parse(statbuf,fields,MAXFIELDNUMBER,BUFLEN);

 /* LOAD1 */
 stats[LOAD1].previous = stats[LOAD1].current;	/* previous value */
 stats[LOAD1].current = atof(fields[0]);	/* current value */
 /* LOAD5 */
 stats[LOAD5].previous = stats[LOAD5].current;	/* previous value */
 stats[LOAD5].current = atof(fields[1]);	/* current value */
 /* LOAD15 */
 stats[LOAD15].previous = stats[LOAD15].current;	/* previous value */
 stats[LOAD15].current = atof(fields[2]);	/* current value */

} /* End of get_proc_loadavg() */


/*
 * I'm leaving a loop through all enumerated types in places like this
 * (for now) even though it would be faster to just put in the only
 * three hits inline and skip the loop and case switch.  This is to
 * make it really easy to turn this whole thing into real OO code (or
 * move the ordinary code even further toward OO structure).  I could
 * define a "method" for evaluating stats[OBJ].rate, for example, that
 * worked for all the different "kinds" of rates (since basically either
 * the raw value or the interval rate is returned for everything but e.g.
 * users and time).  Wastes a bit of time, but I think that this code is
 * really pretty cheap anyway and can afford it during development...
 */

void eval_proc_loadavg()
{

 stats[LOAD1].rate = stats[LOAD1].current;
 stats[LOAD5].rate = stats[LOAD5].current;
 stats[LOAD15].rate = stats[LOAD15].current;

} /* End eval_proc_loadavg() */
