#include <systemd/sd-bus.h>
+#include "../daemon/string.h"
+
const char* argp_program_version = PACKAGE_VERSION;
static const char* doc = "The telemetry client that can draw graphs";
static int render(td_client_ctx* ctx) {
sd_bus_message* reply = NULL;
- const void* buffer = NULL;
+ const void* graph = NULL;
sd_bus_message* m = NULL;
sd_bus_error error = {};
char path[PATH_MAX];
size_t bytes_written = 0;
size_t length = 0;
+ char* key = NULL;
int r;
// Format the path
goto ERROR;
}
- // Read the response
- r = sd_bus_message_read_array(reply, 'y', &buffer, &length);
- if (r < 0) {
- perror("Failed to read the response");
+ // Open the result array
+ r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
+ if (r < 0)
goto ERROR;
+
+ for (;;) {
+ r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv");
+ if (r < 0)
+ goto ERROR;
+
+ // Break if we have read everything
+ if (r == 0)
+ break;
+
+ // Read the key
+ r = sd_bus_message_read(reply, "s", &key);
+ if (r < 0)
+ goto ERROR;
+
+ // Write the graph
+ if (td_string_equals(key, "graph")) {
+ // Open the variant
+ r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "ay");
+ if (r < 0)
+ goto ERROR;
+
+ // Read the buffer
+ r = sd_bus_message_read_array(reply, 'y', &graph, &length);
+ if (r < 0)
+ goto ERROR;
+
+ // Write the buffer to the output
+ bytes_written = fwrite(graph, 1, length, ctx->f);
+ if (bytes_written < length) {
+ perror("Failed to write output");
+ r = -errno;
+ goto ERROR;
+ }
+
+ // Leave the variant
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ goto ERROR;
+
+ // Skip any unknown keys
+ } else {
+ r = sd_bus_message_skip(reply, "v");
+ if (r < 0)
+ goto ERROR;
+ }
+
+ // Leave the container
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ 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;
+ // Leave the outer container
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
goto ERROR;
- }
+
+ // Success
+ r = 0;
ERROR:
if (reply)
if (check)
options.flags |= TD_GRAPH_CHECK;
+
+ // Skip any unknown keys
+ } else {
+ r = sd_bus_message_skip(m, "v");
+ if (r < 0)
+ goto ERROR;
}
// Leave the container
goto ERROR;
}
+ // Create a new array
+ r = sd_bus_message_open_container(reply, 'a', "{sv}");
+ if (r < 0)
+ goto ERROR;
+
+ // Append the format
+ r = sd_bus_message_append(reply, "{sv}", "format", "s", options.format);
+ if (r < 0)
+ goto ERROR;
+
// Append the graph
+ r = sd_bus_message_open_container(reply, 'e', "sv");
+ if (r < 0)
+ goto ERROR;
+
+ // Add the key
+ r = sd_bus_message_append(reply, "s", "graph");
+ if (r < 0)
+ goto ERROR;
+
+ // Create the value (an array of bytes)
+ r = sd_bus_message_open_container(reply, 'v', "ay");
+ if (r < 0)
+ goto ERROR;
+
+ // Write the payload
r = sd_bus_message_append_array(reply, 'y', buffer, length);
if (r < 0)
goto ERROR;
+ // Close the value array
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ goto ERROR;
+
+ // Close the entry
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ goto ERROR;
+
+ // Close the array
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ goto ERROR;
+
// Send the reply
r = sd_bus_send(NULL, reply, NULL);