blob: c5930256dd09e46440ab642a3c2cf5a51cefe8d0 [file] [log] [blame]
/*
* Copyright (C) 2001-2011 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 <http://www.gnu.org/licenses/>.
*
* 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 <assert.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_REGEX_H
#include <regex.h>
#endif
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_SYS_UTSNAME_H
#include <sys/utsname.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include "ssl.h"
#include "socket.h"
// libmonit
#include "system/Command.h"
#include "system/Process.h"
#include "util/Str.h"
#include "util/StringBuffer.h"
#define MONITRC "monitrc"
#define TIMEFORMAT "%Z %b %e %T"
#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 HTTP_CONTENT_MAX (1024*1000)
/* Set event queue directory mode: "drwx------" */
#define QUEUEMASK 0077
/* Set file mode: "drw-------" */
#define PRIVATEMASK 0177
/* Set log file mode: "-rw-r-----" */
#define LOGMASK 0137
/* Set pid file mode: "-rw-r--r--" */
#define MYPIDMASK 0122
#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 15
#define START_DELAY 0
#define EXEC_TIMEOUT 30
#define START_HTTP 1
#define STOP_HTTP 2
#define TRUE 1
#define FALSE 0
#define MONITOR_NOT 0x0
#define MONITOR_YES 0x1
#define MONITOR_INIT 0x2
#define MONITOR_WAITING 0x4
#define EVERY_CYCLE 0
#define EVERY_SKIPCYCLES 1
#define EVERY_CRON 2
#define EVERY_NOTINCRON 3
#define STATE_SUCCEEDED 0
#define STATE_FAILED 1
#define STATE_CHANGED 2
#define STATE_CHANGEDNOT 3
#define STATE_INIT 4
#define MODE_ACTIVE 0
#define MODE_PASSIVE 1
#define MODE_MANUAL 2
#define OPERATOR_GREATER 0
#define OPERATOR_LESS 1
#define OPERATOR_EQUAL 2
#define OPERATOR_NOTEQUAL 3
#define TIME_SECOND 1
#define TIME_MINUTE 60
#define TIME_HOUR 3600
#define TIME_DAY 86400
#define ACTION_IGNORE 0
#define ACTION_ALERT 1
#define ACTION_RESTART 2
#define ACTION_STOP 3
#define ACTION_EXEC 4
#define ACTION_UNMONITOR 5
#define ACTION_START 6
#define ACTION_MONITOR 7
#define TYPE_FILESYSTEM 0
#define TYPE_DIRECTORY 1
#define TYPE_FILE 2
#define TYPE_PROCESS 3
#define TYPE_HOST 4
#define TYPE_SYSTEM 5
#define TYPE_FIFO 6
#define TYPE_PROGRAM 7
#define RESOURCE_ID_CPU_PERCENT 1
#define RESOURCE_ID_MEM_PERCENT 2
#define RESOURCE_ID_MEM_KBYTE 3
#define RESOURCE_ID_LOAD1 4
#define RESOURCE_ID_LOAD5 5
#define RESOURCE_ID_LOAD15 6
#define RESOURCE_ID_CHILDREN 7
#define RESOURCE_ID_TOTAL_MEM_KBYTE 8
#define RESOURCE_ID_TOTAL_MEM_PERCENT 9
#define RESOURCE_ID_INODE 10
#define RESOURCE_ID_SPACE 11
#define RESOURCE_ID_CPUUSER 12
#define RESOURCE_ID_CPUSYSTEM 13
#define RESOURCE_ID_CPUWAIT 14
#define RESOURCE_ID_TOTAL_CPU_PERCENT 15
#define RESOURCE_ID_SWAP_PERCENT 16
#define RESOURCE_ID_SWAP_KBYTE 17
#define DIGEST_CLEARTEXT 1
#define DIGEST_CRYPT 2
#define DIGEST_MD5 3
#define DIGEST_PAM 4
#define UNIT_BYTE 1
#define UNIT_KILOBYTE 1024
#define UNIT_MEGABYTE 1048580
#define UNIT_GIGABYTE 1073740000
#define HASH_UNKNOWN 0
#define HASH_MD5 1
#define HASH_SHA1 2
#define DEFAULT_HASH HASH_MD5
/* Length of the longest message digest in bytes */
#define MD_SIZE 65
#define PROTOCOL_NULL 0
#define PROTOCOL_HTTP 1
#define PROTOCOL_HTTPS 2
#define LEVEL_FULL 0
#define LEVEL_SUMMARY 1
#define LEVEL_NAME_FULL "full"
#define LEVEL_NAME_SUMMARY "summary"
#define HANDLER_SUCCEEDED 0x0
#define HANDLER_ALERT 0x1
#define HANDLER_MMONIT 0x2
#define HANDLER_MAX HANDLER_MMONIT
#define ICMP_ATTEMPT_COUNT 3
/** ------------------------------------------------- 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)?!strcasecmp(a, b):0)
#define DEBUG if(Run.debug) LogDebug
#define FLAG(x, y) (x & y) == y
#define NVLSTR(x) (x?x:"")
/** ------------------------------------------------- Synchronization macros */
#define LOCK(mutex) do { pthread_mutex_t *_yymutex = &(mutex); \
assert(pthread_mutex_lock(_yymutex)==0);
#define END_LOCK assert(pthread_mutex_unlock(_yymutex)==0); } while (0)
/** ------------------------------------------ Simple Assert Exception macro */
#define ASSERT(e) do { if(!(e)) { LogCritical("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 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.
*/
typedef struct mycommand {
char *arg[ARGMAX]; /**< Program with arguments */
int length; /**< The length of the arguments array */
int has_uid; /**< TRUE if a new uid is defined for this Command */
uid_t uid; /**< The user id to switch to when running this Command */
int has_gid; /**< TRUE if a new gid is defined for this Command */
gid_t gid; /**< The group id to switch to when running this Command */
unsigned timeout; /**< Max seconds which we wait for method to execute */
} *command_t;
/** Defines an event action object */
typedef struct myaction {
int id; /**< Action to be done */
command_t exec; /**< Optional command to be executed */
unsigned count; /**< Event count needed to trigger the action */
unsigned cycles; /**< Cycles during which count limit can be reached */
} *Action_T;
/** Defines event's up and down actions */
typedef struct myeventaction {
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 myurl {
char *url; /**< Full URL */
char *protocol; /**< URL protocol type */
char *user; /**< URL user part */
char *password; /**< URL password part */
char *hostname; /**< URL hostname part */
int port; /**< URL port part */
char *path; /**< URL path part */
char *query; /**< URL query part */
} *URL_T;
/** Defines a HTTP client request object */
typedef struct myrequest {
URL_T url; /**< URL request */
int operator; /**< Response content comparison operator */
#ifdef HAVE_REGEX_H
regex_t *regex; /* regex used to test the response body */
#else
char *regex; /* string to search for in the response body */
#endif
} *Request_T;
/** Defines an event notification and status receiver object */
typedef struct mymmonit {
URL_T url; /**< URL definition */
Ssl_T ssl; /**< SSL definition */
int timeout; /**< The timeout to wait for connection or i/o */
/** For internal use */
struct mymmonit *next; /**< next receiver in chain */
} *Mmonit_T;
/** Defines a mailinglist object */
typedef struct mymail {
char *to; /**< Mail address for alert notification */
char *from; /**< The mail from address */
char *replyto; /**< Optional reply-to address */
char *subject; /**< The mail subject */
char *message; /**< The mail message */
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 mymail *next; /**< next recipient in chain */
} *Mail_T;
/** Defines a mail server address */
typedef struct mymailserver {
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 */
Ssl_T ssl; /**< SSL definition */
/** For internal use */
struct mymailserver *next; /**< Next server to try on connect error */
} *MailServer_T;
typedef struct myauthentication {
char *uname; /**< User allowed to connect to monit httpd */
char *passwd; /**< The users password data */
char *groupname; /**< PAM group name */
int digesttype; /**< How did we store the password */
int is_readonly; /**< TRUE if this is a read-only authenticated user*/
struct myauthentication *next; /**< Next credential or NULL if last */
} *Auth_T;
/** Defines process tree - data storage backend*/
typedef struct myprocesstree {
int pid;
int ppid;
int status_flag;
time_t starttime;
char *cmdline;
int visited;
int children_num;
int children_sum;
int cpu_percent;
int cpu_percent_sum;
unsigned long mem_kbyte;
unsigned long mem_kbyte_sum;
/** For internal use */
double time; /**< 1/10 seconds */
double time_prev; /**< 1/10 seconds */
long cputime; /**< 1/10 seconds */
long cputime_prev; /**< 1/10 seconds */
int parent;
int *children;
} ProcessTree_T;
/** Defines data for systemwide statistic */
typedef struct mysysteminfo {
struct timeval collected; /**< When were data collected */
int cpus; /**< Number of CPUs */
double loadavg[3]; /**< Load average triple */
unsigned long mem_kbyte_max; /**< Maximal system real memory */
unsigned long swap_kbyte_max; /**< Swap size */
unsigned long total_mem_kbyte; /**< Total real memory in use in the system */
unsigned long total_swap_kbyte; /**< Total swap in use in the system */
int total_mem_percent; /**< Total real memory in use in the system */
int total_swap_percent; /**< Total swap in use in the system */
int total_cpu_user_percent; /**< Total CPU in use in user space (pct.)*/
int total_cpu_syst_percent; /**< Total CPU in use in kernel space (pct.)*/
int total_cpu_wait_percent; /**< Total CPU in use in waiting (pct.)*/
struct utsname uname; /**< Platform information provided by uname() */
} SystemInfo_T;
/** Defines a protocol object with protocol functions */
typedef struct Protocol_T {
const char *name; /**< Protocol name */
int(*check)(Socket_T); /**< Protocol verification function */
} *Protocol_T;
/** Defines a send/expect object used for generic protocol tests */
typedef struct mygenericproto {
char *send; /* string to send, or NULL if expect */
#ifdef HAVE_REGEX_H
regex_t *expect; /* regex code to expect, or NULL if send */
#else
char *expect; /* string to expect, or NULL if send */
#endif
/** For internal use */
struct mygenericproto *next;
} *Generic_T;
/** Defines a port object */
typedef struct myport {
volatile int socket; /**< Socket used for connection */
int type; /**< Socket type used for connection (UDP/TCP) */
int family; /**< Socket family used for connection (INET/UNIX) */
char *hostname; /**< Hostname to check */
int port; /**< Portnumber */
char *request; /**< Specific protocol request */
char *request_checksum; /**< The optional checksum for a req. document */
char *request_hostheader; /**< The optional Host: header to use */
int request_hashtype; /**< The optional type of hash for a req. document */
char *pathname; /**< Pathname, in case of an UNIX socket */
int maxforward; /**< Optional max forward for protocol checking */
Generic_T generic; /**< Generic test handle */
int timeout; /**< The timeout in seconds to wait for connect or read i/o */
int retry; /**< Number of connection retry before reporting an error */
int is_available; /**< TRUE if the server/port is available */
double response; /**< Socket connection response time */
EventAction_T action; /**< Description of the action upon event occurence */
/** Apache-status specific parameters */
struct apache_status {
int loglimit; /**< Max percentatge of logging processes */
int loglimitOP; /**< loglimit operator */
int closelimit; /**< Max percentatge of closinging processes */
int closelimitOP; /**< closelimit operator */
int dnslimit; /**< Max percentatge of processes doing DNS lookup */
int dnslimitOP; /**< dnslimit operator */
int keepalivelimit; /**< Max percentatge of keepalive processes */
int keepalivelimitOP; /**< keepalivelimit operator */
int replylimit; /**< Max percentatge of replying processes */
int replylimitOP; /**< replylimit operator */
int requestlimit; /**< Max percentatge of processes reading requests */
int requestlimitOP; /**< requestlimit operator */
int startlimit; /**< Max percentatge of processes starting up */
int startlimitOP; /**< startlimit operator */
int waitlimit; /**< Min percentatge of processes waiting for connection */
int waitlimitOP; /**< waitlimit operator */
int gracefullimit;/**< Max percentatge of processes gracefully finishing */
int gracefullimitOP; /**< gracefullimit operator */
int cleanuplimit; /**< Max percentatge of processes in idle cleanup */
int cleanuplimitOP; /**< cleanuplimit operator */
} ApacheStatus;
Ssl_T SSL; /**< SSL definition */
Protocol_T protocol; /**< Protocol object for testing a port's service */
Request_T url_request; /**< Optional url client request object */
/** For internal use */
struct myport *next; /**< next port in chain */
} *Port_T;
/** Defines a ICMP object */
typedef struct myicmp {
int type; /**< ICMP type used */
int count; /**< ICMP echo requests count */
int timeout; /**< The timeout in seconds to wait for response */
int is_available; /**< TRUE if the server is available */
double response; /**< ICMP ECHO response time */
EventAction_T action; /**< Description of the action upon event occurence */
/** For internal use */
struct myicmp *next; /**< next icmp in chain */
} *Icmp_T;
typedef struct myservicegroupmember {
char *name; /**< name of service */
/** For internal use */
struct myservicegroupmember *next; /**< next service in chain */
} *ServiceGroupMember_T;
typedef struct myservicegroup {
char *name; /**< name of service group */
struct myservicegroupmember *members; /**< Service group members */
/** For internal use */
struct myservicegroup *next; /**< next service group in chain */
} *ServiceGroup_T;
typedef struct mydependant {
char *dependant; /**< name of dependant service */
/** For internal use */
struct mydependant *next; /**< next dependant service in chain */
} *Dependant_T;
/** Defines resource data */
typedef struct myresource {
int resource_id; /**< Which value is checked */
long limit; /**< Limit of the resource */
int operator; /**< Comparison operator */
EventAction_T action; /**< Description of the action upon event occurence */
/** For internal use */
struct myresource *next; /**< next resource in chain */
} *Resource_T;
/** Defines timestamp object */
typedef struct mytimestamp {
int operator; /**< Comparison operator */
int time; /**< Timestamp watermark */
int test_changes; /**< TRUE if we only should test for changes */
time_t timestamp; /**< The original last modified timestamp for this object*/
EventAction_T action; /**< Description of the action upon event occurence */
/** For internal use */
struct mytimestamp *next; /**< next timestamp in chain */
} *Timestamp_T;
/** Defines action rate object */
typedef struct myactionrate {
int count; /**< Action counter */
int cycle; /**< Cycle counter */
EventAction_T action; /**< Description of the action upon matching rate */
/** For internal use */
struct myactionrate *next; /**< next actionrate in chain */
} *ActionRate_T;
/** Defines when to run a check for a service. This type suports both the old
cycle based every statement and the new cronformat version */
typedef struct myevery {
int type; /**< 0 = not set, 1 = cycle, 2 = cron, 3 = negated cron */
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 myprogram {
int return_value; /**< Return value of the program to check */
int operator; /**< Comparison operator */
int timeout; /**< How long the program may run until it is killed */
time_t started; /**< When the sub-process was started */
int exitStatus; /**< Sub-process exit status for reporting */
Process_T P; /**< A Process_T object representing the sub-process */
Command_T C; /**< A Command_T object for building the sub-process */
EventAction_T action; /**< Description of the action upon event occurence */
} *Program_T;
/** Defines size object */
typedef struct mysize {
int operator; /**< Comparison operator */
unsigned long long size; /**< Size watermark */
int test_changes; /**< TRUE if we only should test for changes */
int test_changes_ok; /**< TRUE if size was initialized for changes test */
EventAction_T action; /**< Description of the action upon event occurence */
/** For internal use */
struct mysize *next; /**< next size in chain */
} *Size_T;
/** Defines uptime object */
typedef struct myuptime {
int operator; /**< Comparison operator */
unsigned long long uptime; /**< Uptime watermark */
EventAction_T action; /**< Description of the action upon event occurence */
/** For internal use */
struct myuptime *next; /**< next uptime in chain */
} *Uptime_T;
/** Defines checksum object */
typedef struct mychecksum {
MD_T hash; /**< A checksum hash computed for the path */
int type; /**< The type of hash (e.g. md5 or sha1) */
int length; /**< Length of the hash */
int test_changes; /**< TRUE if we only should test for changes */
int test_changes_ok; /**< TRUE if cksum was initialized for changes test */
EventAction_T action; /**< Description of the action upon event occurence */
} *Checksum_T;
/** Defines permission object */
typedef struct myperm {
int perm; /**< Access permission */
EventAction_T action; /**< Description of the action upon event occurence */
} *Perm_T;
/** Defines match object */
typedef struct mymatch {
int ignore; /**< Ignore match */
int not; /**< Invert match */
char *match_string; /**< Match string */
char *match_path; /**< File with matching rules */
#ifdef HAVE_REGEX_H
regex_t *regex_comp; /**< Match compile */
#endif
StringBuffer_T log; /**< The temporary buffer used to record the matches */
EventAction_T action; /**< Description of the action upon event occurence */
/** For internal use */
struct mymatch *next; /**< next match in chain */
} *Match_T;
/** Defines uid object */
typedef struct myuid {
uid_t uid; /**< Owner's uid */
EventAction_T action; /**< Description of the action upon event occurence */
} *Uid_T;
/** Defines gid object */
typedef struct mygid {
gid_t gid; /**< Owner's gid */
EventAction_T action; /**< Description of the action upon event occurence */
} *Gid_T;
/** Defines filesystem configuration */
typedef struct myfilesystem {
int resource; /**< Whether to check inode or space */
int operator; /**< Comparison operator */
long limit_absolute; /**< Watermark - blocks */
int limit_percent; /**< Watermark - percent */
EventAction_T action; /**< Description of the action upon event occurence */
/** For internal use */
struct myfilesystem *next; /**< next filesystem in chain */
} *Filesystem_T;
/** Defines service data */
typedef struct myinfo {
/* Shared */
mode_t st_mode; /**< Permission */
uid_t st_uid; /**< Owner's uid */
gid_t st_gid; /**< Owner's gid */
time_t timestamp; /**< Timestamp */
union {
struct {
long f_bsize; /**< Transfer block size */
long f_blocks; /**< Total data blocks in filesystem */
long f_blocksfree; /**< Free blocks available to non-superuser */
long f_blocksfreetotal; /**< Free blocks in filesystem */
long f_files; /**< Total file nodes in filesystem */
long f_filesfree; /**< Free file nodes in filesystem */
char *mntpath; /**< Filesystem file, directory or mountpoint */
int inode_percent; /**< Used inode percentage * 10 */
long inode_total; /**< Used inode total objects */
int space_percent; /**< Used space percentage * 10 */
long space_total; /**< Used space total blocks */
int _flags; /**< Filesystem flags from last cycle */
int flags; /**< Filesystem flags from actual cycle */
} filesystem;
struct {
off_t st_size; /**< Size */
off_t readpos; /**< Position for regex matching */
ino_t st_ino; /**< Inode */
ino_t st_ino_prev; /**< Previous inode for regex matching */
MD_T cs_sum; /**< Checksum */
} file;
struct {
int _pid; /**< Process PID from last cycle */
int _ppid; /**< Process parent PID from last cycle */
int pid; /**< Process PID from actual cycle */
int ppid; /**< Process parent PID from actual cycle */
int status_flag;
int children;
long mem_kbyte;
long total_mem_kbyte;
int mem_percent; /**< percentage * 10 */
int total_mem_percent; /**< percentage * 10 */
int cpu_percent; /**< percentage * 10 */
int total_cpu_percent; /**< percentage * 10 */
time_t uptime; /**< Process uptime */
} process;
} priv;
} *Info_T;
/** Defines service data */
typedef struct myservice {
/** Common parameters */
char *name; /**< Service descriptive name */
int (*check)(struct myservice *); /**< Service verification function */
int type; /**< Monitored service type */
int monitor; /**< Monitor state flag */
int mode; /**< Monitoring mode for the service */
int ncycle; /**< The number of the current cycle */
int nstart; /**< The number of current starts with this service */
int visited; /**< Service visited flag, set if dependencies are used */
int depend_visited;/**< Depend visited flag, set if dependencies are used */
Every_T every; /**< Timespec for when to run check of service */
command_t start; /**< The start command for the service */
command_t stop; /**< The stop command for the service */
command_t restart;
Dependant_T dependantlist; /**< Dependant service list */
Mail_T maillist; /**< Alert notification mailinglist */
/** Test rules and event handlers */
ActionRate_T actionratelist; /**< ActionRate check list */
Checksum_T checksum; /**< Checksum check */
Filesystem_T filesystemlist; /**< Filesystem check list */
Gid_T gid; /**< Gid check */
Icmp_T icmplist; /**< ICMP check list */
Perm_T perm; /**< Permission check */
Port_T portlist; /**< Portnumbers to check, either local or at a host */
Resource_T resourcelist; /**< Resouce check list */
Size_T sizelist; /**< Size check list */
Uptime_T uptimelist; /**< Uptime check list */
Match_T matchlist; /**< Content Match list */
Match_T matchignorelist; /**< Content Match ignore list */
Timestamp_T timestamplist; /**< Timestamp check list */
Uid_T uid; /**< Uid check */
Program_T program; /**< Status (of program execution) check */
EventAction_T action_PID; /**< Action upon pid change */
EventAction_T action_PPID; /**< Action upon ppid change */
EventAction_T action_FSFLAG; /**< Action upon filesystem flags change */
/** General event handlers */
EventAction_T action_DATA; /**< Description of the action upon event */
EventAction_T action_EXEC; /**< Description of the action upon event */
EventAction_T action_INVALID; /**< Description of the action upon event */
EventAction_T action_NONEXIST; /**< Description of the action upon event */
/** Internal monit events */
EventAction_T action_MONIT_START; /**< Monit instance start action */
EventAction_T action_MONIT_STOP; /**< Monit instance stop action */
EventAction_T action_MONIT_RELOAD; /**< Monit instance reload action */
EventAction_T action_ACTION; /**< Action requested by CLI or GUI */
/** Runtime parameters */
int error; /**< Error flags bitmap */
int error_hint; /**< Failed/Changed hint for error bitmap */
Info_T inf; /**< Service check result */
struct timeval collected; /**< When were data collected */
int doaction; /**< Action scheduled by http thread */
char *token; /**< Action token */
/** Events */
struct myevent {
#define EVENT_VERSION 3 /**< The event structure version */
long id; /**< The event identification */
struct timeval collected; /**< When the event occured */
char *source; /**< Event source service name */
int mode; /**< Monitoring mode for the service */
int type; /**< Monitored service type */
short state; /**< TRUE if failed, FALSE if succeeded */
short state_changed; /**< TRUE if state changed */
long long state_map; /**< Event bitmap for last cycles */
unsigned int count; /**< The event rate */
unsigned int flag; /**< The handlers state flag */
char *message; /**< Optional message describing the event */
EventAction_T action; /**< Description of the event action */
/** For internal use */
struct myevent *next; /**< next event in chain */
struct myevent *previous; /**< previous event in chain */
} *eventlist; /**< Pending events list */
/** Context specific parameters */
char *path; /**< Path to the filesys, file, directory or process pid file */
/** For internal use */
pthread_mutex_t mutex; /**< Mutex used for action synchronization */
struct myservice *next; /**< next service in chain */
struct myservice *next_conf; /**< next service according to conf file */
struct myservice *next_depend; /**< next depend service in chain */
} *Service_T;
typedef struct myevent *Event_T;
/** Defines data for application runtime */
struct myrun {
volatile int stopped;/**< TRUE if monit was stopped. Flag used by threads */
char *controlfile; /**< The file to read configuration from */
char *logfile; /**< The file to write logdata into */
char *localhostname; /**< The host name for localhost */
char *pidfile; /**< This programs pidfile */
char *idfile; /**< The file with unique monit id */
char id[STRLEN]; /**< Unique monit id */
char *statefile; /**< The file with the saved runtime state */
char *mygroup; /**< Group Name of the Service */
int debug; /**< Write debug information - TRUE or FALSE */
int use_syslog; /**< If TRUE write log to syslog */
int dolog; /**< TRUE if program should log actions, otherwise FALSE */
int isdaemon; /**< TRUE if program should run as a daemon */
int polltime; /**< In deamon mode, the sleeptime (sec) between run */
int startdelay; /**< the sleeptime (sec) after startup */
int dohttpd; /**< TRUE if monit HTTP server should run */
int httpdssl; /**< TRUE if monit HTTP server uses ssl */
char *httpsslpem; /**< PEM file for the HTTPS server */
int clientssl; /**< TRUE if monit HTTP server uses ssl with client auth */
char *httpsslclientpem; /**< PEM file/dir to check against at connect */
int allowselfcert; /**< TRUE if self certified client certs are allowed */
int httpdsig; /**< TRUE if monit HTTP server presents version signature */
int httpdport; /**< The monit http server's portnumber */
int once; /**< TRUE - run only once */
int init; /**< TRUE - don't background to run from init */
int facility; /** The facility to use when running openlog() */
int doprocess; /**< TRUE if process status engine is used */
char *bind_addr; /**< The address monit http will bind to */
volatile int doreload; /**< TRUE if a monit daemon should reinitialize */
volatile int dowakeup; /**< TRUE if a monit daemon was wake up by signal */
int doaction; /**< TRUE if some service(s) has action pending */
mode_t umask; /**< The initial umask monit was started with */
int testing; /**< Running in configuration testing mode - TRUE or FALSE */
time_t incarnation; /**< Unique ID for running monit instance */
int handler_init; /**< The handlers queue initialization */
int handler_flag; /**< The handlers state flag */
int handler_queue[HANDLER_MAX+1]; /**< The handlers queue counter */
Service_T system; /**< The general system service */
char *eventlist_dir; /**< The event queue base directory */
int eventlist_slots; /**< The event queue size - number of slots */
int expectbuffer; /**< Generic protocol expect buffer - STRLEN by default */
/** An object holding program relevant "environment" data, see; env.c */
struct myenvironment {
char *user; /**< The the effective user running this program */
char *home; /**< Users home directory */
char *cwd; /**< Current working directory */
} Env;
char *mail_hostname; /**< Used in HELO/EHLO/MessageID when sending mail */
int mailserver_timeout; /**< Connect and read timeout for a SMTP server */
Mail_T maillist; /**< Global alert notification mailinglist */
MailServer_T mailservers; /**< List of MTAs used for alert notification */
Mmonit_T mmonits; /**< Event notification and status receivers list */
Auth_T credentials; /** A list holding Basic Authentication information */
int dommonitcredentials; /**< TRUE if M/Monit should receive credentials */
Auth_T mmonitcredentials; /**< Pointer to selected credentials or NULL */
Event_T eventlist; /** A list holding partialy handled events */
/** User selected standard mail format */
struct myformat {
char *from; /**< The standard mail from address */
char *replyto; /**< Optional reply-to header */
char *subject; /**< The standard mail subject */
char *message; /**< The standard mail message */
} MailFormat;
pthread_mutex_t mutex; /**< Mutex used for service data synchronization */
#ifdef OPENSSL_FIPS
int fipsEnabled; /** TRUE if monit should use FIPS-140 mode */
#endif
};
/* -------------------------------------------------------- Global variables */
extern const char *prog;
extern struct myrun Run;
extern Service_T servicelist;
extern Service_T servicelist_conf;
extern ServiceGroup_T servicegrouplist;
extern SystemInfo_T systeminfo;
extern ProcessTree_T *ptree;
extern int ptreesize;
extern ProcessTree_T *oldptree;
extern int oldptreesize;
extern char *actionnames[];
extern char *modenames[];
extern char *checksumnames[];
extern char *operatornames[];
extern char *operatorshortnames[];
extern char *statusnames[];
extern char *servicetypes[];
extern char *pathnames[];
extern char *icmpnames[];
extern char *sslnames[];
/* ------------------------------------------------------- Public prototypes */
#include "util.h"
#include "file.h"
// libmonit
#include "system/Mem.h"
/* FIXME: move remaining prototypes into seperate header-files */
int parse(char *);
int control_service(const char *, int);
int control_service_string(const char *, const char *);
int control_service_daemon(const char *, const char *);
void setup_dependants();
void reset_depend();
void spawn(Service_T, command_t, Event_T);
int status(char *);
int log_init();
void LogEmergency(const char *, ...);
void LogAlert(const char *, ...);
void LogCritical(const char *, ...);
void LogError(const char *, ...);
void vLogError(const char *s, va_list ap);
void vLogAbortHandler(const char *s, va_list ap);
void LogWarning(const char *, ...);
void LogNotice(const char *, ...);
void LogInfo(const char *, ...);
void LogDebug(const char *, ...);
void log_close();
#ifndef HAVE_VSYSLOG
#ifdef HAVE_SYSLOG
void vsyslog (int, const char *, va_list);
#endif /* HAVE_SYSLOG */
#endif /* HAVE_VSYSLOG */
int validate();
void daemonize();
void gc();
void gc_mail_list(Mail_T *);
void gccmd(command_t *);
void gc_event(Event_T *e);
int kill_daemon(int);
int exist_daemon();
int sendmail(Mail_T);
int sock_msg(int, char *, ...);
void init_env();
void monit_http(int);
int can_http();
char *format(const char *, va_list, long *);
void redirect_stdfd();
void fd_close();
pid_t getpgid(pid_t);
void unset_signal_block(sigset_t *);
void set_signal_block(sigset_t *, sigset_t *);
int check_process(Service_T);
int check_filesystem(Service_T);
int check_file(Service_T);
int check_directory(Service_T);
int check_remote_host(Service_T);
int check_system(Service_T);
int check_fifo(Service_T);
int check_program(Service_T);
int check_URL(Service_T s);
int sha_md5_stream (FILE *, void *, void *);
void reset_procinfo(Service_T);
int check_service_status(Service_T);
void printhash(char *);
void status_xml(StringBuffer_T, Event_T, short, int, const char *);
int handle_mmonit(Event_T);
int do_wakeupcall();
#endif