1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
#include <sys/types.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <microhttpd.h>
#include "monitor.h"
#include "config.h"
#include "check.h"
#define CFG_FILE "monitor.cfg"
#define TMPL_FILE "index.htm.tmpl"
#define LOG_FILE "events.log"
static char *index_format_template = NULL;
enum MHD_Result answer_to_connection(
void *cls, struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
const char *upload_data,
size_t *upload_data_size,
void **ptr
) {
char buff[BUFF_SIZE];
const struct sockaddr_in **coninfo =
(const struct sockaddr_in**)MHD_get_connection_info(
connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS);
time_t time_now = time(NULL);
struct tm *tm_now = gmtime(&time_now);
static char timestr[256];
strftime(timestr, 256, "%Y-%m-%d %H:%M:%S", tm_now);
printf("[%s] [webserver] %s %s %s: ",
timestr, inet_ntoa((*coninfo)->sin_addr), method, url);
struct MHD_Response *response;
int ret;
if (strcmp(method, "GET") == 0 && strcmp(url, "/") == 0) {
snprintf(buff, BUFF_SIZE,
index_format_template,
timestr,
monitor_generate_status_html(),
monitor_generate_incidents_html());
response = MHD_create_response_from_buffer(strlen(buff), (void*)buff,
MHD_RESPMEM_PERSISTENT);
printf("%d\n", 200);
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
MHD_destroy_response(response);
}
else {
response = MHD_create_response_from_buffer(0, (void*)NULL, 0);
printf("%d\n", 418);
ret = MHD_queue_response(connection, 418, response);
MHD_destroy_response(response);
}
return ret;
}
int main() {
printf("ARFNET Status Monitor (C) 2025 under GPLv3\n");
/* read index template file */
FILE *tf = fopen(TMPL_FILE, "r");
if (!tf) {
fprintf(stderr, "error opening index template file: %s\n",
strerror(errno));
return 1;
}
fseek(tf, 0, SEEK_END);
size_t tfs = ftell(tf);
rewind(tf);
index_format_template = malloc(tfs);
fread(index_format_template, 1, tfs, tf);
fclose(tf);
if (config_load(CONFIG_PATH) < 0)
return 1;
if (check_init() < 0)
return 1;
if (monitor_init(CFG_FILE, LOG_FILE) < 0)
return 1;
/* start server */
struct MHD_Daemon *daemon;
daemon = MHD_start_daemon(
MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_EPOLL,
port, NULL, NULL,
&answer_to_connection, NULL, MHD_OPTION_END);
if (!daemon) {
fprintf(stderr, "error starting libmicrohttpd daemon: \n");
return 1;
}
while (1) {
check_perform(targets, targets_size);
monitor_update_events(LOG_FILE);
sleep(monitor_config.interval);
}
}
|