/****************************************************************************
   Program:     $Id: rtg.h,v 1.20 2003/09/25 15:56:04 rbeverly Exp $ 
   Author:      $Author: rbeverly $
   Date:        $Date: 2003/09/25 15:56:04 $
   Description: RTG headers
****************************************************************************/

#ifndef _RTG_H_
#define _RTG_H_ 1

/* Defines */ 
#ifndef FALSE
# define FALSE 0
#endif
#ifndef TRUE
# define TRUE !FALSE
#endif

/* Constants */
#define MAX_THREADS		10
#define BUFSIZE			512
#define BITSINBYTE		8
#define THIRTYTWO		4294967295ul
#define SIXTYFOUR		18446744073709551615ul

/* Define CONFIG_PATHS places to search for the rtg.conf file.  Note
   that RTG_HOME, as determined during autoconf is one path */
#define CONFIG_PATHS		4
#define CONFIG_PATH_1		"/etc/rtg/"
#define CONFIG_PATH_2		""

/* Defaults */
#define DEFAULT_CONF_FILE	"rtg.conf"
#define DEFAULT_THREADS		5
#define DEFAULT_INTERVAL	300
#define DEFAULT_HIGHSKEWSLOP	3
#define DEFAULT_LOWSKEWSLOP	.5
#define DEFAULT_OUT_OF_RANGE	900000000000ull
#define DEFAULT_DB_HOST		"localhost"
#define DEFAULT_DB_PORT		3306
#define DEFAULT_DB_DB		"rtg"
#define DEFAULT_DB_USER		"snmp"
#define DEFAULT_DB_PASS		"rtgdefault"
#define DEFAULT_SNMP_VER	2
#define DEFAULT_SNMP_PORT	161
#define DEFAULT_PIDFILE		"/tmp/rtgpoll.pid"

#define STAT_DESCRIP_ERROR	99
#define HASHSIZE		5000

/* pthread error messages */
#define PML_ERR			"pthread_mutex_lock error\n"
#define PMU_ERR			"pthread_mutex_unlock error\n"
#define PCW_ERR			"pthread_cond_wait error\n"
#define PCB_ERR			"pthread_cond_broadcast error\n"

/* pthread macros */
#define PT_MUTEX_LOCK(x)	if (pthread_mutex_lock(x) != 0) printf(PML_ERR);
#define PT_MUTEX_UNLOCK(x)	if (pthread_mutex_unlock(x) != 0) printf(PMU_ERR);
#define PT_COND_WAIT(x,y)	if (pthread_cond_wait(x, y) != 0) printf(PCW_ERR);
#define PT_COND_BROAD(x)	if (pthread_cond_broadcast(x) != 0) printf(PCB_ERR);

/* Verbosity levels LOW=info HIGH=info+SQL DEBUG=info+SQL+junk */
enum debugLevel
{
	OFF,
	LOW,
	HIGH,
	DEBUG,
	DEVELOP
}; 

/* Target state */
enum targetState
{
	NEW,
	LIVE,
	STALE
};

/* Typedefs */
typedef struct worker_struct
{
	int			index;
	pthread_t		thread;
	struct crew_struct	*crew;
} worker_t;

typedef struct config_struct
{
	unsigned int		interval;
	unsigned long long	out_of_range;
	char			dbhost[80];
	unsigned int		dbport;
	char			dbdb[80];
	char			dbuser[80];
	char			dbpass[80];
	enum debugLevel		verbose;
	unsigned short		withzeros;
	unsigned short		dboff;
	unsigned short		multiple;
	unsigned short		snmp_ver;
	unsigned short		snmp_port;
	unsigned short		threads;
	float			highskewslop;
	float			lowskewslop;
	unsigned short		update_desc;
} config_t;

typedef struct target_struct
{
	char			host[64];
	unsigned int		port;
	char			objoid[128];
	unsigned short		bits;
	char			community[64];
	char			table[64];
	unsigned int		iid;
#ifdef HAVE_STRTOLL
	long long		maxspeed;
#else
	long			maxspeed;
#endif
	enum targetState	init;
	unsigned long long	last_value;
	struct target_struct	*next;
} target_t;

typedef struct crew_struct
{
	int			work_count;
	worker_t		member[MAX_THREADS];
	pthread_mutex_t		mutex;
	pthread_cond_t		done;
	pthread_cond_t		go;
} crew_t;

typedef struct poll_stats
{
	pthread_mutex_t		mutex;
	unsigned long long	polls;
	unsigned long long	db_inserts;
	unsigned int		round;
	unsigned int		wraps;
	unsigned int		no_resp;
	unsigned int		out_of_range;
	unsigned int		errors;
	unsigned int		slow;
	double			poll_time; 
} stats_t;

typedef struct hash_struct
{
	target_t		*table[HASHSIZE];
	int			bucket;
	target_t		*target;
} hash_t;

/* Precasts: rtgpoll.c */
void *sig_handler(void *);
void usage(char *);

/* Precasts: rtgpoll.c */
void *poller(void *);

/* Precasts: rtgmysql.c */
int db_insert(char *, MYSQL *);
int rtg_dbconnect(char *, MYSQL *);
void rtg_dbdisconnect(MYSQL *);

/* Precasts: rtgutil.c */
int read_rtg_config(char *, config_t *);
int write_rtg_config(char *, config_t *);
void config_defaults(config_t *);
void print_stats (stats_t);
void sleepy(float);
void timestamp(char *);
int checkPID(char *);
int alldigits(char *);

/* Precasts: rtghash.c */
void init_hash();
void init_hash_walk();
target_t *getNext();
void free_hash();
unsigned long make_key(const void *);
void mark_targets(int);
int delete_targets(int);
void walk_target_hash();
void *in_hash(target_t *, target_t *);
int compare_targets(target_t *, target_t *);
int del_hash_entry(target_t *);
int add_hash_entry(target_t *);
int hash_target_file(char *);

/* Globals */
extern config_t			set;
extern int			lock;
extern int			waiting;
extern char			config_paths[CONFIG_PATHS][BUFSIZE];
extern hash_t			hash;

#endif /* not _RTG_H_ */
