/*
 * $Id: proc_lm78.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_lm78()
{

 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_lm78.c (this one) and proc_sensors.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_LM78] = fopen("/proc/sys/dev/lm78/status/temperature","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/sys/dev/lm78/status/temperature */
 if(stat_fd[PROC_LM78]){

   /*
    * If the file exists, its single content is all we want.  This
    * simplifies life.
    */

   /* Get the line... */
   if((fgets(statbuf,BUFLEN,stat_fd[PROC_LM78]) == NULL)){
      /*
       * We need to do a LOT more of this error checking and wrapping,
       * and to install a logger alternative for inetd or multicast
       * operation during beta.
       */
      if(daemonmode == FORK) fprintf(stderr,"Error:  /proc/sys/dev/lm78/status/temperature exists but is empty.\n");
   }
   /* ...parse the line into fields... */
   numfields = parse(statbuf,fields,MAXFIELDNUMBER,BUFLEN);

   /* TEMP */
   sprintf(stats[TEMP].name,"lm78temp");	/* Label it. */
   stats[TEMP].source = PROC_LM78;		/* Tag its source for xref */
   stats[TEMP].avail = 1;			/* Yes, we found it */
   stats[TEMP].current = atof(fields[0]);	/* current value */
 }

} /* End init_proc_lm78() */

void get_proc_lm78()
{

 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_LM78]){
    rewind(stat_fd[PROC_LM78]);	/* void, so tough to check errors */
 } else {
    return;
 }
 if(errno == EBADF){
   fprintf(stderr,"Error: The /proc/sys/dev/lm78/status/temperature descriptor/stream is not seekable.\n");
   fclose(stat_fd[PROC_LM78]); 
   fprintf(stderr,"Closing and reopening /proc/sys/dev/lm78/status/temperature.\n");
   stat_fd[PROC_LM78] = fopen("/proc/sys/dev/lm78/status/temperature","r");
 }

 /* Get line... */
 if((fgets(statbuf,BUFLEN,stat_fd[PROC_LM78]) == NULL)){
   /*
    * We need to do a LOT more of this error checking and wrapping,
    * and to install a logger alternative for inetd or multicast
    * operation during beta.
    */
   if(daemonmode == FORK) fprintf(stderr,"Error:  /proc/sys/dev/lm78/status/temperature exists but is empty.\n");
 }
 /* ...parse the line into fields... */
 numfields = parse(statbuf,fields,MAXFIELDNUMBER,BUFLEN);

 /* TEMP */
 stats[TEMP].previous = stats[TEMP].current;	/* previous value */
 stats[TEMP].current = atof(fields[0]);	/* current value */

} /* End get_proc_lm78() */

void eval_proc_lm78()
{


 /* 
  * For single values we skip the loop/switch.  See proc_stats.c for
  * a loop template in the event that there are lots of values
  * to be added to this source module (like the PS voltages or
  * individual CPU fan speeds or temperatures).
  */
 stats[TEMP].rate = stats[TEMP].current;

} /* End eval_proc_lm78() */
