const char* since;
const char* until;
} interval;
+
+ // Locale
+ const char* locale;
} td_client_ctx;
enum {
OPT_SINCE = 4,
OPT_UNTIL = 5,
OPT_OMIT_TITLE = 6,
+ OPT_LOCALE = 7,
};
static struct argp_option options[] = {
// Flags
{ "omit-title", OPT_OMIT_TITLE, NULL, 0, "Omit the title in the graph image", 0},
+
+ // Locale
+ { "locale", OPT_LOCALE, "CODE", 0, "Render the graph for a different locale", 0 },
{ NULL },
};
ctx->flags |= OMIT_TITLE;
break;
+ case OPT_LOCALE:
+ ctx->locale = arg;
+ break;
+
// Called for each argument
case ARGP_KEY_ARG:
// Take the graph name as first argument
goto ERROR;
}
+ // Send the locale
+ if (ctx->locale) {
+ r = sd_bus_message_append(m, "{sv}", "locale", "s", ctx->locale);
+ if (r < 0)
+ goto ERROR;
+ }
+
// Close the array
r = sd_bus_message_close_container(m);
if (r < 0)
#include <errno.h>
#include <limits.h>
+#include <locale.h>
#include <stdlib.h>
#include <rrd.h>
return 0;
}
+static void td_graph_reset_locale(td_ctx* ctx, char* locale) {
+ const char* l = NULL;
+
+ // Nothing to do if the locale is not known
+ if (!*locale)
+ return;
+
+ // Set the locale
+ l = setlocale(LC_ALL, locale);
+ if (!l)
+ ERROR(ctx, "Failed to reset the locale to '%s': %m\n", locale);
+}
+
int td_graph_render(td_graph* self, const char* object,
const td_graph_render_options* options, char** buffer, size_t* length) {
td_args* args = NULL;
double ymax = 0;
int r;
+ // Locale
+ char locale[NAME_MAX] = "";
+ const char* l;
+
// Measure the runtime
clock_t t_start = 0;
clock_t t_end = 0;
goto ERROR;
}
+ // Fetch the current locale
+ l = setlocale(LC_ALL, NULL);
+ if (l) {
+ // Store the locale for it to be reset later
+ r = td_string_set(locale, l);
+ if (r < 0)
+ goto ERROR;
+ }
+
// Allocate a new argument list
r = td_args_create(&args, self->ctx);
if (r < 0)
if (r < 0)
goto ERROR;
+ // Change the locale
+ if (options->locale) {
+ l = setlocale(LC_ALL, options->locale);
+ if (l)
+ DEBUG(self->ctx, "Locale has been changed to: %s\n", l);
+ else
+ ERROR(self->ctx, "Failed to set locale '%s': %m. Ignoring.\n", options->locale);
+ }
+
// Call the implementation to add some arguments
r = self->impl->render(self->ctx, self, args, object);
if (r < 0)
// warning since rrdtool >= 1.9 has constified their input arguments.
r = rrd_graph(td_args_argc(args), (void*)td_args_argv(args),
&data, &w, &h, f, &ymin, &ymax);
+
+ // Reset the locale again
+ td_graph_reset_locale(self->ctx, locale);
+
+ // Handle any errors
if (r < 0) {
ERROR(self->ctx, "Failed to generate the graph: %s\n", rrd_get_error());
rrd_clear_error();
}
ERROR:
+ // Reset the locale
+ td_graph_reset_locale(self->ctx, locale);
+
if (data) {
for (unsigned int i = 0; data[i]; i++)
free(data[i]);