/*
 * $Id: statlist.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 eval_filestuff();
void eval_ipcstuff();
void eval_proc_loadavg();
void eval_proc_lm78();
void eval_proc_meminfo();
void eval_proc_net_dev();
void eval_proc_sensors();
void eval_proc_stat();
void eval_proc_uptime();
void eval_time();
void eval_users();
void get_ipcstuff();
void get_proc_lm78();
void get_proc_loadavg();
void get_proc_meminfo();
void get_proc_net_dev();
void get_proc_sensors();
void get_proc_stat();
void get_proc_uptime();
void get_filestuff();
void get_time();
void get_users();
void init_filestuff();
void init_identity();
void init_proc_lm78();
void init_proc_loadavg();
void init_proc_meminfo();
void init_proc_net_dev();
void init_proc_sensors();
void init_proc_stat();
void init_proc_uptime();
void init_proc_version();
void init_time();
void init_users();
void init_ipcstuff();

/*
 * statlist routines are simple shells that initialize, retrieve, process,
 * and transmit statistics derived from /proc/* or various systems calls.
 * This program component contains none of the actual code for handling a
 * particular statistics family.  All code for a particular statistic can be
 * found in e.g. proc_stat, proc_meminfo, etc.  This should make it 
 * RELATIVELY easy to add, for example, a new statistic or information on 
 * running processes to the bundle of things being transmitted because one 
 * can work on the code associated with each statistic in isolation
 * following a fairly simple presentation format) without touching or 
 * breaking the working routines -- only small, obvious changes to 
 * the subroutines below should be necessary to add a new statistic.
 *
 * We can thus add a statistic as an "object", sort of, although homie 
 * don't do c++.  Adding a statistic ALSO should not break applications
 * that talk to the daemons or read the broadcast information, if they
 * simply parse the information they get and ignore either extra fields
 * or missing fields.
 *
 * Note, the API of the data portion of the transmitted packet(s), such as 
 * it is, is basically defined below.  Eventually it will be codified and
 * described in detail in README.API, but not until we are at least in
 * some sort of beta...
 */


/*
 * init_statlist goes through all the sources listed in Sources,
 * determines which of these sources are available, and verifies that
 * the data therein can be extracted and stored in the current/previous
 * vectors.  These Sources are basically classes; this can be thought
 * of as a constructor that initializes the structures that are the
 * objects associated with a Source if possible.
 */

void init_statlist()
{

 /* IDENT */
 init_identity();
 /* PROC_VERSION */
 init_proc_version();
 /* PROC_STAT */
 init_proc_stat();
 /* PROC_LOADAVG */
 init_proc_loadavg();
 /* PROC_MEMINFO */
 init_proc_meminfo();
 /* PROC_NETDEV */
 init_proc_net_dev();
 /* PROC_LM78 */
 init_proc_lm78();
 /*
  * Only need to check for PROC_SENSORS if PROC_LM78 failed.
  */
 if(!stat_fd[PROC_LM78]){
   /* PROC_SENSORS */
   init_proc_sensors();
 }
 /* PROC_UPTIME */
 init_proc_uptime();
 /* TIME */
 init_time();
 /* USERS */
 init_users();

 /* IPC */
 init_ipcstuff();

 /* File system checks */
 init_filestuff();

} /* End init_statlist() */


/*
 * get_statlist goes through all the initialized sources that have
 * proven to be available, retrieves their current value(s), and puts
 * the values into the object/structure for the source.  This
 * would be a "method" if this were really object oriented.  Note also
 * the interval timestamp -- this is used to evaluate rates.
 */

void get_statlist()
{

 int i,numfields;
 static int cur_time,prev_time;

 /* 
  * Set the global interval for use in evaluating rates below. 
  */
 cur_time = (long) time(NULL);
 interval=(cur_time - prev_time);
 prev_time = cur_time;

 /*
  * I should probably wrap all of these in conditionals to ensure that
  * the file descriptors exist before wasting time trying to collect
  * data that may not be there, but almost all of them are "sure" to
  * exist on a 2.0.X system (all that is currently supported).
  */

 /* Get PROC_STAT stats */
 get_proc_stat();
 /* Get PROC_LOADAVG stats */
 get_proc_loadavg();
 /* Get PROC_MEMINFO stats */
 get_proc_meminfo();
 /* Get PROC_NET_DEV stats */
 get_proc_net_dev();
 if(stat_fd[PROC_LM78]){
   /* Get PROC_LM78 stats */
   get_proc_lm78();
 }
 else if(stat_fd[PROC_SENSORS]){
  /* Get PROC_SENSORS stats */
   get_proc_sensors();
 }
 /* Get PROC_UPTIME stats */
 get_proc_uptime();
 /* Get TIME stats */
 get_time();
 /* Get USERS stats */
 get_users();

 /* IPC */
 get_ipcstuff();

 /* File system checks */
 get_filestuff();

} /* End get_statlist */

/*
 * Once get_statlist has obtained the raw values from the available
 * Sources and set the interval between the current call and the
 * previous call, eval_statlist derives the statistics and sets the rates
 * as necessary.  EACH eval_XXX routine is also responsible for APPENDING
 * its results onto the "results" buffer for transmission or return.
 * That way all the Source-dependent work for a given Source is done in
 * the software source file for the statistics Source.
 */

void eval_statlist()
{

 int i,numfields;

 /* Evaluate all the statistics in /proc/stat */
 eval_proc_stat();
 /* Evaluate all the statistics in /proc/loadavg */
 eval_proc_loadavg();
 /* Evaluate all the statistics in /proc/meminfo */
 eval_proc_meminfo();
 /* Evaluate all the statistics in /proc/net_dev */
 eval_proc_net_dev();
 if(stat_fd[PROC_LM78]){
   /* Evaluate all the statistics in /proc/sys/dev/lm78 */
   eval_proc_lm78();
 } else if(stat_fd[PROC_SENSORS]){
   /* Evaluate all the statistics in /proc/sensors */
   eval_proc_sensors();
 }
 /* Evaluate all the statistics in /proc/uptime */
 eval_proc_uptime();
 /* Evaluate the node/client time */
 eval_time();
 /* Evaluate the node/client number of users */
 eval_users();

 /* IPC */
 eval_ipcstuff();

 /* File system checks */
 eval_filestuff();

} /* End eval_statlist */


