/*
* Copyright (C), 2000-2007 by the monit project group.
* All Rights Reserved.
*
* 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 3 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, see .
*/
#include
#ifdef HAVE_STDIO_H
#include
#endif
#ifdef HAVE_STDLIB_H
#include
#endif
#ifdef HAVE_ERRNO_H
#include
#endif
#ifdef HAVE_SYS_TYPES_H
#include
#endif
#ifdef HAVE_SYS_SOCKET_H
#include
#endif
#ifdef HAVE_STRING_H
#include
#endif
#ifdef HAVE_STRINGS_H
#include
#endif
#ifdef HAVE_UNISTD_H
#include
#endif
#ifdef HAVE_SYS_STAT_H
#include
#endif
#ifdef HAVE_SYS_TIME_H
#include
#endif
#include "monitor.h"
#include "cervlet.h"
#include "engine.h"
#include "processor.h"
#include "base64.h"
#include "event.h"
#include "alert.h"
#include "process.h"
#include "device.h"
#define ACTION(c) !strncasecmp(req->url, c, sizeof(c))
/* URL Commands supported */
#define HOME "/"
#define TEST "/_monit"
#define ABOUT "/_about"
#define PING "/_ping"
#define PIXEL "/_pixel"
#define STATUS "/_status"
#define RUN "/_runtime"
#define VIEWLOG "/_viewlog"
/* Private prototypes */
static int is_readonly(HttpRequest);
static void printPixel(HttpResponse);
static void doGet(HttpRequest, HttpResponse);
static void doPost(HttpRequest, HttpResponse);
static void do_home(HttpRequest, HttpResponse);
static void do_home_system(HttpRequest, HttpResponse);
static void do_home_device(HttpRequest, HttpResponse);
static void do_home_directory(HttpRequest, HttpResponse);
static void do_home_file(HttpRequest, HttpResponse);
static void do_home_fifo(HttpRequest, HttpResponse);
static void do_home_process(HttpRequest, HttpResponse);
static void do_home_host(HttpRequest, HttpResponse);
static void do_about(HttpRequest, HttpResponse);
static void do_ping(HttpRequest, HttpResponse);
static void do_runtime(HttpRequest, HttpResponse);
static void do_viewlog(HttpRequest, HttpResponse);
static void handle_action(HttpRequest, HttpResponse);
static void handle_run(HttpRequest, HttpResponse);
static void is_monit_running(HttpRequest, HttpResponse);
static void do_service(HttpRequest, HttpResponse, Service_T);
static void print_alerts(HttpResponse, Mail_T);
static void print_buttons(HttpRequest, HttpResponse, Service_T);
static void print_service_rules_port(HttpResponse, Service_T);
static void print_service_rules_icmp(HttpResponse, Service_T);
static void print_service_rules_perm(HttpResponse, Service_T);
static void print_service_rules_uid(HttpResponse, Service_T);
static void print_service_rules_gid(HttpResponse, Service_T);
static void print_service_rules_timestamp(HttpResponse, Service_T);
static void print_service_rules_device(HttpResponse, Service_T);
static void print_service_rules_size(HttpResponse, Service_T);
static void print_service_rules_match(HttpResponse, Service_T);
static void print_service_rules_checksum(HttpResponse, Service_T);
static void print_service_rules_process(HttpResponse, Service_T);
static void print_service_rules_resource(HttpResponse, Service_T);
static void print_service_params_port(HttpResponse, Service_T);
static void print_service_params_icmp(HttpResponse, Service_T);
static void print_service_params_perm(HttpResponse, Service_T);
static void print_service_params_uid(HttpResponse, Service_T);
static void print_service_params_gid(HttpResponse, Service_T);
static void print_service_params_timestamp(HttpResponse, Service_T);
static void print_service_params_device(HttpResponse, Service_T);
static void print_service_params_size(HttpResponse, Service_T);
static void print_service_params_match(HttpResponse, Service_T);
static void print_service_params_checksum(HttpResponse, Service_T);
static void print_service_params_process(HttpResponse, Service_T);
static void print_service_params_resource(HttpResponse, Service_T);
static void print_status(HttpRequest, HttpResponse);
static void status_service_txt(Service_T, HttpResponse, short);
static char *get_service_status_html(Service_T);
static char *get_service_status_text(Service_T);
/**
* Implementation of doGet and doPost routines used by the cervlet
* processor module. This particilary cervlet will provide
* information about the monit deamon and programs monitored by
* monit.
*
* @author Jan-Henrik Haukeland,
* @author Martin Pala
* @author Christian Hopp
*
* @version \$Id: cervlet.c,v 1.224 2007/10/02 21:35:16 martinp Exp $
*
* @file
*/
/* ------------------------------------------------------------------ Public */
/**
* Callback hook to the Processor module for registering this modules
* doGet and doPost methods.
*/
void init_service() {
add_Impl(doGet, doPost);
}
/* ----------------------------------------------------------------- Private */
/**
* Called by the Processor (via the service method)
* to handle a POST request.
*/
static void doPost(HttpRequest req, HttpResponse res) {
if(ACTION(RUN)) {
handle_run(req, res);
} else {
handle_action(req, res);
}
}
/**
* Called by the Processor (via the service method)
* to handle a GET request.
*/
static void doGet(HttpRequest req, HttpResponse res) {
set_content_type(res, "text/html");
if(ACTION(HOME)) {
LOCK(Run.mutex)
do_home(req, res);
END_LOCK;
} else if(ACTION(RUN)) {
handle_run(req, res);
} else if(ACTION(TEST)) {
is_monit_running(req, res);
} else if(ACTION(VIEWLOG)) {
do_viewlog(req, res);
} else if(ACTION(ABOUT)) {
do_about(req, res);
} else if(ACTION(PING)) {
do_ping(req, res);
} else if(ACTION(PIXEL)) {
printPixel(res);
} else if(ACTION(STATUS)) {
print_status(req, res);
} else {
handle_action(req, res);
}
}
/* ----------------------------------------------------------------- Helpers */
static void is_monit_running(HttpRequest req, HttpResponse res) {
int status;
int monit= exist_daemon();
if(monit) {
status= SC_OK;
} else {
status= SC_GONE;
}
set_status(res, status);
}
static void do_home(HttpRequest req, HttpResponse res) {
char *uptime= Util_getUptime(Util_getProcessUptime(Run.pidfile), " ");
HEAD("", Run.polltime)
out_print(res,
""
" "
" "
"
Monit Service Manager"
" Monit is running on %s "
" with uptime, %s and monitoring: "
" | "
"
"
"
"
""
" "
"  | "
"
"
"
", Run.localhostname, uptime);
FREE(uptime);
do_home_system(req, res);
do_home_process(req, res);
do_home_device(req, res);
do_home_file(req, res);
do_home_fifo(req, res);
do_home_directory(req, res);
do_home_host(req, res);
FOOT
}
static void do_about(HttpRequest req, HttpResponse res) {
out_print(res,
"about monit"
"
"
"monit " VERSION "
");
out_print(res,
"");
out_print(res,
""
" "
"  |
");
out_print(res,
"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 3 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."
"
Please consider making a "
""
"donation and support our continued work with monit.
");
out_print(res,
"[Click here to go back to monit]"
"");
FOOT
}
static void do_ping(HttpRequest req, HttpResponse res) {
out_print(res, "pong");
}
static void do_runtime(HttpRequest req, HttpResponse res) {
int pid= exist_daemon();
HEAD("_runtime", 1000)
out_print(res,
"monit runtime status
");
out_print(res,""
"| Parameter | "
"Value |
");
out_print(res,
"| Host | %s |
",
Run.localhostname);
out_print(res,
"| Process id | %d |
", pid);
out_print(res,
"| Effective user running monit | "
"%s |
", Run.Env.user);
out_print(res,
"| Controlfile | %s |
", Run.controlfile);
if(Run.logfile)
out_print(res,
"| Logfile | %s |
", Run.logfile);
out_print(res,
"| Pidfile | %s |
", Run.pidfile);
out_print(res,
"| State file | %s |
", Run.statefile);
out_print(res,
"| Debug | %s |
",
Run.debug?"True":"False");
out_print(res,
"| Log | %s |
", Run.dolog?"True":"False");
out_print(res,
"| Use syslog | %s |
",
Run.use_syslog?"True":"False");
if(Run.eventlist_dir) {
char slots[STRLEN];
if(Run.eventlist_slots < 0)
snprintf(slots, STRLEN, "unlimited");
else
snprintf(slots, STRLEN, "%d", Run.eventlist_slots);
out_print(res,
"| Event queue | "
"base directory %s with %d slots |
",
Run.eventlist_dir, Run.eventlist_slots);
}
if(Run.collectors) {
Collector_T c= Run.collectors;
out_print(res, "| Collector server(s) | ");
for(c= Run.collectors; c; c= c->next)
{
out_print(res,
"%s with timeout %d seconds%s%s%s%s |
%s",
c->url->url,
c->timeout,
c->ssl.use_ssl?" ssl version ":"",
c->ssl.use_ssl?sslnames[c->ssl.version]:"",
c->ssl.certmd5?" server cert md5 sum ":"",
c->ssl.certmd5?c->ssl.certmd5:"",
c->next?"| | ":"");
}
printf("\n");
}
out_print(res, " |
| Mail server(s) | ");
if(Run.mailservers) {
MailServer_T mta= Run.mailservers;
for(mta= Run.mailservers; mta; mta= mta->next)
out_print(res, "%s:%d%s ",
mta->host, mta->port, mta->ssl.use_ssl?"(ssl)":"");
out_print(res, " |
");
} else {
out_print(res, "localhost");
}
if(Run.MailFormat.from)
out_print(res,
"| Default mail from | %s |
",
Run.MailFormat.from);
if(Run.MailFormat.subject)
out_print(res,
"| Default mail subject | %s |
",
Run.MailFormat.subject);
if(Run.MailFormat.message)
out_print(res,
"| Default mail message | %s |
",
Run.MailFormat.message);
out_print(res,
"| Poll time | %d seconds |
",
Run.polltime);
out_print(res,
"| httpd bind address | %s |
",
Run.bind_addr?Run.bind_addr:"Any/All");
out_print(res,
"| httpd portnumber | %d |
", Run.httpdport);
out_print(res,
"| httpd signature | %s |
",
Run.httpdsig?"True":"False");
out_print(res,
"| Use ssl encryption | %s |
",
Run.httpdssl?"True":"False");
if (Run.httpdssl) {
out_print(res,
"| PEM key/certificate file | %s |
",
Run.httpsslpem);
if (Run.httpsslclientpem!=NULL) {
out_print(res,
"| Client PEM key/certification"
" | %s |
", "Enabled");
out_print(res,
"| Client PEM key/certificate file"
" | %s |
", Run.httpsslclientpem);
} else {
out_print(res,
"| Client PEM key/certification"
" | %s |
", "Disabled");
}
out_print(res,
"| Allow self certified certificates "
" | %s |
", Run.allowselfcert?"True":"False");
}
out_print(res,
"| httpd auth. style | %s |
",
(Run.credentials!=NULL)&&(has_hosts_allow())?
"Basic Authentication and Host/Net allow list":
(Run.credentials!=NULL)?"Basic Authentication":
(has_hosts_allow())?"Host/Net allow list":
"No authentication");
print_alerts(res, Run.maillist);
out_print(res,"
");
if(!is_readonly(req)) {
out_print(res,
""
"");
out_print(res,
"| "
"Stop monit http server?"
" | "
""
""
" | ");
out_print(res,
""
"Force validate now?"
" | "
""
""
" | ");
if(Run.dolog && !Run.use_syslog) {
out_print(res,
""
"View monit logfile?"
" | "
""
""
" | ");
}
out_print(res,
"
"
"
");
}
FOOT
}
static void do_viewlog(HttpRequest req, HttpResponse res) {
if(is_readonly(req)) {
send_error(res, SC_FORBIDDEN,
"You do not have sufficent privilegs to access this page");
return;
}
HEAD("_viewlog", 100)
if(Run.dolog && !Run.use_syslog) {
struct stat sb;
if(!stat(Run.logfile, &sb)) {
FILE *f= fopen(Run.logfile, "r");
if(f) {
#define BUFSIZE 8192
int n;
char buf[BUFSIZE+1];
out_print(res, "
");
} else {
out_print(res, "Error opening logfile: %s", STRERROR);
}
} else {
out_print(res, "Error stating logfile: %s", STRERROR);
}
} else {
out_print(res,
"Cannot view logfile:
");
if(!Run.dolog) {
out_print(res, "monit was started without logging");
} else {
out_print(res, "monit uses syslog");
}
}
FOOT
}
static void handle_action(HttpRequest req, HttpResponse res) {
char *name= req->url;
const char *action;
Service_T s;
if(!(s = Util_getService(++name))) {
send_error(res, SC_BAD_REQUEST, "There is no service by that name");
return;
}
if((action = get_parameter(req, "action"))) {
if(is_readonly(req)) {
send_error(res, SC_FORBIDDEN,
"You do not have sufficent privilegs to access this page");
return;
}
if((s->doaction = Util_getAction(action)) == ACTION_IGNORE) {
send_error(res, SC_BAD_REQUEST, "Invalid action");
return;
}
LogInfo("%s service '%s' on user request\n", action, s->name);
Run.doaction = TRUE; /* set the global flag */
do_wakeupcall();
}
do_service(req, res, s);
}
static void handle_run(HttpRequest req, HttpResponse res) {
const char *action= get_parameter(req, "action");
if(action) {
if(is_readonly(req)) {
send_error(res, SC_FORBIDDEN,
"You do not have sufficent privilegs to access this page");
return;
}
if(IS(action, "validate")) {
LogInfo("The monit http server woke up on user request\n");
do_wakeupcall();
} else if(IS(action, "stop")) {
LogInfo("The monit http server stopped on user request\n");
send_error(res, SC_SERVICE_UNAVAILABLE,
"The monit http server is stopped");
stop_httpd();
return;
}
}
LOCK(Run.mutex)
do_runtime(req, res);
END_LOCK;
}
static void do_service(HttpRequest req, HttpResponse res, Service_T s) {
Dependant_T d;
char *status;
char time[STRLEN];
ASSERT(s);
LOCK(s->mutex)
HEAD(s->name, Run.polltime)
out_print(res,
"
%s status
"
""
""
"| Parameter | "
"Value | "
"
"
""
"| Name | "
"%s | "
"
",
servicetypes[s->type],
s->name);
if(s->path && *s->path)
out_print(res,
""
"| %s | "
"%s | "
"
",
pathnames[s->type],
s->path);
status= get_service_status_html(s);
out_print(res,
"| Status | %s |
", status);
FREE(status);
if(s->group)
out_print(res,
"| Group | %s |
",
s->group);
out_print(res,
"| Monitoring mode | %s |
", modenames[s->mode]);
out_print(res,
"| Monitoring status | %s"
" |
",
monitornames[s->monitor]);
for(d= s->dependantlist; d; d= d->next) {
if(d->dependant != NULL) {
out_print(res,
"| Depends on service | %s |
",
d->dependant, d->dependant);
}
}
if(s->start) {
int i= 0;
out_print(res, "| Start program | '");
while(s->start->arg[i]) {
if(i) out_print(res, " ");
out_print(res, "%s", s->start->arg[i++]);
}
out_print(res, "'");
if(s->start->has_uid)
out_print(res, " as uid %d", s->start->uid);
if(s->start->has_gid)
out_print(res, " as gid %d", s->start->gid);
out_print(res, " timeout %d cycle(s)", s->start->timeout);
out_print(res, " |
");
}
if(s->stop) {
int i= 0;
out_print(res, "| Stop program | '");
while(s->stop->arg[i]) {
if(i) out_print(res, " ");
out_print(res, "%s", s->stop->arg[i++]);
}
out_print(res, "'");
if(s->stop->has_uid)
out_print(res, " as uid %d", s->stop->uid);
if(s->stop->has_gid)
out_print(res, " as gid %d", s->stop->gid);
out_print(res, " timeout %d cycle(s)", s->stop->timeout);
out_print(res, " |
");
}
out_print(res,
"| Check service | every %d cycle |
",
s->every?s->every:1);
if(s->def_timeout && s->action_TIMEOUT) {
EventAction_T a= s->action_TIMEOUT;
out_print(res,
"| Timeout | "
"If %d restart within %d cycles then %s else if passed "
"then %s |
",
s->to_start,
s->to_cycle,
a->failed->description,
a->passed->description);
}
ctime_r(&s->collected, time);
out_print(res,
"| Data collected | %s |
",
time);
/* Parameters */
print_service_params_icmp(res, s);
print_service_params_port(res, s);
print_service_params_perm(res, s);
print_service_params_uid(res, s);
print_service_params_gid(res, s);
print_service_params_timestamp(res, s);
print_service_params_device(res, s);
print_service_params_size(res, s);
print_service_params_match(res, s);
print_service_params_checksum(res, s);
print_service_params_process(res, s);
print_service_params_resource(res, s);
/* Rules */
print_service_rules_icmp(res, s);
print_service_rules_port(res, s);
print_service_rules_perm(res, s);
print_service_rules_uid(res, s);
print_service_rules_gid(res, s);
print_service_rules_timestamp(res, s);
print_service_rules_device(res, s);
print_service_rules_size(res, s);
print_service_rules_match(res, s);
print_service_rules_checksum(res, s);
print_service_rules_process(res, s);
print_service_rules_resource(res, s);
print_alerts(res, s->maillist);
out_print(res, "
");
print_buttons(req, res, s);
FOOT
END_LOCK;
}
static void printPixel(HttpResponse res) {
static int l;
Socket_T S= res->S;
static unsigned char *pixel= NULL;
if(! pixel) {
pixel= xcalloc(sizeof(unsigned char), strlen(PIXEL_GIF));
l= decode_base64(pixel, PIXEL_GIF);
}
if (l) {
res->is_committed= TRUE;
socket_print(S, "HTTP/1.0 200 OK\r\n");
socket_print(S, "Content-length: %d\r\n", l);
socket_print(S, "Content-Type: image/gif\r\n");
socket_print(S, "Connection: close\r\n\r\n");
socket_write(S, pixel, l);
}
}
static void do_home_system(HttpRequest req, HttpResponse res) {
char *status;
Service_T s = Run.system;
status= get_service_status_html(s);
out_print(res,
"
"
""
""
"System | "
"Status | ");
if(Run.doprocess) {
out_print(res,
"Load | "
"CPU | "
"Memory | ");
}
out_print(res,
"
"
""
"| %s | "
"%s | ",
s->name, s->name,
status);
FREE(status);
if(Run.doprocess) {
out_print(res,
"[%.2f] [%.2f] [%.2f] | "
""
"%.1f%%us, %.1f%%sy"
#ifdef HAVE_CPU_WAIT
", %.1f%%wa"
#endif
" | "
"%.1f%% [%ld kB] | ",
systeminfo.loadavg[0], systeminfo.loadavg[1], systeminfo.loadavg[2],
systeminfo.total_cpu_user_percent/10., systeminfo.total_cpu_syst_percent/10.,
#ifdef HAVE_CPU_WAIT
systeminfo.total_cpu_wait_percent/10.,
#endif
systeminfo.total_mem_percent/10., systeminfo.total_mem_kbyte);
}
out_print(res,
"
"
"
");
}
static void do_home_process(HttpRequest req, HttpResponse res) {
Service_T s;
char *status;
int on= TRUE;
int header= TRUE;
for(s= servicelist_conf; s; s= s->next_conf) {
if(s->type != TYPE_PROCESS) continue;
if(header) {
out_print(res,
"
"
""
""
"Process | "
"Status | "
"Uptime | ");
if(Run.doprocess) {
out_print(res,
"CPU | "
"Memory | ");
}
out_print(res, "
");
header= FALSE;
}
status= get_service_status_html(s);
out_print(res,
""
"| %s | "
"%s | ",
on?"bgcolor=\"#EFEFEF\"":"",
s->name, s->name,
status);
FREE(status);
if(!Util_hasServiceStatus(s)) {
out_print(res,
"- | ");
if(Run.doprocess) {
out_print(res,
"- | "
"- | ");
}
} else {
char *uptime= Util_getUptime(s->inf->uptime, " ");
out_print(res,
"%s | ", uptime);
FREE(uptime);
if(Run.doprocess) {
out_print(res,
"%.1f%% | ",
(s->error & EVENT_RESOURCE)?" color='#ff0000'":"",
s->inf->cpu_percent/10.0);
out_print(res,
"%.1f%% [%ld kB] |
",
(s->error & EVENT_RESOURCE)?" color='#ff0000'":"",
s->inf->mem_percent/10.0, s->inf->mem_kbyte);
}
}
out_print(res, "");
on= on?FALSE:TRUE;
}
if(!header)
out_print(res, "
");
}
static void do_home_device(HttpRequest req, HttpResponse res) {
Service_T s;
char *status;
int on= TRUE;
int header= TRUE;
for(s= servicelist_conf; s; s= s->next_conf) {
if(s->type != TYPE_DEVICE) continue;
if(header) {
out_print(res,
"
"
""
""
"Device | "
"Status | "
"Space usage | "
"Inodes usage | "
"
");
header= FALSE;
}
status= get_service_status_html(s);
out_print(res,
""
"| %s | "
"%s | ",
on?"bgcolor=\"#EFEFEF\"":"",
s->name, s->name,
status);
FREE(status);
if(!Util_hasServiceStatus(s)) {
out_print(res,
"- [-] | "
"- [-] | ");
} else {
out_print(res,
"%.1f%% [%.1f MB] | ",
s->inf->space_percent/10.,
(float)s->inf->space_total / (float)1048576 * (float)s->inf->f_bsize);
if(s->inf->f_files > 0) {
out_print(res,
"%.1f%% [%ld objects] | ",
s->inf->inode_percent/10.,
s->inf->inode_total);
} else {
out_print(res,
"not supported by filesystem | ");
}
}
out_print(res, "
");
on= on?FALSE:TRUE;
}
if(!header)
out_print(res, "
");
}
static void do_home_file(HttpRequest req, HttpResponse res) {
Service_T s;
char *status;
int on= TRUE;
int header= TRUE;
for(s= servicelist_conf; s; s= s->next_conf) {
if(s->type != TYPE_FILE) continue;
if(header) {
out_print(res,
"
"
""
""
"File | "
"Status | "
"Size | "
"Permission | "
"UID | "
"GID | "
"
");
header= FALSE;
}
status= get_service_status_html(s);
out_print(res,
""
"| %s | "
"%s | ",
on?"bgcolor=\"#EFEFEF\"":"",
s->name, s->name,
status);
FREE(status);
if(!Util_hasServiceStatus(s)) {
out_print(res,
"- | "
"- | "
"- | "
"- | ");
} else {
out_print(res,
"%llu B | "
"%04o | "
"%d | "
"%d | ",
(unsigned long long)s->inf->st_size,
s->inf->st_mode & 07777,
s->inf->st_uid,
s->inf->st_gid);
}
out_print(res, "
");
on= on?FALSE:TRUE;
}
if(!header)
out_print(res, "
");
}
static void do_home_fifo(HttpRequest req, HttpResponse res) {
Service_T s;
char *status;
int on= TRUE;
int header= TRUE;
for(s= servicelist_conf; s; s= s->next_conf) {
if(s->type != TYPE_FIFO) continue;
if(header) {
out_print(res,
"
"
""
""
"Fifo | "
"Status | "
"Permission | "
"UID | "
"GID | "
"
");
header= FALSE;
}
status= get_service_status_html(s);
out_print(res,
""
"| %s | "
"%s | ",
on?"bgcolor=\"#EFEFEF\"":"",
s->name, s->name,
status);
FREE(status);
if(!Util_hasServiceStatus(s)) {
out_print(res,
"- | "
"- | "
"- | ");
} else {
out_print(res,
"%o | "
"%d | "
"%d | ",
s->inf->st_mode & 07777,
s->inf->st_uid,
s->inf->st_gid);
}
out_print(res, "
");
on= on?FALSE:TRUE;
}
if(!header)
out_print(res, "
");
}
static void do_home_directory(HttpRequest req, HttpResponse res) {
Service_T s;
char *status;
int on= TRUE;
int header= TRUE;
for(s= servicelist_conf; s; s= s->next_conf) {
if(s->type != TYPE_DIRECTORY) continue;
if(header) {
out_print(res,
"
"
""
""
"Directory | "
"Status | "
"Permission | "
"UID | "
"GID | "
"
");
header= FALSE;
}
status= get_service_status_html(s);
out_print(res,
""
"| %s | "
"%s | ",
on?"bgcolor=\"#EFEFEF\"":"",
s->name, s->name,
status);
FREE(status);
if(!Util_hasServiceStatus(s)) {
out_print(res,
"- | "
"- | "
"- | ");
} else {
out_print(res,
"%o | "
"%d | "
"%d | ",
s->inf->st_mode & 07777,
s->inf->st_uid,
s->inf->st_gid);
}
out_print(res, "
");
on= on?FALSE:TRUE;
}
if(!header)
out_print(res, "
");
}
static void do_home_host(HttpRequest req, HttpResponse res) {
Service_T s;
Icmp_T icmp;
Port_T port;
char *status;
int on= TRUE;
int header= TRUE;
for(s= servicelist_conf; s; s= s->next_conf) {
if(s->type != TYPE_HOST) continue;
if(header) {
out_print(res,
"
"
""
""
"Host | "
"Status | "
"Protocol(s) | "
"
");
header= FALSE;
}
status= get_service_status_html(s);
out_print(res,
""
"| %s | "
"%s | ",
on?"bgcolor=\"#EFEFEF\"":"",
s->name, s->name,
status);
FREE(status);
if(!Util_hasServiceStatus(s)) {
out_print(res,
"- | ");
} else {
out_print(res,
"");
if(s->icmplist) {
for(icmp= s->icmplist; icmp; icmp= icmp->next) {
if(icmp != s->icmplist)
out_print(res, " | ");
out_print(res, "[ICMP %s]",
(icmp->is_available)?"":" color='#ff0000'",
icmpnames[icmp->type]);
}
}
if(s->icmplist && s->portlist)
out_print(res, " | ");
if(s->portlist) {
for(port= s->portlist; port; port= port->next) {
if(port != s->portlist)
out_print(res, " | ");
out_print(res, "[%s] at port %d",
(port->is_available)?"":" color='#ff0000'",
port->protocol->name, port->port);
}
}
out_print(res, " | ");
}
out_print(res, "
");
on= on?FALSE:TRUE;
}
if(!header)
out_print(res, "
");
}
/* ------------------------------------------------------------------------- */
static void print_alerts(HttpResponse res, Mail_T s) {
Mail_T r;
for(r= s; r; r= r->next) {
out_print(res,
"| Alert mail to | "
"%s |
", r->to?r->to:"");
out_print(res, "| Alert on | ");
if(r->events == EVENT_NULL) {
out_print(res, "No events");
} else if(r->events == EVENT_ALL) {
out_print(res, "All events");
} else {
if(IS_EVENT_SET(r->events, EVENT_CHANGED))
out_print(res, "Change ");
if(IS_EVENT_SET(r->events, EVENT_CHECKSUM))
out_print(res, "Checksum ");
if(IS_EVENT_SET(r->events, EVENT_CONNECTION))
out_print(res, "Connection ");
if(IS_EVENT_SET(r->events, EVENT_DATA))
out_print(res, "Data ");
if(IS_EVENT_SET(r->events, EVENT_EXEC))
out_print(res, "Exec ");
if(IS_EVENT_SET(r->events, EVENT_GID))
out_print(res, "Gid ");
if(IS_EVENT_SET(r->events, EVENT_ICMP))
out_print(res, "Icmp ");
if(IS_EVENT_SET(r->events, EVENT_INSTANCE))
out_print(res, "Instance ");
if(IS_EVENT_SET(r->events, EVENT_INVALID))
out_print(res, "Invalid ");
if(IS_EVENT_SET(r->events, EVENT_MATCH))
out_print(res, "Match ");
if(IS_EVENT_SET(r->events, EVENT_NONEXIST))
out_print(res, "Nonexist ");
if(IS_EVENT_SET(r->events, EVENT_PERMISSION))
out_print(res, "Permission ");
if(IS_EVENT_SET(r->events, EVENT_RESOURCE))
out_print(res, "Resource ");
if(IS_EVENT_SET(r->events, EVENT_SIZE))
out_print(res, "Size ");
if(IS_EVENT_SET(r->events, EVENT_MATCH))
out_print(res, "Match ");
if(IS_EVENT_SET(r->events, EVENT_TIMEOUT))
out_print(res, "Timeout ");
if(IS_EVENT_SET(r->events, EVENT_TIMESTAMP))
out_print(res, "Timestamp ");
if(IS_EVENT_SET(r->events, EVENT_UID))
out_print(res, "Uid ");
}
out_print(res, " |
");
if(r->reminder) {
out_print(res,
"| Alert reminder | %u cycles |
",
r->reminder);
}
}
}
static void print_buttons(HttpRequest req, HttpResponse res, Service_T s) {
if(is_readonly(req)) {
/*
* A read-only REMOTE_USER does not get access to these buttons
*/
return;
}
out_print(res, "",
s->name,
s->monitor?"unmonitor":"monitor",
s->monitor?"Disable monitoring":"Enable monitoring");
}
static void print_service_rules_port(HttpResponse res, Service_T s) {
if(s->portlist) {
char ratio1[STRLEN];
char ratio2[STRLEN];
Port_T p;
EventAction_T a;
for(p= s->portlist; p; p= p->next) {
a= p->action;
Util_getEventratio(a->failed, ratio1);
Util_getEventratio(a->passed, ratio2);
if(p->family == AF_INET) {
out_print(res,
"| Port | "
"If failed %s:%d%s [%s via %s] with timeout %d seconds %s then %s "
"else if passed %s then %s |
",
p->hostname, p->port, p->request?p->request:"",
p->protocol->name, Util_portTypeDescription(p),
p->timeout,
ratio1, a->failed->description,
ratio2, a->passed->description);
if(p->SSL.certmd5 != NULL)
out_print(res,
"| Server certificate md5 sum | %s |
",
p->SSL.certmd5);
} else if(p->family == AF_UNIX) {
out_print(res,
"| Unix Socket | "
"If failed %s [%s] with timeout %ds %s then %s else if passed %s then %s"
" |
",
p->pathname, p->protocol->name, p->timeout,
ratio1, a->failed->description,
ratio2, a->passed->description);
}
}
}
}
static void print_service_rules_icmp(HttpResponse res, Service_T s) {
if(s->icmplist) {
char ratio1[STRLEN];
char ratio2[STRLEN];
Icmp_T i;
EventAction_T a;
for(i= s->icmplist; i; i= i->next) {
a= i->action;
Util_getEventratio(a->failed, ratio1);
Util_getEventratio(a->passed, ratio2);
out_print(res,
"| ICMP | "
"If failed %s count %d with timeout %d seconds %s then %s else if passed %s then %s"
" |
",
icmpnames[i->type], i->count, i->timeout,
ratio1, a->failed->description,
ratio2, a->passed->description);
}
}
}
static void print_service_rules_perm(HttpResponse res, Service_T s) {
if(s->perm) {
char ratio1[STRLEN];
char ratio2[STRLEN];
EventAction_T a= s->perm->action;
Util_getEventratio(a->failed, ratio1);
Util_getEventratio(a->passed, ratio2);
out_print(res, "| Associated permission | "
"If failed %o %s then %s else if passed %s then %s |
",
s->perm->perm,
ratio1, a->failed->description,
ratio2, a->passed->description);
}
}
static void print_service_rules_uid(HttpResponse res, Service_T s) {
if(s->uid) {
char ratio1[STRLEN];
char ratio2[STRLEN];
EventAction_T a= s->uid->action;
Util_getEventratio(a->failed, ratio1);
Util_getEventratio(a->passed, ratio2);
out_print(res, "| Associated UID | "
"If failed %d %s then %s else if passed %s then %s |
",
(int)s->uid->uid,
ratio1, a->failed->description,
ratio2, a->passed->description);
}
}
static void print_service_rules_gid(HttpResponse res, Service_T s) {
if(s->gid) {
char ratio1[STRLEN];
char ratio2[STRLEN];
EventAction_T a= s->gid->action;
Util_getEventratio(a->failed, ratio1);
Util_getEventratio(a->passed, ratio2);
out_print(res, "| Associated GID | "
"If failed %d %s then %s else if passed %s then %s |
",
(int)s->gid->gid,
ratio1, a->failed->description,
ratio2, a->passed->description);
}
}
static void print_service_rules_timestamp(HttpResponse res, Service_T s) {
if(s->timestamplist) {
char ratio1[STRLEN];
char ratio2[STRLEN];
Timestamp_T t;
EventAction_T a;
for(t= s->timestamplist; t; t= t->next) {
a= t->action;
Util_getEventratio(a->failed, ratio1);
Util_getEventratio(a->passed, ratio2);
if(t->test_changes) {
out_print(res,
"| Associated timestamp | If changed %s then %s |
",
ratio1, a->failed->description);
} else {
out_print(res,
"| Associated timestamp | "
"If %s %d second(s) %s then %s else if passed %s then %s |
",
operatornames[t->operator], t->time,
ratio1, a->failed->description,
ratio2, a->passed->description);
}
}
}
}
static void print_service_rules_device(HttpResponse res, Service_T s) {
if(s->type == TYPE_DEVICE) {
char ratio1[STRLEN];
out_print(res, "| Filesystem flags | If changed %s then %s |
\n",
Util_getEventratio(s->action_FSFLAG->failed, ratio1),
s->action_FSFLAG->failed->description);
}
if(s->devicelist) {
char ratio1[STRLEN];
char ratio2[STRLEN];
Device_T dl;
EventAction_T a;
for(dl= s->devicelist; dl; dl= dl->next) {
a= dl->action;
Util_getEventratio(a->failed, ratio1);
Util_getEventratio(a->passed, ratio2);
if(dl->resource == RESOURCE_ID_INODE) {
if(dl->limit_absolute > -1) {
out_print(res,
"| Inodes usage limit | If %s %ld %s "
"then %s else if passed %s then %s |
",
operatornames[dl->operator],
dl->limit_absolute,
ratio1, a->failed->description,
ratio2, a->passed->description);
} else {
out_print(res,
"| Inodes usage limit | If %s %.1f%% %s "
"then %s else if passed %s then %s |
",
operatornames[dl->operator],
dl->limit_percent/10.,
ratio1, a->failed->description,
ratio2, a->passed->description);
}
} else if(dl->resource == RESOURCE_ID_SPACE) {
if(dl->limit_absolute > -1) {
out_print(res,
"| Space usage limit | If %s %ld blocks %s "
"then %s else if passed %s then %s |
",
operatornames[dl->operator],
dl->limit_absolute,
ratio1, a->failed->description,
ratio2, a->passed->description);
} else {
out_print(res,
"| Space usage limit | If %s %.1f%% %s "
"then %s else if passed %s then %s |
",
operatornames[dl->operator],
dl->limit_percent/10.,
ratio1, a->failed->description,
ratio2, a->passed->description);
}
}
}
}
}
static void print_service_rules_size(HttpResponse res, Service_T s) {
if(s->sizelist) {
char ratio1[STRLEN];
char ratio2[STRLEN];
Size_T sl;
EventAction_T a;
for(sl= s->sizelist; sl; sl= sl->next) {
a= sl->action;
Util_getEventratio(a->failed, ratio1);
Util_getEventratio(a->passed, ratio2);
if(sl->test_changes) {
out_print(res,
"| Associated size | If changed %s then %s |
",
ratio1, a->failed->description);
} else {
out_print(res,
"| Associated size | "
"If %s %llu byte(s) %s then %s else if passed %s then %s |
",
operatornames[sl->operator], sl->size,
ratio1, a->failed->description,
ratio2, a->passed->description);
}
}
}
}
static void print_service_rules_match(HttpResponse res, Service_T s) {
if(s->matchlist) {
char ratio1[STRLEN];
Match_T ml;
EventAction_T a;
for(ml= s->matchlist; ml; ml= ml->next) {
a= ml->action;
Util_getEventratio(a->failed, ratio1);
out_print(res,
"| Associated regex | If %s match "
"\"%s\" %s then %s |
",
ml->not?"not ":"", ml->match_string,
ratio1, a->failed->description);
}
}
}
static void print_service_rules_checksum(HttpResponse res, Service_T s) {
if(s->checksum) {
char ratio1[STRLEN];
char ratio2[STRLEN];
Checksum_T cs= s->checksum;
EventAction_T a= cs->action;
Util_getEventratio(a->failed, ratio1);
Util_getEventratio(a->passed, ratio2);
if(cs->test_changes) {
out_print(res,
"| Associated checksum | if changed %s %s then %s |
",
checksumnames[cs->type],
ratio1, a->failed->description);
} else {
out_print(res, "| Associated checksum | "
"if failed %s(%s) %s then %s else if passed %s then %s |
",
cs->hash, checksumnames[cs->type],
ratio1, a->failed->description,
ratio2, a->passed->description);
}
}
}
static void print_service_rules_process(HttpResponse res, Service_T s) {
if(s->type == TYPE_PROCESS) {
char ratio1[STRLEN];
out_print(res, "| Pid | If changed %s then %s |
\n",
Util_getEventratio(s->action_PID->failed, ratio1),
s->action_PID->failed->description);
out_print(res, "| Ppid | If changed %s then %s |
\n",
Util_getEventratio(s->action_PPID->failed, ratio1),
s->action_PPID->failed->description);
}
}
static void print_service_rules_resource(HttpResponse res, Service_T s) {
if(s->resourcelist) {
char ratio1[STRLEN];
char ratio2[STRLEN];
Resource_T q;
EventAction_T a;
for (q= s->resourcelist; q; q= q->next) {
a= q->action;
Util_getEventratio(a->failed, ratio1);
Util_getEventratio(a->passed, ratio2);
switch (q->resource_id) {
case RESOURCE_ID_CPU_PERCENT:
out_print(res,"| CPU usage limit | "
"If %s %.1f%% %s then %s "
"else if passed %s then %s |
",
operatornames[q->operator],
q->limit/10.0,
ratio1, a->failed->description,
ratio2, a->passed->description);
break;
case RESOURCE_ID_CPUUSER:
out_print(res,"| CPU user limit | "
"If %s %.1f%% %s then %s "
"else if passed %s then %s |
",
operatornames[q->operator],
q->limit/10.0,
ratio1, a->failed->description,
ratio2, a->passed->description);
break;
case RESOURCE_ID_CPUSYSTEM:
out_print(res,"| CPU system limit | "
"If %s %.1f%% %s then %s "
"else if passed %s then %s |
",
operatornames[q->operator],
q->limit/10.0,
ratio1, a->failed->description,
ratio2, a->passed->description);
break;
case RESOURCE_ID_CPUWAIT:
out_print(res,"| CPU wait limit | "
"If %s %.1f%% %s then %s "
"else if passed %s then %s |
",
operatornames[q->operator],
q->limit/10.0,
ratio1, a->failed->description,
ratio2, a->passed->description);
break;
case RESOURCE_ID_MEM_PERCENT:
out_print(res,"| Memory usage limit | "
"If %s %.1f%% %s then %s "
"else if passed %s then %s |
",
operatornames[q->operator],
q->limit/10.0,
ratio1, a->failed->description,
ratio2, a->passed->description);
break;
case RESOURCE_ID_MEM_KBYTE:
out_print(res,"| Memory amount limit | "
"If %s %ld %s then %s "
"else if passed %s then %s |
",
operatornames[q->operator],
q->limit,
ratio1, a->failed->description,
ratio2, a->passed->description);
break;
case RESOURCE_ID_LOAD1:
out_print(res,"| Load average (1min) | "
"If %s %.1f %s then %s "
"else if passed %s then %s |
",
operatornames[q->operator],
q->limit/10.0,
ratio1, a->failed->description,
ratio2, a->passed->description);
break;
case RESOURCE_ID_LOAD5:
out_print(res,"| Load average (5min) | "
"If %s %.1f %s then %s else if passed %s "
"then %s |
",
operatornames[q->operator],
q->limit/10.0,
ratio1, a->failed->description,
ratio2, a->passed->description);
break;
case RESOURCE_ID_LOAD15:
out_print(res,"| Load average (15min) | "
"If %s %.1f %s then %s else if passed %s "
"then %s |
",
operatornames[q->operator],
q->limit/10.0,
ratio1, a->failed->description,
ratio2, a->passed->description);
break;
case RESOURCE_ID_CHILDREN:
out_print(res,"| Children | "
"If %s %d %s then %s else if passed %s "
"then %s |
",
operatornames[q->operator],
q->limit,
ratio1, a->failed->description,
ratio2, a->passed->description);
break;
case RESOURCE_ID_TOTAL_MEM_KBYTE:
out_print(res,"| Memory amount limit (incl. children) | "
"If %s %d %s then %s else if passed %s then %s"
" |
",
operatornames[q->operator],
q->limit,
ratio1, a->failed->description,
ratio2, a->passed->description);
break;
case RESOURCE_ID_TOTAL_MEM_PERCENT:
out_print(res,"| Memory usage limit (incl. children) | "
"If %s %.1f%% %s then %s else if passed %s then %s"
" |
",
operatornames[q->operator],
q->limit/10.0,
ratio1, a->failed->description,
ratio2, a->passed->description);
break;
}
}
}
}
static void print_service_params_port(HttpResponse res, Service_T s) {
if((s->type == TYPE_HOST ||
s->type == TYPE_PROCESS) &&
s-> portlist) {
Port_T p;
if(!Util_hasServiceStatus(s)) {
for(p= s->portlist; p; p= p->next)
if(p->family == AF_INET) {
out_print(res,
"| Port Response time | - |
");
} else if(p->family == AF_UNIX) {
out_print(res,
"| Unix Socket Response time | - |
");
}
} else {
for(p= s->portlist; p; p= p->next) {
if(p->family == AF_INET) {
if(!p->is_available) {
out_print(res,
"| Port Response time | "
"connection failed to %s:%d%s [%s via %s]"
" |
",
p->hostname, p->port, p->request?p->request:"",
p->protocol->name, Util_portTypeDescription(p));
} else {
out_print(res,
"| Port Response time | "
"%.3fs to %s:%d%s [%s via %s] |
",
p->response, p->hostname, p->port, p->request?p->request:"",
p->protocol->name, Util_portTypeDescription(p));
}
} else if(p->family == AF_UNIX) {
if(!p->is_available) {
out_print(res,
"| Unix Socket Response time | "
"connection failed to %s [%s]"
" |
",
p->pathname, p->protocol->name);
} else {
out_print(res,
"| Unix Socket Response time | "
"%.3fs to %s [%s] |
",
p->response, p->pathname, p->protocol->name);
}
}
}
}
}
}
static void print_service_params_icmp(HttpResponse res, Service_T s) {
if(s->type == TYPE_HOST && s->icmplist) {
Icmp_T i;
if(!Util_hasServiceStatus(s)) {
for(i= s->icmplist; i; i= i->next)
out_print(res, "| ICMP Response time | - |
");
} else {
for(i= s->icmplist; i; i= i->next) {
if(!i->is_available) {
out_print(res,
"| ICMP Response time | "
"connection failed [%s] |
", icmpnames[i->type]);
} else {
out_print(res,
"| ICMP Response time | %.3fs [%s] |
",
i->response, icmpnames[i->type]);
}
}
}
}
}
static void print_service_params_perm(HttpResponse res, Service_T s) {
if(s->type == TYPE_FILE ||
s->type == TYPE_FIFO ||
s->type == TYPE_DIRECTORY ||
s->type == TYPE_DEVICE) {
if(!Util_hasServiceStatus(s)) {
out_print(res, "| Permission | - |
");
} else {
out_print(res,
"| Permission | %o |
",
(s->error & EVENT_PERMISSION)?" color='#ff0000'":"",
s->inf->st_mode & 07777);
}
}
}
static void print_service_params_uid(HttpResponse res, Service_T s) {
if(s->type == TYPE_FILE ||
s->type == TYPE_FIFO ||
s->type == TYPE_DIRECTORY ||
s->type == TYPE_DEVICE) {
if(!Util_hasServiceStatus(s)) {
out_print(res, "| UID | - |
");
} else {
out_print(res,
"| UID | %d |
",
(s->error & EVENT_UID)?" color='#ff0000'":"",
(int)s->inf->st_uid);
}
}
}
static void print_service_params_gid(HttpResponse res, Service_T s) {
if(s->type == TYPE_FILE ||
s->type == TYPE_FIFO ||
s->type == TYPE_DIRECTORY ||
s->type == TYPE_DEVICE) {
if(!Util_hasServiceStatus(s)) {
out_print(res, "| GID | - |
");
} else {
out_print(res,
"| GID | %d |
",
(s->error & EVENT_GID)?" color='#ff0000'":"",
(int)s->inf->st_gid);
}
}
}
static void print_service_params_timestamp(HttpResponse res, Service_T s) {
if(s->type == TYPE_FILE ||
s->type == TYPE_FIFO ||
s->type == TYPE_DIRECTORY) {
if(!Util_hasServiceStatus(s)) {
out_print(res, "| Timestamp | - |
");
} else {
char time[STRLEN];
ctime_r(&s->inf->timestamp, time);
out_print(res,
"| Timestamp | %s |
",
(s->error & EVENT_TIMESTAMP)?" color='#ff0000'":"", time);
}
}
}
static void print_service_params_device(HttpResponse res, Service_T s) {
if(s->type == TYPE_DEVICE) {
if(!Util_hasServiceStatus(s)) {
out_print(res,
"| Filesystem flags | - |
");
out_print(res,
"| Blocks total | - |
");
out_print(res,
"| Blocks free for non superuser | - |
");
out_print(res,
"| Blocks free total | - |
");
out_print(res,
"| Block size | - |
");
out_print(res,
"| Inodes total | - |
");
out_print(res,
"| Inodes free | - |
");
} else {
out_print(res,
"| Filesystem flags | %#lx |
",
s->inf->flags);
out_print(res,
"| Blocks total | %ld [%.1f MB] |
",
s->inf->f_blocks,
(float) s->inf->f_blocks/1048576*s->inf->f_bsize);
out_print(res,
"| Blocks free for non superuser | "
"%ld [%.1f MB] [%.1f%%] |
",
s->inf->f_blocksfree,
(float)s->inf->f_blocksfree / (float)1048576 * (float)s->inf->f_bsize,
(float)100 * (float)s->inf->f_blocksfree / (float)s->inf->f_blocks);
out_print(res,
"| Blocks free total | "
"%ld [%.1f MB] [%.1f%%] |
",
(s->error & EVENT_RESOURCE)?" color='#ff0000'":"",
s->inf->f_blocksfreetotal,
(float)s->inf->f_blocksfreetotal / (float)1048576 * (float)s->inf->f_bsize,
(float)100 * (float)s->inf->f_blocksfreetotal / (float)s->inf->f_blocks);
out_print(res,
"| Block size | %ld B |
", s->inf->f_bsize);
if(s->inf->f_files > 0) {
out_print(res,
"| Inodes total | %ld |
", s->inf->f_files);
out_print(res,
"| Inodes free | %ld [%.1f%%] |
",
(s->error & EVENT_RESOURCE)?" color='#ff0000'":"",
s->inf->f_filesfree,
(float)100 * (float)s->inf->f_filesfree / (float)s->inf->f_files);
}
}
}
}
static void print_service_params_size(HttpResponse res, Service_T s) {
if(s->type == TYPE_FILE) {
if(!Util_hasServiceStatus(s)) {
out_print(res,
"| Size | - |
");
} else {
out_print(res,
"| Size | %llu B |
",
(s->error & EVENT_SIZE)?" color='#ff0000'":"",
(unsigned long long) s->inf->st_size);
}
}
}
static void print_service_params_match(HttpResponse res, Service_T s) {
if(s->type == TYPE_FILE) {
if(!Util_hasServiceStatus(s)) {
out_print(res,
"| Match regex | - |
");
} else {
out_print(res,
"| Match regex | %s |
",
(s->error & EVENT_MATCH)?" color='#ff0000'":"",
(s->error & EVENT_MATCH)?"yes":"no");
}
}
}
static void print_service_params_checksum(HttpResponse res, Service_T s) {
if(s->type == TYPE_FILE && s->checksum) {
if(!Util_hasServiceStatus(s)) {
out_print(res, "| Checksum | - |
");
} else {
out_print(res,
"| Checksum | %s(%s) |
",
(s->error & EVENT_CHECKSUM)?" color='#ff0000'":"", s->inf->cs_sum,
checksumnames[s->checksum->type]);
}
}
}
static void print_service_params_process(HttpResponse res, Service_T s) {
if(s->type == TYPE_PROCESS) {
if(!Util_hasServiceStatus(s)) {
out_print(res,
"| Process id | - |
"
"| Parent process id | - |
"
"| Process uptime | - |
");
} else {
char *uptime;
out_print(res,
"| Process id | %d |
",
s->inf->pid);
out_print(res,
"| Parent process id | %d |
",
s->inf->ppid);
uptime= Util_getUptime(s->inf->uptime, " ");
out_print(res,
"| Process uptime | %s |
",
uptime);
FREE(uptime);
}
}
}
static void print_service_params_resource(HttpResponse res, Service_T s) {
if(Run.doprocess && (s->type == TYPE_PROCESS || s->type == TYPE_SYSTEM) ) {
if(!Util_hasServiceStatus(s)) {
if(s->type == TYPE_PROCESS) {
out_print(res,
"| CPU usage | - |
"
"| Memory usage | - |
"
"| Children | - |
"
"| Total CPU usage (incl. children) | - |
"
"| Total memory usage (incl. children) | - |
");
} else if(s->type == TYPE_SYSTEM) {
out_print(res,
"| Load average | - |
"
"| CPU usage | - |
"
"| Memory usage | - |
");
}
} else {
if(s->type == TYPE_PROCESS) {
out_print(res,
"| CPU usage | %.1f%% |
",
(s->error & EVENT_RESOURCE)?" color='#ff0000'":"",
s->inf->cpu_percent/10.0);
out_print(res,
"| Memory usage | %.1f%% [%ldkB] |
",
(s->error & EVENT_RESOURCE)?" color='#ff0000'":"",
s->inf->mem_percent/10.0, s->inf->mem_kbyte);
out_print(res,
"| Children | %d |
",
(s->error & EVENT_RESOURCE)?" color='#ff0000'":"",
s->inf->children);
out_print(res,
"| Total CPU usage (incl. children) | %.1f%%"
" |
",
(s->error & EVENT_RESOURCE)?" color='#ff0000'":"",
s->inf->total_cpu_percent/10.0);
out_print(res,
"| Total memory usage (incl. children) | "
"%.1f%% [%ldkB] |
",
(s->error & EVENT_RESOURCE)?" color='#ff0000'":"",
s->inf->total_mem_percent/10.0, s->inf->total_mem_kbyte);
} else if(s->type == TYPE_SYSTEM) {
out_print(res,
"| Load average | [%.2f] [%.2f] [%.2f] |
",
(s->error & EVENT_RESOURCE)?" color='#ff0000'":"",
systeminfo.loadavg[0],
systeminfo.loadavg[1],
systeminfo.loadavg[2]);
out_print(res,
"| CPU usage | %.1f%%us %.1f%%sy"
#ifdef HAVE_CPU_WAIT
" %.1f%%wa"
#endif
"%s",
(s->error & EVENT_RESOURCE)?" color='#ff0000'":"",
systeminfo.total_cpu_user_percent/10.,
systeminfo.total_cpu_syst_percent/10.,
#ifdef HAVE_CPU_WAIT
systeminfo.total_cpu_wait_percent/10.,
#endif
" |
");
out_print(res,
"| Memory usage | %ld kB [%.1f%%] |
",
(s->error & EVENT_RESOURCE)?" color='#ff0000'":"",
systeminfo.total_mem_kbyte,
systeminfo.total_mem_percent/10.);
}
}
}
}
static int is_readonly(HttpRequest req) {
if(req->remote_user) {
Auth_T user_creds = Util_getUserCredentials(req->remote_user);
return ( user_creds?user_creds->is_readonly:TRUE );
}
return FALSE;
}
/* ----------------------------------------------------------- Status output */
/* Print status in the given format. Text status is default. */
static void print_status(HttpRequest req, HttpResponse res)
{
Service_T s;
short level = LEVEL_FULL;
const char *stringFormat = get_parameter(req, "format");
const char *stringLevel = get_parameter(req, "level");
if(stringLevel && Util_startsWith(stringLevel, LEVEL_NAME_SUMMARY))
{
level = LEVEL_SUMMARY;
}
if(stringFormat && Util_startsWith(stringFormat, "xml"))
{
char *D = status_xml(NULL, level);
out_print(res, "%s", D);
FREE(D);
set_content_type(res, "text/xml");
}
else
{
char *uptime = Util_getUptime(Util_getProcessUptime(Run.pidfile), " ");
out_print(res, "The monit daemon %s uptime: %s\n\n", VERSION, uptime);
FREE(uptime);
for(s= servicelist_conf; s; s= s->next_conf)
{
status_service_txt(s, res, level);
}
set_content_type(res, "text/plain");
}
}
static void status_service_txt(Service_T s, HttpResponse res, short level) {
char *status = get_service_status_text(s);
if(level == LEVEL_SUMMARY)
{
char prefix[STRLEN];
snprintf(prefix, STRLEN, "%s '%s'", servicetypes[s->type], s->name);
out_print(res, "%-35s %s\n", prefix, status);
}
else
{
char time[STRLEN];
out_print(res,
"%s '%s'\n"
" %-33s %s\n"
" %-33s %s\n",
servicetypes[s->type], s->name,
"status", status,
"monitoring status", monitornames[s->monitor]);
if(Util_hasServiceStatus(s)) {
if(s->type == TYPE_FILE ||
s->type == TYPE_FIFO ||
s->type == TYPE_DIRECTORY ||
s->type == TYPE_DEVICE) {
out_print(res,
" %-33s %o\n"
" %-33s %d\n"
" %-33s %d\n",
"permission", s->inf->st_mode & 07777,
"uid", (int)s->inf->st_uid,
"gid", (int)s->inf->st_gid);
}
if(s->type == TYPE_FILE ||
s->type == TYPE_FIFO ||
s->type == TYPE_DIRECTORY) {
ctime_r(&s->inf->timestamp, time);
out_print(res,
" %-33s %s",
"timestamp", time);
}
if(s->type == TYPE_FILE) {
out_print(res,
" %-33s %llu B\n",
"size", (unsigned long long) s->inf->st_size);
if(s->checksum) {
out_print(res,
" %-33s %s(%s)\n",
"checksum", s->inf->cs_sum,
checksumnames[s->checksum->type]);
}
}
if(s->type == TYPE_DEVICE) {
out_print(res,
" %-33s %#lx\n"
" %-33s %ld B\n"
" %-33s %ld [%.1f MB]\n"
" %-33s %ld [%.1f MB] [%.1f%%]\n"
" %-33s %ld [%.1f MB] [%.1f%%]\n",
"filesystem flags",
s->inf->flags,
"block size",
s->inf->f_bsize,
"blocks total",
s->inf->f_blocks,
((float)s->inf->f_blocks/(float)1048576*
(float)s->inf->f_bsize),
"blocks free for non superuser",
s->inf->f_blocksfree,
((float)s->inf->f_blocksfree/(float)1048576*
(float)s->inf->f_bsize),
((float)100*(float)s->inf->f_blocksfree/
(float)s->inf->f_blocks),
"blocks free total",
s->inf->f_blocksfreetotal,
((float)s->inf->f_blocksfreetotal/(float)1048576*
(float)s->inf->f_bsize),
((float)100*(float)s->inf->f_blocksfreetotal/
(float)s->inf->f_blocks));
if(s->inf->f_files > 0) {
out_print(res,
" %-33s %ld\n"
" %-33s %ld [%.1f%%]\n",
"inodes total",
s->inf->f_files,
"inodes free",
s->inf->f_filesfree,
((float)100*(float)s->inf->f_filesfree/
(float)s->inf->f_files));
}
}
if(s->type == TYPE_PROCESS) {
char *uptime= Util_getUptime(s->inf->uptime, " ");
out_print(res,
" %-33s %d\n"
" %-33s %d\n"
" %-33s %s\n",
"pid", s->inf->pid,
"parent pid", s->inf->ppid,
"uptime", uptime);
FREE(uptime);
if(Run.doprocess) {
out_print(res,
" %-33s %d\n"
" %-33s %ld\n"
" %-33s %ld\n"
" %-33s %.1f%%\n"
" %-33s %.1f%%\n"
" %-33s %.1f%%\n"
" %-33s %.1f%%\n",
"childrens", s->inf->children,
"memory kilobytes", s->inf->mem_kbyte,
"memory kilobytes total", s->inf->total_mem_kbyte,
"memory percent", s->inf->mem_percent/10.0,
"memory percent total", s->inf->total_mem_percent/10.0,
"cpu percent", s->inf->cpu_percent/10.0,
"cpu percent total", s->inf->total_cpu_percent/10.0);
}
}
if(s->type == TYPE_HOST && s->icmplist) {
Icmp_T i;
for(i= s->icmplist; i; i= i->next) {
out_print(res,
" %-33s %.3fs [%s]\n",
"icmp response time", i->is_available?i->response:-1.,
icmpnames[i->type]);
}
}
if((s->type == TYPE_HOST || s->type == TYPE_PROCESS) && s-> portlist) {
Port_T p;
for(p= s->portlist; p; p= p->next) {
if(p->family == AF_INET) {
out_print(res,
" %-33s %.3fs to %s:%d%s [%s via %s]\n",
"port response time", p->is_available?p->response:-1.,
p->hostname,
p->port, p->request?p->request:"", p->protocol->name,
Util_portTypeDescription(p));
} else if(p->family == AF_UNIX) {
out_print(res,
" %-33s %.3fs to %s [%s]\n",
"unix socket response time", p->is_available?p->response:-1.,
p->pathname, p->protocol->name);
}
}
}
if(s->type == TYPE_SYSTEM && Run.doprocess) {
out_print(res,
" %-33s [%.2f] [%.2f] [%.2f]\n"
" %-33s %.1f%%us %.1f%%sy"
#ifdef HAVE_CPU_WAIT
" %.1f%%wa"
#endif
"\n"
" %-33s %ld kB [%.1f%%]\n",
"load average",
systeminfo.loadavg[0],
systeminfo.loadavg[1],
systeminfo.loadavg[2],
"cpu",
systeminfo.total_cpu_user_percent/10.,
systeminfo.total_cpu_syst_percent/10.,
#ifdef HAVE_CPU_WAIT
systeminfo.total_cpu_wait_percent/10.,
#endif
"memory usage",
systeminfo.total_mem_kbyte,
systeminfo.total_mem_percent/10.);
}
}
ctime_r(&s->collected, time);
out_print(res, " %-33s %s\n", "data collected", time);
}
FREE(status);
}
static char *get_service_status_html(Service_T s) {
char *status= NULL;
char doaction[STRLEN];
EventTable_T *et= Event_Table;
ASSERT(s);
memset(doaction, 0, STRLEN);
if(s->doaction) {
snprintf(doaction, STRLEN-1, " - %s pending", actionnames[s->doaction]);
}
status= xcalloc(sizeof(char), STRLEN);
/* In the case that the service is not monitored, we will return immediately,
* because we are not able to describe actual service state */
if(s->monitor == MONITOR_NOT) {
snprintf(status, STRLEN, "not monitored%s",
doaction);
return status;
} else if(s->monitor == MONITOR_INIT) {
snprintf(status, STRLEN, "initializing%s",
doaction);
return status;
}
/* In the case that error is zero, service is up without errors */
if(!s->error) {
snprintf(status, STRLEN, "%s%s",
statusnames[s->type], doaction);
return status;
}
/* In the case that the service has actualy some failure, error
* will be non zero. We will check the bitmap and print the description
* of the first error found */
while((*et).id) {
if(s->error & (*et).id) {
snprintf(status, STRLEN, "%s%s",
(*et).description_failed, doaction);
return status;
}
et++;
}
/* We should not pass through here */
snprintf(status, STRLEN, "unknown%s",
doaction);
return status;
}
static char *get_service_status_text(Service_T s) {
char *status= NULL;
char doaction[STRLEN];
EventTable_T *et= Event_Table;
ASSERT(s);
memset(doaction, 0, STRLEN);
if(s->doaction) {
snprintf(doaction, STRLEN, " - %s pending", actionnames[s->doaction]);
}
status= xcalloc(sizeof(char), STRLEN);
/* In the case that the service is not monitored, we will return immediately,
* because we are not able to describe actual service state */
if(s->monitor == MONITOR_NOT) {
snprintf(status, STRLEN, "not monitored%s", doaction);
return status;
} else if(s->monitor == MONITOR_INIT) {
snprintf(status, STRLEN, "initializing%s", doaction);
return status;
}
/* In the case that error is zero, service is up without errors */
if(!s->error) {
snprintf(status, STRLEN, "%s%s", statusnames[s->type], doaction);
return status;
}
/* In the case that the service has actualy some failure, error
* will be non zero. We will check the bitmap and print the description
* of the first error found */
while((*et).id) {
if(s->error & (*et).id) {
snprintf(status, STRLEN, "%s%s", (*et).description_failed, doaction);
return status;
}
et++;
}
/* We should not pass through here */
snprintf(status, STRLEN, "unknown%s", doaction);
return status;
}