/* * 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; /**