/*
 * $Id: proc_sensors.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"

void init_proc_sensors()
{

 int i,numfields;

 /* 
  * There can be SEVERAL possible locations for temperature (the only
  * sensor field we monitor at this moment).  We therefore have to check
  * for them one at a time.  However, the code for parsing the TEMP field
  * is pretty different at this moment, so we put it in two different
  * source modules, proc_sensors.c (this one) and proc_lm78.c.  Only 
  * (at most) one of the two will yield fruit, of course, but it doesn't
  * matter which order they are checked.  We'll put a small conditional
  * in the statlist code to keep the actual updates reasonably efficient.
  */
 stat_fd[PROC_SENSORS] = fopen("/proc/sensors","r");

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

   while(TRUE){
     /* Normal EOF causes break from while loop */
     if((fgets(statbuf,BUFLEN,stat_fd[PROC_SENSORS]) == NULL)) break;
     /* parse the line into fields */
     numfields = parse(statbuf,fields,MAXFIELDNUMBER,BUFLEN);

     /* TEMP */
     if(strncmp(fields[0],"Mainboard:",10) == 0){
       /* TEMP */
       sprintf(stats[TEMP].name,"temp_sensors");	/* Label it. */
       stats[TEMP].source = PROC_SENSORS;		/* Tag its source for xref */
       stats[TEMP].avail = 1;			/* Yes, we found it */
       stats[TEMP].current = atof(fields[1]);	/* current value */
     } /* End TEMP */
   } /* End while(true) */
 }

} /* End init_proc_sensors() */

void get_proc_sensors()
{

 int i,numfields;

 /* 
  * Now, for a clever trick.  We'll reset the files without actually
  * closing or reopening them.  Perhaps we can save the overhead of
  * an open/close (presumed relatively large, as one has to stat the
  * files in question on EACH open).
  */

 errno = 0;
 if(stat_fd[PROC_SENSORS]){
    rewind(stat_fd[PROC_SENSORS]);	/* void, so tough to check errors */
 } else {
    return;
 }
 if(errno == EBADF){
   if(daemonmode == FORK) fprintf(stderr,"Error: The /proc/sensors file descriptor/stream is not seekable.\n");
   if(daemonmode == FORK) fprintf(stderr,"Closing and reopening /proc/sensors.\n");
   fclose(stat_fd[PROC_SENSORS]); 
   stat_fd[PROC_SENSORS] = fopen("/proc/sensors","r");
 }

 while(TRUE){
   /* Normal EOF causes break from while loop */
   if((fgets(statbuf,BUFLEN,stat_fd[PROC_SENSORS]) == NULL)) break;
   /* parse the line into fields */
   numfields = parse(statbuf,fields,MAXFIELDNUMBER,BUFLEN);

   /* TEMP */
   if(strncmp(fields[0],"Mainboard:",10) == 0){
     /* TEMP */
     stats[TEMP].previous = stats[TEMP].current;	/* previous value */
     stats[TEMP].current = atof(fields[1]);	/* current value */
   } /* End TEMP */
 } /* End while(true) */

} /* End get_proc_sensors() */

void eval_proc_sensors()
{

 int i,numfields;


 for(i=0;i<N_STATS;i++){

   switch(i) {
     /* 
      * TEMP (the only sensor value monitored if available so far, sorry)
      * is a straight value.
      */
     case TEMP:
       stats[i].rate = stats[i].current;
       if(stats[i].rate < 0.0) stats[i].rate = 0.0;
       break;
     default:
       break;
   } /* End case switch */

 } /* End loop through enumerated types */

} /* End eval_proc_sensors() */
