/*
 * $Id: upsd.h,v 2.0.1.5 1996/06/26 18:39:38 alexis Exp alexis $
 *
 * UPS Daemon
 * The Wild Wind Communications, 1995, 1996
 *
 * See file LICENSE for the distribution terms of this software.
 */

#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>


/* Generic data types. */
#define	T_TYPE		0x0001	/* The bit 0 is the actual type. */
#define	T_BINARY	0x0000
#define	T_NUMBER	0x0001
#define	T_DEC		0x0003
#define	T_HEX		0x0005
#define	T_OCT		0x0007

/* Registers flags. */
#define	R_COMMAND	0x0001	/* Command only. */
#define R_INFO		0x0002	/* Informational register. */
#define R_OPTION	0x0004	/* An UPS setting. */
#define R_STATUS	0x0008	/* UPS current status register. */

/* Actions types. */
#define	A_NONE		000	/* Do nothing. */
#define	A_EVENT		001	/* Check another event. */
#define	A_EXEC		002	/* Execute a command (with sh -c ...). */
#define	A_RAISE		003	/* Trigger. */
#define	A_DROP		004	/* Drop a trigger or event. */
#define	A_POLL		005	/* Poll a register. */
#define	A_TUNE		006	/* Tune a register. */
#define	A_SLEEP		007	/* Sleep. */
#define	A_LOG		010	/* Writes to the syslog. */

/* Conditions. */
#define C_COND		0x0007	/* Condition bits. */
#define	C_NONE		0x0000	/* Do not compare. */
#define	C_MORE		0x0001	/* More than. */
#define	C_LESS		0x0002	/* Less than. */
#define	C_EQUAL		0x0004	/* Equal to. */
#define	C_NEQUAL	0x0005	/* Not equal to. */
#define	C_STRING	0x0008	/* The operands are strings, not numbers. */

/* 
 * Generic item identificator. All structures which use identification
 * contain at least id as their first element and marked with LIST
 * comment.
 */
struct ident {		/* LIST */
	int	id;
	char	*name;
};

/*
 * Generic chain element. All structures which are gathered into
 * chains should contain *next as their first element and all of
 * them are marked with CHAIN comment.
 */
struct chain {		/* CHAIN */
	struct	chain *next;
};


/* UPS Register. */	/* LIST */
struct ups_reg {
	int	id;		/* This register id. */
	char 	*name;		/* This register name. */
	int	flag;		/* This register flag. */
	int	mode;		/* Register mode. (UPS specific) */
	int	type;		/* Type of the register. */
	size_t	size;		/* Size of the value. */
	size_t	prec;		/* Precision of the value. */
	void	*cmd_data;	/* Actual command. */
	size_t	cmd_size;	/* Actual command size. */
};

/* UPS value. */	/* LIST */
struct ups_val {
	int	id;		/* Register id. */
	union	{
		void	*binary;
		double	number;
	} val;
};

/* UPS trigger. */	/* LIST */
struct ups_trig {
	int	id;		/* This trigger id. */
	char	*name;		/* This trigger name. */
	int	drop;		/* This trigger drops another one. */
	void	*trigger;	/* Actual trigger. */
	size_t	size;		/* The trigger size (for bcmp). */
};

/* UPS communication port handler.  */
struct ups_port {
	char	*device;		/* Pathname of the port. */
	int	fd;			/* File descriptor. */
	struct	timeval timeout;	/* This port read timeout. */
	struct	termios otty;		/* Initial tty settings. */
	struct	termios ntty;		/* New tty settings. */
	size_t	writeblksz;		/* Write block size. */
	struct	timeval writedelay;	/* Write delay between blocks. */
	struct {
		size_t	size;		/* Size of the queue. */
		void	*base;		/* Queue base. */
		void	*head;		/* Queue head. */
		void	*tail;		/* Queue tail. */
	} queue;			/* Asynchronous read queue. */
};

/* Actual UPS. */
struct ups {
	struct	ups_model *model;	/* Hardware specification. */
	struct	ups_port port;		/* Communication port handler. */
	struct	ups_val *state;		/* Current UPS state. */
	struct	event *eventv;		/* Events. Period. */
};

/* Specific UPS model description. */
struct ups_model {
	char	*protocol;		/* Protocol. */
	char	*type;			/* Type. */
	int	voltage;		/* Voltage. */
	int	nregs;			/* How many registers this UPS has? */
	struct	ups_reg *registers;	/* Registers. */
	struct	ups_trig *triggers;	/* Triggers. */
	struct	ups_val *values;	/* Legal values. */
	int	(*poll)(struct ups_val *);
					/* Poll function. */
	int	(*tune)(struct ups_val *);
					/* Tune function. */
};

/* Generic action. */
struct action {		/* CHAIN */
	struct	action *next;	/* Next in the chain. */
	int	type;		/* Action type. */
	void	*action;	/* Actual action. */
};

/* When. */
struct when {
	time_t	act_after;
	time_t	act_every;
	time_t	act_for;
};
	
/* Generic event. */
struct event {		/* CHAIN */
	struct	event *next;	/* Next in the chain. */
	struct	ups_val	*v;	/* An UPS variable to check. */
	int	condition;	/* How to treat the variable. */
	int	trigger;	/* If any trigger involved. */
	struct	when *when;	/* When the acts are executed. */
	struct	action *acts;	/* NULL terminated chain of actions. */
	time_t	first;		/* When the event occured first time. */
	time_t	last;		/* When the event occured last time. */
	time_t	nextrun;	/* Next time the actions need to be run. */
};

/* System log message. */
struct message {
	int	priority;
	char	*message;
};

#define	REGISTERNAME(regname)	(struct ups_reg *)		\
				    wherename(regname,		\
				    upsp->model->registers,	\
				    sizeof(struct ups_reg))

#define	REGISTERID(regid)	(struct ups_reg *)		\
				    whereid(regid,		\
				    upsp->model->registers,	\
				    sizeof(struct ups_reg))

#define	TRIGGERNAME(trigname)	(struct ups_trig *)		\
				    wherename(trigname,		\
				    upsp->model->triggers,	\
				    sizeof(struct ups_trig))

#define	TRIGGERID(trigid)	(struct ups_trig *)		\
				    whereid(trigid,		\
				    upsp->model->triggers,	\
				    sizeof(struct ups_trig))

#define	VALUEID(valid)		(struct ups_val *)		\
				    whereid(valid,		\
				    upsp->state,		\
				    sizeof(struct ups_val))

#define	TERMINATE		kill(getpid(), SIGTERM)

#include "conf.h"
#include "proto.h"


syntax highlighted by Code2HTML, v. 0.9.1