]> git.ipfire.org Git - collecty.git/commitdiff
client: Add a basic client to fetch the graphs
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 2 Oct 2025 18:12:11 +0000 (18:12 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 2 Oct 2025 18:12:11 +0000 (18:12 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
.gitignore
Makefile.am
src/client/main.c [new file with mode: 0644]

index f6a2aa4ad6b8a9ce8df02701709d8930c0a679f2..611540a2e6e4617d833b67ece6ff8c9458fcaea5 100644 (file)
@@ -1,6 +1,7 @@
 /Makefile
 /build-aux
 /collectyd
+/collecty-graph
 /config.h*
 /libtool
 /man/*.[0-9]
index 3bbf5742050f19ad3d800804ac0363da76fb2bb0..f6866ce62c204fcd158f713b5a0693a824678562 100644 (file)
@@ -145,6 +145,28 @@ collectyd_LDADD = \
 
 # ------------------------------------------------------------------------------
 
+bin_PROGRAMS += \
+       collecty-graph
+
+dist_collecty_graph_SOURCES = \
+       src/client/main.c
+
+collecty_graph_CPPFLAGS = \
+       $(AM_CPPFLAGS)
+
+collecty_graph_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(SYSTEMD_CFLAGS)
+
+collecty_graph_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       $(SYSTEMD_LDFLAGS)
+
+collecty_graph_LDADD = \
+       $(SYSTEMD_LIBS)
+
+# ------------------------------------------------------------------------------
+
 dist_dbuspolicy_DATA = \
        src/dbus/org.ipfire.collecty1.conf
 
diff --git a/src/client/main.c b/src/client/main.c
new file mode 100644 (file)
index 0000000..1c3ad94
--- /dev/null
@@ -0,0 +1,154 @@
+/*#############################################################################
+#                                                                             #
+# collecty - A system statistics collection daemon for IPFire                 #
+# Copyright (C) 2025 IPFire Development Team                                  #
+#                                                                             #
+# 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 <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#include <argp.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <systemd/sd-bus.h>
+
+const char* argp_program_version = PACKAGE_VERSION;
+
+static const char* doc = "The collecty client that can draw graphs";
+
+typedef struct collecty_client_ctx {
+       // DBus
+       sd_bus* bus;
+
+       // Name of the graph
+       const char* graph;
+
+       // Output Format
+       const char* format;
+
+       // Output
+       FILE* f;
+} collecty_client_ctx;
+
+static error_t parse(int key, char* arg, struct argp_state* state) {
+       collecty_client_ctx* ctx = state->input;
+
+       switch (key) {
+               // Called for each argument
+               case ARGP_KEY_ARG:
+                       // Take the graph name as first argument
+                       if (!ctx->graph) {
+                               ctx->graph = arg;
+                               return 0;
+
+                       // Otherwise show help
+                       } else {
+                               argp_usage(state);
+                       }
+                       break;
+
+               // Called once all arguments have been parsed
+               case ARGP_KEY_END:
+                       // Not enough arguments
+                       if (state->arg_num < 1)
+                               argp_usage(state);
+
+                       break;
+
+               default:
+                       return ARGP_ERR_UNKNOWN;
+       }
+
+       return 0;
+}
+
+static int render(collecty_client_ctx* ctx) {
+       const void* buffer = NULL;
+       sd_bus_message* m = NULL;
+       char path[PATH_MAX];
+       size_t bytes_written = 0;
+       size_t length = 0;
+       int r;
+
+       // Format the path
+       r = snprintf(path, sizeof(path), "/org/ipfire/collecty1/graph/%s", ctx->graph);
+       if (r < 0)
+               goto ERROR;
+
+       // Call the render function
+       r = sd_bus_call_method(ctx->bus, "org.ipfire.collecty1", path,
+                       "org.ipfire.collecty1.Graph", "Render", NULL, &m, "s", "");
+       if (r < 0) {
+               perror("Failed to call the Render() method");
+               goto ERROR;
+       }
+
+       // Read the response
+       r = sd_bus_message_read_array(m, 'y', &buffer, &length);
+       if (r < 0) {
+               perror("Failed to read the response");
+               goto ERROR;
+       }
+
+       // Write the buffer to the output
+       bytes_written = fwrite(buffer, 1, length, ctx->f);
+       if (bytes_written < length) {
+               perror("Failed to write output");
+               r = -errno;
+               goto ERROR;
+       }
+
+ERROR:
+       if (m)
+               sd_bus_message_unref(m);
+
+       return r;
+}
+
+int main(int argc, char* argv[]) {
+       struct argp parser = {
+               .parser  = parse,
+               .doc     = doc,
+       };
+       int arg_index = 0;
+       int r;
+
+       // Allocate a new context
+       collecty_client_ctx ctx = {
+               .f = stdout,
+       };
+
+       // Parse command line arguments
+       r = argp_parse(&parser, argc, argv, 0, &arg_index, &ctx);
+       if (r)
+               goto ERROR;
+
+       // Connect to the bus
+       r = sd_bus_open_system(&ctx.bus);
+       if (r < 0) {
+               perror("Failed to connect to system bus");
+               goto ERROR;
+       }
+
+       // Render the graph
+       r = render(&ctx);
+
+ERROR:
+       if (ctx.bus)
+               sd_bus_unref(ctx.bus);
+
+       return (r) ? EXIT_FAILURE : EXIT_SUCCESS;
+}