/*
* Copyright (C) Tildeslash Ltd. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License version 3.
*
* 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 Affero General Public License
* along with this program. If not, see .
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
*
* You must obey the GNU Affero General Public License in all respects
* for all of the code used other than OpenSSL.
*/
#ifndef MONIT_H
#define MONIT_H
#include "config.h"
#include
#ifdef HAVE_KINFO_H
#include
#endif
#ifdef HAVE_SYS_TYPES_H
#include
#endif
#ifdef HAVE_SYS_STAT_H
#include
#endif
#ifdef HAVE_SIGNAL_H
#include
#endif
#ifdef HAVE_PTHREAD_H
#include
#endif
#ifdef HAVE_STDARG_H
#include
#endif
#ifdef HAVE_STDIO_H
#include
#endif
#ifdef HAVE_STDLIB_H
#include
#endif
#ifdef HAVE_REGEX_H
#include
#endif
#ifdef HAVE_SYSLOG_H
#include
#endif
#ifdef HAVE_LIMITS_H
#include
#endif
#ifdef HAVE_SYS_UTSNAME_H
#include
#endif
#ifdef HAVE_ERRNO_H
#include
#endif
#ifdef HAVE_NETDB_H
#include
#endif
#ifdef HAVE_SYS_SOCKET_H
#include
#endif
#ifdef HAVE_UVM_UVM_PARAM_H
#include
#endif
#ifdef HAVE_VM_VM_H
#include
#endif
#include
#include "Ssl.h"
#include "Address.h"
#include "statistics/Statistics.h"
#include "net/socket.h"
#include "net/Link.h"
// libmonit
#include "system/Command.h"
#include "system/Process.h"
#include "util/Str.h"
#include "util/StringBuffer.h"
#include "thread/Thread.h"
#define MONITRC "monitrc"
#define TIMEFORMAT "%FT%T%z"
#define STRERROR strerror(errno)
#define STRLEN 256
#ifndef USEC_PER_SEC
#define USEC_PER_SEC 1000000L
#endif
#define USEC_PER_MSEC 1000L
#define ARGMAX 64
#define MYPIDDIR PIDDIR
#define MYPIDFILE "monit.pid"
#define MYSTATEFILE "monit.state"
#define MYIDFILE "monit.id"
#define MYEVENTLISTBASE "/var/monit"
#define LOCALHOST "localhost"
#define PORT_SMTP 25
#define PORT_SMTPS 465
#define PORT_HTTP 80
#define PORT_HTTPS 443
#define SSL_TIMEOUT 15000
#define SMTP_TIMEOUT 30000
//FIXME: refactor Run_Flags to bit field
typedef enum {
Run_Once = 0x1, /**< Run Monit only once */
Run_Foreground = 0x2, /**< Don't daemonize Monit */ //FIXME: cleanup: Run_Foreground and Run_Daemon are mutually exclusive => no need for 2 flags
Run_Daemon = 0x4, /**< Daemonize Monit */ //FIXME: cleanup: Run_Foreground and Run_Daemon are mutually exclusive => no need for 2 flags
Run_Log = 0x8, /**< Log enabled */
Run_UseSyslog = 0x10, /**< Use syslog */ //FIXME: cleanup: no need for standalone flag ... if syslog is enabled, don't set Run.files.log, then (Run.flags&Run_Log && ! Run.files.log => syslog)
Run_FipsEnabled = 0x20, /** FIPS-140 mode enabled */
Run_HandlerInit = 0x40, /**< The handlers queue initialization */
Run_ProcessEngineEnabled = 0x80, /**< Process monitoring engine enabled */
Run_ActionPending = 0x100, /**< Service action pending */
Run_MmonitCredentials = 0x200, /**< Should set M/Monit credentials */
Run_Stopped = 0x400, /**< Stop Monit */
Run_DoReload = 0x800, /**< Reload Monit */
Run_DoWakeup = 0x1000, /**< Wakeup Monit */
Run_Batch = 0x2000 /**< CLI batch mode */
} __attribute__((__packed__)) Run_Flags;
typedef enum {
ProcessEngine_None = 0x0,
ProcessEngine_CollectCommandLine = 0x1
} __attribute__((__packed__)) ProcessEngine_Flags;
typedef enum {
Httpd_Start = 1,
Httpd_Stop
} __attribute__((__packed__)) Httpd_Action;
typedef enum {
Every_Initializing = 0,
Every_Cycle,
Every_SkipCycles,
Every_Cron,
Every_NotInCron
} __attribute__((__packed__)) Every_Type;
typedef enum {
State_Succeeded = 0x0,
State_Failed = 0x1,
State_Changed = 0x2,
State_ChangedNot = 0x4,
State_Init = 0x8,
State_None = State_Init // Alias
} __attribute__((__packed__)) State_Type;
typedef enum {
Operator_Less = 0,
Operator_LessOrEqual,
Operator_Greater,
Operator_GreaterOrEqual,
Operator_Equal,
Operator_NotEqual,
Operator_Changed
} __attribute__((__packed__)) Operator_Type;
typedef enum {
Timestamp_Default = 0,
Timestamp_Access,
Timestamp_Change,
Timestamp_Modification
} __attribute__((__packed__)) Timestamp_Type;
typedef enum {
Httpd_Disabled = 0x0,
Httpd_Net = 0x1, // IP
Httpd_Unix = 0x2, // Unix socket
Httpd_UnixUid = 0x4, // Unix socket: override UID
Httpd_UnixGid = 0x8, // Unix socket: override GID
Httpd_UnixPermission = 0x10, // Unix socket: override permissions
Httpd_Signature = 0x20 // Server Signature enabled
} __attribute__((__packed__)) Httpd_Flags;
typedef enum {
Http_Head = 1,
Http_Get
} __attribute__((__packed__)) Http_Method;
typedef enum {
Time_Second = 1,
Time_Minute = 60,
Time_Hour = 3600,
Time_Day = 86400,
Time_Month = 2678400
} __attribute__((__packed__)) Time_Type;
typedef enum {
Action_Ignored = 0,
Action_Alert,
Action_Restart,
Action_Stop,
Action_Exec,
Action_Unmonitor,
Action_Start,
Action_Monitor
} __attribute__((__packed__)) Action_Type;
typedef enum {
Monitor_Active = 0,
Monitor_Passive
} __attribute__((__packed__)) Monitor_Mode;
typedef enum {
Onreboot_Start = 0,
Onreboot_Nostart,
Onreboot_Laststate
} __attribute__((__packed__)) Onreboot_Type;
typedef enum {
Monitor_Not = 0x0,
Monitor_Yes = 0x1,
Monitor_Init = 0x2,
Monitor_Waiting = 0x4
} __attribute__((__packed__)) Monitor_State;
typedef enum {
Connection_Failed = 0,
Connection_Ok,
Connection_Init
} __attribute__((__packed__)) Connection_State;
typedef enum {
Service_Filesystem = 0,
Service_Directory,
Service_File,
Service_Process,
Service_Host,
Service_System,
Service_Fifo,
Service_Program,
Service_Net,
Service_Last = Service_Net
} __attribute__((__packed__)) Service_Type;
typedef enum {
Resource_CpuPercent = 1,
Resource_MemoryPercent,
Resource_MemoryKbyte,
Resource_LoadAverage1m,
Resource_LoadAverage5m,
Resource_LoadAverage15m,
Resource_Children,
Resource_MemoryKbyteTotal,
Resource_MemoryPercentTotal,
Resource_Inode,
Resource_InodeFree,
Resource_Space,
Resource_SpaceFree,
Resource_CpuUser,
Resource_CpuSystem,
Resource_CpuWait,
Resource_CpuNice,
Resource_CpuHardIRQ,
Resource_CpuSoftIRQ,
Resource_CpuSteal,
Resource_CpuGuest,
Resource_CpuGuestNice,
Resource_CpuPercentTotal,
Resource_SwapPercent,
Resource_SwapKbyte,
Resource_Threads,
Resource_ReadBytes,
Resource_ReadBytesPhysical,
Resource_ReadOperations,
Resource_WriteBytes,
Resource_WriteBytesPhysical,
Resource_WriteOperations,
Resource_ServiceTime,
Resource_LoadAveragePerCore1m,
Resource_LoadAveragePerCore5m,
Resource_LoadAveragePerCore15m
} __attribute__((__packed__)) Resource_Type;
typedef enum {
Digest_Cleartext = 1,
Digest_Crypt,
Digest_Md5,
Digest_Pam
} __attribute__((__packed__)) Digest_Type;
typedef enum {
Unit_Byte = 1,
Unit_Kilobyte = 1024,
Unit_Megabyte = 1048576,
Unit_Gigabyte = 1073741824
} __attribute__((__packed__)) Unit_Type;
typedef enum {
Hash_Unknown = 0,
Hash_Md5,
Hash_Sha1,
Hash_Default = Hash_Md5
} __attribute__((__packed__)) Hash_Type;
typedef enum {
Handler_Succeeded = 0x0,
Handler_Alert = 0x1,
Handler_Mmonit = 0x2,
Handler_Max = Handler_Mmonit
} __attribute__((__packed__)) Handler_Type;
typedef enum {
MmonitCompress_Init = 0,
MmonitCompress_No,
MmonitCompress_Yes
} __attribute__((__packed__)) MmonitCompress_Type;
typedef enum {
Statistics_CpuUser = 0x1,
Statistics_CpuNice = 0x2,
Statistics_CpuSystem = 0x4,
Statistics_CpuIOWait = 0x8,
Statistics_CpuHardIRQ = 0x10,
Statistics_CpuSoftIRQ = 0x20,
Statistics_CpuSteal = 0x40,
Statistics_CpuGuest = 0x80,
Statistics_CpuGuestNice = 0x100,
Statistics_FiledescriptorsPerSystem = 0x200,
Statistics_FiledescriptorsPerProcess = 0x400,
Statistics_FiledescriptorsPerProcessMax = 0x800
} __attribute__((__packed__)) Statistics_Flags;
/* Length of the longest message digest in bytes */
#define MD_SIZE 65
#define ICMP_SIZE 64
#define ICMP_MAXSIZE 1500
#define ICMP_ATTEMPT_COUNT 3
/* Default limits */
#define LIMIT_SENDEXPECTBUFFER 256
#define LIMIT_FILECONTENTBUFFER 512
#define LIMIT_PROGRAMOUTPUT 512
#define LIMIT_HTTPCONTENTBUFFER 1048576
#define LIMIT_NETWORKTIMEOUT 5000
#define LIMIT_PROGRAMTIMEOUT 300000
#define LIMIT_STOPTIMEOUT 30000
#define LIMIT_STARTTIMEOUT 30000
#define LIMIT_RESTARTTIMEOUT 30000
/** ------------------------------------------------- Special purpose macros */
/* Replace the standard signal function with a more reliable using
* sigaction. Taken from Stevens APUE book. */
typedef void Sigfunc(int);
Sigfunc *signal(int signo, Sigfunc * func);
#if defined(SIG_IGN) && !defined(SIG_ERR)
#define SIG_ERR ((Sigfunc *)-1)
#endif
/** ------------------------------------------------- General purpose macros */
#undef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#undef MIN
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#define IS(a,b) ((a && b) ? Str_isEqual(a, b) : false)
#define DEBUG Log_debug
#define FLAG(x, y) (x & y) == y
#define NVLSTR(x) (x ? x : "")
/** ------------------------------------------ Simple Assert Exception macro */
#define ASSERT(e) do { if (!(e)) { Log_critical("AssertException: " #e \
" at %s:%d\naborting..\n", __FILE__, __LINE__); abort(); } } while (0)
/* --------------------------------------------------------- Data structures */
/** Message Digest type with size for the longest digest we will compute */
typedef char MD_T[MD_SIZE];
/** Defines monit limits object */
typedef struct Limits_T {
int programOutput; /**< Program output truncate limit [B] */
size_t fileContentBuffer; /**< Maximum tested file content length [B] */
uint32_t sendExpectBuffer; /**< Maximum send/expect response length [B] */
uint32_t httpContentBuffer; /**< Maximum tested HTTP content length [B] */
uint32_t networkTimeout; /**< Default network timeout [ms] */
uint32_t programTimeout; /**< Default program timeout [ms] */
uint32_t stopTimeout; /**< Default stop timeout [ms] */
uint32_t startTimeout; /**< Default start timeout [ms] */
uint32_t restartTimeout; /**< Default restart timeout [ms] */
} Limits_T;
/**
* Defines a Command with ARGMAX optional arguments. The arguments
* array must be NULL terminated and the first entry is the program
* itself. In addition, a user and group may be set for the Command
* which means that the Command should run as a certain user and with
* certain group. To avoid name collision with Command_T in libmonit
* this structure uses lower case.
*/
typedef struct command_t {
char *arg[ARGMAX]; /**< Program with arguments */
short length; /**< The length of the arguments array */
bool has_uid; /**< true if a new uid is defined for this Command */
bool has_gid; /**< true if a new gid is defined for this Command */
uid_t uid; /**< The user id to switch to when running this Command */
gid_t gid; /**< The group id to switch to when running this Command */
unsigned int timeout; /**< Max seconds which we wait for method to execute */
} *command_t;
/** Defines an event action object */
typedef struct Action_T {
Action_Type id; /**< Action to be done */
int count; /**< Event count needed to trigger the action */
int cycles; /**< Cycles during which count limit can be reached */
int repeat; /*< Repeat action each Xth cycle */
command_t exec; /**< Optional command to be executed */
} *Action_T;
/** Defines event's up and down actions */
typedef struct EventAction_T {
Action_T failed; /**< Action in the case of failure down */
Action_T succeeded; /**< Action in the case of failure up */
} *EventAction_T;
/** Defines an url object */
typedef struct URL_T {
char *url; /**< Full URL */
char *protocol; /**< URL protocol type */
char *user; /**< URL user part */
char *password; /**< URL password part */
char *hostname; /**< URL hostname part */
char *path; /**< URL path part */
char *query; /**< URL query part */
int port; /**< URL port part */
bool ipv6;
} *URL_T;
/** Defines a HTTP client request object */
typedef struct Request_T {
URL_T url; /**< URL request */
Operator_Type operator; /**< Response content comparison operator */
regex_t *regex; /* regex used to test the response body */
} *Request_T;
/** Defines an event notification and status receiver object */
typedef struct Mmonit_T {
URL_T url; /**< URL definition */
struct SslOptions_T ssl; /**< SSL definition */
int timeout; /**< The timeout to wait for connection or i/o */
MmonitCompress_Type compress; /**< Compression flag */
/** For internal use */
struct Mmonit_T *next; /**< next receiver in chain */
} *Mmonit_T;
/** Defines a mailinglist object */
typedef struct Mail_T {
char *to; /**< Mail address for alert notification */
Address_T from; /**< The mail from address */
Address_T replyto; /**< Optional reply-to address */
char *subject; /**< The mail subject */
char *message; /**< The mail message */
char *host; /**< FQDN hostname */
unsigned int events; /*< Events for which this mail object should be sent */
unsigned int reminder; /*< Send error reminder each Xth cycle */
/** For internal use */
struct Mail_T *next; /**< next recipient in chain */
} *Mail_T;
/** Defines a mail server address */
typedef struct MailServer_T {
char *host; /**< Server host address, may be a IP or a hostname string */
int port; /**< Server port */
char *username; /** < Username for SMTP_AUTH */
char *password; /** < Password for SMTP_AUTH */
struct SslOptions_T ssl; /**< SSL definition */
Socket_T socket; /**< Connected socket */
/** For internal use */
struct MailServer_T *next; /**< Next server to try on connect error */
} *MailServer_T;
typedef struct Auth_T {
char *uname; /**< User allowed to connect to monit httpd */
char *passwd; /**< The users password data */
char *groupname; /**< PAM group name */
Digest_Type digesttype; /**< How did we store the password */
bool is_readonly; /**< true if this is a read-only authenticated user*/
struct Auth_T *next; /**< Next credential or NULL if last */
} *Auth_T;
/** Defines data for systemwide statistic */
typedef struct SystemInfo_T {
Statistics_Flags statisticsAvailable; /**< List of statistics that are available on this system */
struct {
int count; /**< Number of CPUs */
struct {
float user; /**< Time in user space [%] */
float nice; /**< Time in user space with low priority [%] */
float system; /**< Time in kernel space [%] */
float iowait; /**< Idle time while waiting for I/O [%] */
float hardirq; /**< Time servicing hardware interrupts [%] */
float softirq; /**< Time servicing software interrupts [%] */
float steal; /**< Stolen time, which is the time spent in other operating systems when running in a virtualized environment [%] */
float guest; /**< Time spent running a virtual CPU for guest operating systems under the control of the kernel [%] */
float guest_nice; /**< Time spent running a niced guest (virtual CPU for guest operating systems under the control of the kernel) [%] */
float idle; /**< Idle time [%] */
} usage;
} cpu;
struct {
unsigned long long size; /**< Maximal system real memory */
struct {
float percent; /**< Total real memory in use in the system */
unsigned long long bytes; /**< Total real memory in use in the system */
} usage;
} memory;
struct {
unsigned long long size; /**< Swap size */
struct {
float percent; /**< Total swap in use in the system */
unsigned long long bytes; /**< Total swap in use in the system */
} usage;
} swap;
struct {
long long allocated; /**< Number of allocated filedescriptors */
long long unused; /**< Number of unused filedescriptors */
long long maximum; /**< Filedescriptors limit */
} filedescriptors;
size_t argmax; /**< Program arguments maximum [B] */
double loadavg[3]; /**< Load average triple */
struct utsname uname; /**< Platform information provided by uname() */
struct timeval collected; /**< When were data collected */
unsigned long long booted; /**< System boot time (seconds since UNIX epoch, using platform-agnostic unsigned long long) */
double time; /**< 1/10 seconds */
double time_prev; /**< 1/10 seconds */
} SystemInfo_T;
/** Defines a protocol object with protocol functions */
typedef struct Protocol_T {
const char *name; /**< Protocol name */
void (*check)(Socket_T); /**< Protocol verification function */
} *Protocol_T;
/** Defines a send/expect object used for generic protocol tests */
typedef struct Generic_T {
char *send; /* string to send, or NULL if expect */
regex_t *expect; /* regex code to expect, or NULL if send */
/** For internal use */
struct Generic_T *next;
} *Generic_T;
typedef struct Outgoing_T {
char *ip; /**< Outgoing IP address */
struct sockaddr_storage addr;
socklen_t addrlen;
} Outgoing_T;
typedef struct ResponseTime_T {
Operator_Type operator;
double current; /**< Current response time [ms] */
double limit; /**< Response time limit [ms] */
} ResponseTime_T;
/** Defines a port object */
typedef struct Port_T {
char *hostname; /**< Hostname to check */
union {
struct {
char *pathname; /**< Unix socket pathname */
} unix;
struct {
int port; /**< Port number */
struct {
struct SslOptions_T options;
struct {
int validDays;
int minimumDays;
} certificate;
} ssl;
} net;
} target;
Outgoing_T outgoing; /**< Outgoing address */
bool check_invers; /**< Whether to alert on a connection success */
int timeout; /**< The timeout in [ms] to wait for connect or read i/o */
int retry; /**< Number of connection retry before reporting an error */
volatile int socket; /**< Socket used for connection */
struct ResponseTime_T responsetime; /**< Response time limit */
Socket_Type type; /**< Socket type used for connection (UDP/TCP) */
Socket_Family family; /**< Socket family used for connection (NET/UNIX) */
Connection_State is_available; /**< Server/port availability */
EventAction_T action; /**< Description of the action upon event occurrence */
/** Protocol specific parameters */
union {
struct {
char *username;
char *password;
char *path; /**< status path */
short loglimit; /**< Max percentage of logging processes */
short closelimit; /**< Max percentage of closinging processes */
short dnslimit; /**< Max percentage of processes doing DNS lookup */
short keepalivelimit; /**< Max percentage of keepalive processes */
short replylimit; /**< Max percentage of replying processes */
short requestlimit; /**< Max percentage of processes reading requests */
short startlimit; /**< Max percentage of processes starting up */
short waitlimit; /**< Min percentage of processes waiting for connection */
short gracefullimit;/**< Max percentage of processes gracefully finishing */
short cleanuplimit; /**< Max percentage of processes in idle cleanup */
Operator_Type loglimitOP; /**< loglimit operator */
Operator_Type closelimitOP; /**< closelimit operator */
Operator_Type dnslimitOP; /**< dnslimit operator */
Operator_Type keepalivelimitOP; /**< keepalivelimit operator */
Operator_Type replylimitOP; /**< replylimit operator */
Operator_Type requestlimitOP; /**< requestlimit operator */
Operator_Type startlimitOP; /**< startlimit operator */
Operator_Type waitlimitOP; /**< waitlimit operator */
Operator_Type gracefullimitOP; /**< gracefullimit operator */
Operator_Type cleanuplimitOP; /**< cleanuplimit operator */
} apachestatus;
struct {
Generic_T sendexpect;
} generic;
struct {
Hash_Type hashtype; /**< Type of hash for a checksum (optional) */
bool hasStatus; /**< Is explicit HTTP status set? */
Operator_Type operator; /**< HTTP status operator */
Http_Method method;
int status; /**< HTTP status */
char *username;
char *password;
char *request; /**< HTTP request */
char *checksum; /**< Document checksum (optional) */
List_T headers; /**< List of headers to send with request (optional) */
} http;
struct {
char *username;
char *password;
} mqtt;
struct {
char *username;
char *password;
char *rsaChecksum;
Hash_Type rsaChecksumType;
} mysql;
struct {
char *username;
char *password;
char *database;
} postgresql;
struct {
char *secret;
} radius;
struct {
int maxforward;
char *target;
} sip;
struct {
char *username;
char *password;
} smtp;
struct {
int version;
char *host;
char *origin;
char *request;
} websocket;
} parameters;
Protocol_T protocol; /**< Protocol object for testing a port's service */
Request_T url_request; /**< Optional url client request object */
/** For internal use */
struct Port_T *next; /**< next port in chain */
} *Port_T;
/** Defines a ICMP/Ping object */
typedef struct Icmp_T {
int type; /**< ICMP type used */
int size; /**< ICMP echo requests size */
int count; /**< ICMP echo requests count */
int timeout; /**< The timeout in milliseconds to wait for response */
bool check_invers; /**< Whether to alert on a connection success */
Connection_State is_available; /**< Flag for the server is availability */
Socket_Family family; /**< ICMP family used for connection */
struct ResponseTime_T responsetime; /**< Response time limit */
Outgoing_T outgoing; /**< Outgoing address */
EventAction_T action; /**< Description of the action upon event occurrence */
/** For internal use */
struct Icmp_T *next; /**< next icmp in chain */
} *Icmp_T;
typedef struct Dependant_T {
char *dependant; /**< name of dependant service */
char *dependant_urlescaped; /**< URL escaped name of dependant service */
StringBuffer_T dependant_htmlescaped; /**< HTML escaped name of dependant service */
/** For internal use */
struct Dependant_T *next; /**< next dependant service in chain */
} *Dependant_T;
/** Defines resource data */
typedef struct Resource_T {
Resource_Type resource_id; /**< Which value is checked */
Operator_Type operator; /**< Comparison operator */
double limit; /**< Limit of the resource */
EventAction_T action; /**< Description of the action upon event occurrence */
/** For internal use */
struct Resource_T *next; /**< next resource in chain */
} *Resource_T;
/** Defines timestamp object */
typedef struct Timestamp_T {
bool initialized; /**< true if timestamp was initialized */
bool test_changes; /**< true if we only should test for changes */
Timestamp_Type type;
Operator_Type operator; /**< Comparison operator */
unsigned long long time; /**< Timestamp watermark */
time_t lastTimestamp; /**< Last timestamp (context depends on type) */
EventAction_T action; /**< Description of the action upon event occurrence */
/** For internal use */
struct Timestamp_T *next; /**< next timestamp in chain */
} *Timestamp_T;
/** Defines action rate object */
typedef struct ActionRate_T {
int count; /**< Action counter */
int cycle; /**< Cycle counter */
EventAction_T action; /**< Description of the action upon matching rate */
/** For internal use */
struct ActionRate_T *next; /**< next actionrate in chain */
} *ActionRate_T;
/** Defines when to run a check for a service. This type supports both the old
cycle based every statement and the new cron-format version */
typedef struct Every_T {
Every_Type type;
time_t last_run;
union {
struct {
int number; /**< Check this program at a given cycles */
int counter; /**< Counter for number. When counter == number, check */
} cycle; /**< Old cycle based every check */
char *cron; /* A crontab format string */
} spec;
} Every_T;
typedef struct Status_T {
bool initialized; /**< true if status was initialized */
Operator_Type operator; /**< Comparison operator */
int return_value; /**< Return value of the program to check */
EventAction_T action; /**< Description of the action upon event occurrence */
/** For internal use */
struct Status_T *next; /**< next exit value in chain */
} *Status_T;
typedef struct Program_T {
Process_T P; /**< A Process_T object representing the sub-process */
Command_T C; /**< A Command_T object for creating the sub-process */
command_t args; /**< Program arguments */
time_t started; /**< When the sub-process was started */
int timeout; /**< Seconds the program may run until it is killed */
int exitStatus; /**< Sub-process exit status for reporting */
StringBuffer_T lastOutput; /**< Last program output */
StringBuffer_T inprogressOutput; /**< Output of the pending program instance */
} *Program_T;
/** Defines size object */
typedef struct Size_T {
bool initialized; /**< true if size was initialized */
bool test_changes; /**< true if we only should test for changes */
Operator_Type operator; /**< Comparison operator */
unsigned long long size; /**< Size watermark */
EventAction_T action; /**< Description of the action upon event occurrence */
/** For internal use */
struct Size_T *next; /**< next size in chain */
} *Size_T;
/** Defines uptime object */
typedef struct Uptime_T {
Operator_Type operator; /**< Comparison operator */
unsigned long long uptime; /**< Uptime watermark */
EventAction_T action; /**< Description of the action upon event occurrence */
/** For internal use */
struct Uptime_T *next; /**< next uptime in chain */
} *Uptime_T;
typedef struct LinkStatus_T {
bool check_invers; /**< Whether to alert on a link up */
EventAction_T action; /**< Description of the action upon event occurrence */
/** For internal use */
struct LinkStatus_T *next; /**< next link in chain */
} *LinkStatus_T;
typedef struct LinkSpeed_T {
int duplex; /**< Last duplex status */
long long speed; /**< Last speed [bps] */
EventAction_T action; /**< Description of the action upon event occurrence */
/** For internal use */
struct LinkSpeed_T *next; /**< next link in chain */
} *LinkSpeed_T;
typedef struct LinkSaturation_T {
Operator_Type operator; /**< Comparison operator */
float limit; /**< Saturation limit [%] */
EventAction_T action; /**< Description of the action upon event occurrence */
/** For internal use */
struct LinkSaturation_T *next; /**< next link in chain */
} *LinkSaturation_T;
typedef struct Bandwidth_T {
Operator_Type operator; /**< Comparison operator */
Time_Type range; /**< Time range to watch: unit */
int rangecount; /**< Time range to watch: count */
unsigned long long limit; /**< Data watermark */
EventAction_T action; /**< Description of the action upon event occurrence */
/** For internal use */
struct Bandwidth_T *next; /**< next bandwidth in chain */
} *Bandwidth_T;
/** Defines checksum object */
typedef struct Checksum_T {
bool initialized; /**< true if checksum was initialized */
bool test_changes; /**< true if we only should test for changes */
Hash_Type type; /**< The type of hash (e.g. md5 or sha1) */
int length; /**< Length of the hash */
char hash[MD_SIZE + 1]; /**< A checksum hash computed for the path */
EventAction_T action; /**< Description of the action upon event occurrence */
} *Checksum_T;
/** Defines permission object */
typedef struct Perm_T {
bool test_changes; /**< true if we only should test for changes */
int perm; /**< Access permission */
EventAction_T action; /**< Description of the action upon event occurrence */
} *Perm_T;
/** Defines match object */
typedef struct Match_T {
bool ignore; /**< Ignore match */
bool not; /**< Invert match */
char *match_string; /**< Match string */ //FIXME: union?
char *match_path; /**< File with matching rules */ //FIXME: union?
regex_t *regex_comp; /**< Match compile */
StringBuffer_T log; /**< The temporary buffer used to record the matches */
EventAction_T action; /**< Description of the action upon event occurrence */
/** For internal use */
struct Match_T *next; /**< next match in chain */
} *Match_T;
/** Defines uid object */
typedef struct Uid_T {
uid_t uid; /**< Owner's uid */
EventAction_T action; /**< Description of the action upon event occurrence */
} *Uid_T;
/** Defines gid object */
typedef struct Gid_T {
gid_t gid; /**< Owner's gid */
EventAction_T action; /**< Description of the action upon event occurrence */
} *Gid_T;
typedef struct SecurityAttribute_T {
char *attribute; /**< Security attribute */
EventAction_T action; /**< Description of the action upon event occurrence */
/** For internal use */
struct SecurityAttribute_T *next;
} *SecurityAttribute_T;
typedef struct Filedescriptors_T {
bool total; /**