[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 02/23] C webapp


MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

From: arf20 <aruizfernandez05@xxxxxxxxx>

---
 Makefile       |  14 +++++++
 README.md      |   7 ++++
 index.htm.tmpl |   8 +++-
 main.c         |  98 +++++++++++++++++++++++++++++++++++++++++++++
 monitor        | Bin 0 -> 29912 bytes
 monitor.c      | 105 +++++++++++++++++++++++++++++++++++++++++++++++++
 monitor.cfg    |   6 +++
 monitor.h      |   8 ++++
 8 files changed, 245 insertions(+), 1 deletion(-)
 create mode 100644 Makefile
 create mode 100644 main.c
 create mode 100755 monitor
 create mode 100644 monitor.c
 create mode 100644 monitor.cfg
 create mode 100644 monitor.h

diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..bc05321
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+CC = gcc
+CFLAGS = -g -Wall -pedantic
+LDFLAGS = -lmicrohttpd
+
+BIN = monitor
+SRC = main.c monitor.c
+
+$(BIN): $(SRC)
+	$(CC) -o $@ $(CFLAGS) $^ $(LDFLAGS)
+
+.PHONY: clean
+clean:
+	rm $(BIN)
+
diff --git a/README.md b/README.md
index 2f0b344..a373746 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,10 @@
 # arfnet2-status
 
 ARFNET Status Monitor
+
+## Features (TODO)
+
+ - Current service status table
+ - Outage events table
+ - Uptime counter (total, month)
+
diff --git a/index.htm.tmpl b/index.htm.tmpl
index a9022d8..462f744 100644
--- a/index.htm.tmpl
+++ b/index.htm.tmpl
@@ -4,6 +4,11 @@
         <meta charset="UTF-8">
         <link rel="stylesheet" type="text/css" href="https://arf20.com/style.css";>
         <title>ARFNET</title>
+        <style>
+table, th, td {
+  border: 1px solid #abb2bf;
+}
+        </style>
     </head>
 
     <body>
@@ -15,7 +20,8 @@
             <h2 class="center">Status Monitor</h2>
             <p>This webapp monitors the status of the main ARFNET services from outside the ARFNET network</p>
             <table>
-
+                <tr><th>Type</th><th>Service</th><th>Status</th></tr>
+                %s
             </table>
         </main>
     </body>
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..f01d928
--- /dev/null
+++ b/main.c
@@ -0,0 +1,98 @@
+#include <sys/types.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <microhttpd.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "monitor.h"
+
+#define PORT        8888
+#define RES_BUFF    65535
+
+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[RES_BUFF];
+
+    const struct sockaddr_in **coninfo =
+        (const struct sockaddr_in**)MHD_get_connection_info(
+            connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS);
+
+    printf("%s - %s %s: ", inet_ntoa((*coninfo)->sin_addr), method, url);
+
+    struct MHD_Response *response;
+    int ret;
+
+    if (strcmp(method, "GET") == 0 && strcmp(url, "/") == 0) {
+        snprintf(buff, RES_BUFF,
+            index_format_template, monitor_generate_status_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() {
+    /* read index template file */
+    FILE *tf = fopen("index.htm.tmpl", "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);
+
+    /* 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;
+    }
+
+    monitor_init("monitor.cfg");
+
+    while (1) {
+        monitor_check();
+        sleep(5);
+    }
+}
+
diff --git a/monitor b/monitor
new file mode 100755
index 0000000000000000000000000000000000000000..3992ddc45410cd58d6f0d1cdfa37db5b3aa9d44b
GIT binary patch
literal 29912
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

literal 0
HcmV?d00001

diff --git a/monitor.c b/monitor.c
new file mode 100644
index 0000000..c9903ce
--- /dev/null
+++ b/monitor.c
@@ -0,0 +1,105 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "monitor.h"
+
+typedef enum {
+    TYPE_REACH,
+    TYPE_DNS,
+    TYPE_WEB
+} type_t;
+
+const char *type_str[] = { "reach", "dns", "web" };
+
+typedef enum {
+    STATUS_DOWN,
+    STATUS_UP
+} status_t;
+
+typedef struct {
+    type_t type;
+    char *target;
+    status_t status;
+} target_t;
+
+static target_t targets[256];
+static size_t target_n = 0;
+
+int
+monitor_init(const char *cfg_file) {
+    FILE *cfgf = fopen(cfg_file, "r");
+    if (!cfgf) {
+        fprintf(stderr, "Error opening config: %s\n", strerror(errno));
+        return -1;
+    }
+
+    printf("monitor targets:\n");
+    
+    char line[256];
+    while (fgets(line, sizeof(line), cfgf)) {
+        if (*line == '#' || *line == '\n')
+            continue;
+
+        char *type = line;
+        char *target = strchr(line, '=');
+        if (!target) {
+            fprintf(stderr, "malformed config line: %s\n", line);
+            continue;
+        }
+
+
+        *target = '\0';
+        target++;
+
+        if (strcmp(type, "reach") == 0)
+            targets[target_n].type = TYPE_REACH;
+        else if (strcmp(type, "dns") == 0)
+            targets[target_n].type = TYPE_DNS;
+        else if (strcmp(type, "web") == 0)
+            targets[target_n].type = TYPE_WEB;
+
+        targets[target_n].target = strdup(target);
+        targets[target_n].status = STATUS_DOWN;
+
+        printf("\t%s: %s", type_str[targets[target_n].type],
+            targets[target_n].target);
+        
+        target_n++;
+    } 
+
+    fclose(cfgf);
+
+    return 0;
+}
+
+const char *
+monitor_generate_status_html()
+{
+    static char buff[65535];
+
+    static char *status_html[] = {
+        "down",
+        "up"
+    };
+   
+    char *pos = buff;
+
+    for (size_t i = 0; i < target_n; i++) {
+        pos += snprintf(pos, 65535,
+            "<tr><td>%s</td><td>%s</td><td>%s</td></tr>\n",
+            type_str[targets[i].type],
+            targets[i].target,
+            status_html[targets[i].status]);
+    }
+
+    return buff;  
+}
+
+void
+monitor_check()
+{
+
+}
+
diff --git a/monitor.cfg b/monitor.cfg
new file mode 100644
index 0000000..1e2f9dc
--- /dev/null
+++ b/monitor.cfg
@@ -0,0 +1,6 @@
+# Monitor config
+# type=target
+reach=2.59.235.35
+dns=arf20.com
+web=http://arf20.com
+
diff --git a/monitor.h b/monitor.h
new file mode 100644
index 0000000..f9d4458
--- /dev/null
+++ b/monitor.h
@@ -0,0 +1,8 @@
+#ifndef _MONITOR_H
+#define _MONITOR_H
+
+int monitor_init(const char *cfg_file);
+const char *monitor_generate_status_html();
+void monitor_check();
+
+#endif /* _MONITOR_H */
-- 
2.47.3


References:
[arfnet2-status PATCH 00/23] First releasearf20 <arf20@xxxxxxxxx>