/* 
logpp (Log PreProcessor) 0.16 - logpp.h
Copyright (C) 2006-2008 Risto Vaarandi

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#ifndef LOGPP_H
#define LOGPP_H

#include "common.h"

/* --------------- Constant defitions -------------- */

/* Generic constants */

#define NEWLINE '\n'    /* the newline character */
#define REPLACENULL '_' /* replace null bytes with _ in log lines */
#define COMMENT '#'     /* comments in config files begin with # */
#define MATCHVAR '$'    /* match variables in templates begin with $ */
#define IFILEVAR '~'    /* the ~ variable denotes an input file name */
#define MVARBUFSIZE 100 /* match variable buffer size (equals to max 
                           number of ()-constructs in regexps plus 1) */
#define SHELL "/bin/sh" /* shell for parsing forked command lines */
#define TAGLEN 33       /* syslog tag length according to RFC3164 */

/* with libpcre MVARBUFSIZE is the logical size of the match variable
   buffer, while MVARBUFSIZEx3 indicates the physical size and must be
   set to MVARBUFSIZE*3 */
#ifdef HAVE_LIBPCRE
#define MVARBUFSIZEx3 300
#else
/* with POSIX REs compile regular expressions with the following flags */
#define POSIX_REGEX_FLAGS (REG_EXTENDED | REG_NEWLINE)
#endif

/* Constants that define the type of input/output */

#define SRCDST_FILE 0
#define SRCDST_SYSLOG 1
#define SRCDST_EXEC 2

/* Constants that define the status of input/output determined by stat() */

#define SDSTAT_UNKN 0
#define SDSTAT_NONE 1
#define SDSTAT_REG 2
#define SDSTAT_FIFO 3

/* --------------- Filter defitions -------------- */

/* template_elem defines a part of a template where either 'str' is a string
   and 'len' is its length, or 'num' is a backreference variable number and
   'str' is NULL ('num' can be negative, e.g., -1 denotes an input file name).
   For example, "Message $1 received" will be split into the following parts: 
   "Message ", 1, " received"
*/

struct template_elem {
  char *str;
  size_t len;
  ssize_t num;
};

/* cond defines a filter condition where:
   'str' stores the string representation of the matching pattern,
   'regexp' stores a compiled regular expression or a pointer to it, 
   'extra' is extra information about 'regexp' (used for PCREs only)
   'num' indicates the number of lines that the regular expression was 
   designed to match; if 'num' is 0, pattern is a truth value, 
   'negative' indicates whether the regular expression is negative or
   the truth value is false, 
   'template' is the array of template parts, 
   'templ_size' is the number of template parts (if 'templ_size' is 0, 
   condition does not create output and prevents matching events from 
   being matched by later conditions), 
   'templ_str' is the string representation of the template,
   'counter' shows how many times the condition has matched
*/

struct cond {
  char *str;
#ifdef HAVE_LIBPCRE
  pcre *regexp;
  pcre_extra *extra;
#else
  regex_t regexp;
#endif
  size_t num;
  char negative;
  struct template_elem *template;
  size_t templ_size;
  char *templ_str;
  long long counter;
};

/* filter definition where 'name' is the name of the filter, 'condlist'
   is the array of filter conditions, and 'condl_size' is the size of 
   the condition array
*/

struct filter {
  char *name;
  struct cond *condlist;
  size_t condl_size;
  struct filter *next;
};

/* --------------- Output defitions -------------- */

/* output destination definition where: 
   'type' is the type of output, 
   'name' is the name of a file, syslog priority string or program name, 
   'status' is the status of output (set for SRCDST_FILE only),
   'fd' is a file descriptor (set for SRCDST_FILE only), 
   'tloa' is the time of last open attempt (set for SRCDST_FILE only), 
   'priority' is a syslog(3) priority (set for SRCDST_SYSLOG only),
   'counter' shows the number of writes to the output destination
*/

struct dst {
  int type;
  char *name;
  int status;
  int fd;
  time_t tloa;
  int priority;
  long long counter;
};

/* output definition where 'name' is the name of the output, 'dstlist' 
   is the array of output destinations, and 'dstl_size' is the size of 
   the output destination array 
*/

struct output {
  char *name;
  struct dst *dstlist;
  size_t dstl_size;
  struct output *next;
};

/* --------------- Flow defitions -------------- */

/* flow definition where:
   'name' is the name of the flow, 
   'flist' is the list of pointers to filters associated with the flow,
   'fl_size' is the size of 'flist',
   'olist' is the list of pointers to outputs associated with the flow,
   'ol_size' is the size of 'olist'
   'ilist' is the list of pointers to inputs associated with the flow,
   'il_size' is the size of 'ilist'
*/

struct flow {
  char *name;
  struct filter **flist;
  size_t fl_size;
  struct output **olist;
  size_t ol_size;
  struct input **ilist;
  size_t il_size;
  struct flow *next;
};

/* --------------- Input defitions -------------- */

/* line defines a buffer for holding a log line where 'bytes' is a pointer
   to a memory area of N bytes allocated at program start (the value of N
   is specified with a command line parameter) and 'len' is the number of 
   bytes in the line
*/

struct line {
  char *bytes;
  size_t len;
};

/* input source definition where: 
   'type' is the type of the source (currently SRCDST_FILE only), 
   'name' is the name of a file, 
   'status' is the status of the source determined by stat(), 
   'fd' is the descriptor of the open file (equals to -1 if the file is 
   in the closed state), 
   'pos' is the position of the file offset (set for regular files only)
   'dev' is the device ID containing the file,
   'ino' is the inode number of the file,
   'tloa' is the time of last open attempt, 
   'iobuf' is the IO buffer (its size depends on the command line option), 
   'iobuf_pos' and 'iobuf_len' reflect the offset and length of data in 
   the IO buffer
   'lbuf' is the buffer of last N lines from the file (N is specified with 
   the command line option; the buffer is implemented as an array with an 
   index incremented as i = (i+1) mod N), 
   'lbuf_pos' is the position of the index,
   'counter' shows the number of lines read from the input source
*/

struct src {
  int type;
  char *name;
  int status;
  int fd;
  off_t pos;
  dev_t dev;
  ino_t ino;
  time_t tloa;
  char *iobuf;
  char *iobuf_pos;
  size_t iobuf_len;
  struct line *lbuf;
  size_t lbuf_pos;
  long long counter;
};

/* flow list element definition */

struct fl_elem {
  struct flow *flow;
  struct fl_elem *next;
};

/* input definition where 'name' is the name of the input, 'srclist' is 
   the array of input sources, 'srcl_size' is the size of the input source
   array, 'flowlist' is the list of pointers to flow definitions
*/

struct input {
  char *name;
  struct src *srclist;
  size_t srcl_size;
  struct fl_elem *flowlist;
  struct input *next;
};

/* --------------- Global variables -------------- */

/* Command line options */
extern size_t BLOCKSIZE;
extern char DAEMON;
extern int FACILITY;
extern size_t IBUFSIZE;
extern int LOGLEVEL;
extern char *PIDFILE;
extern time_t REOPENINT;
extern long SLEEPSEC;
extern long SLEEPUSEC;
extern char TAG[];

/* List of configuration files */
extern char **CFLIST;
extern int CFLSIZE;

/* Config lists */
extern struct filter *FILTERLIST;
extern struct output *OUTPUTLIST;
extern struct flow *FLOWLIST;
extern struct input *INPUTLIST;

/* Buffers for input matching and output */
extern char *MATCHBUF;
extern size_t MBUFSIZE;
extern char *OUTBUF;
extern size_t OBUFSIZE;

/* Signal flags */
extern char GOT_SIGHUP;
extern char GOT_SIGTERM;
extern char GOT_SIGUSR1;
extern char GOT_SIGUSR2;
extern char GOT_SIGCHLD;

/* --------------- Functions -------------- */

/* readconf.c */
int read_config(char *);

/* tools.c */
int get_options(int, char **);
int daemonize(void);
void log_msg(int, const char *, ...);
int syslog_facility(char *, size_t);
int syslog_level(char *, size_t);
int set_sighandlers(void);
time_t get_time(void);
void *my_malloc(size_t);
void my_free(void *);
void create_config_lists(void);
void free_config_lists(void);
void dump_config_lists(void);

/* input.c */
int open_src_file(struct src *, off_t);
int close_src_file(struct src *);
void open_inputs(void);
void close_inputs(void);
int read_line(struct src *);
int src_file_shuffled(struct src *);

/* output.c */
int open_dst_file(struct dst *);
int close_dst_file(struct dst *);
void open_outputs(void);
void close_outputs(void);
int write_line(struct dst *, char *, size_t);

/* process.c */
int read_and_process(void);

#endif /* LOGPP_H */
