X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Faction_graph.c;h=d496a242e55cb97bcbcfe29cf13a8579455f0610;hb=8e72ccc76582cf1f68b6e9e4816ac0bd785fc7d8;hp=a0f257e47b4d168571c02d0e8f2660af39194d67;hpb=0ab3085f89e64eecd67d3179ea87f0463e918a10;p=collection4.git diff --git a/src/action_graph.c b/src/action_graph.c index a0f257e..d496a24 100644 --- a/src/action_graph.c +++ b/src/action_graph.c @@ -12,13 +12,101 @@ #include "common.h" #include "action_graph.h" +#include "graph.h" +#include "graph_instance.h" #include "graph_list.h" -#include "utils_params.h" +#include "utils_cgi.h" #include "utils_array.h" #include #include +struct graph_data_s +{ + str_array_t *args; + rrd_info_t *info; + time_t mtime; + time_t expires; + long now; + long begin; + long end; +}; +typedef struct graph_data_s graph_data_t; + +static int get_time_args (graph_data_t *data) /* {{{ */ +{ + const char *begin_str; + const char *end_str; + long now; + long begin; + long end; + char *endptr; + long tmp; + + begin_str = param ("begin"); + end_str = param ("end"); + + now = (long) time (NULL); + data->now = now; + data->begin = now - 86400; + data->end = now; + + if (begin_str != NULL) + { + endptr = NULL; + errno = 0; + tmp = strtol (begin_str, &endptr, /* base = */ 0); + if ((endptr == begin_str) || (errno != 0)) + return (-1); + if (tmp <= 0) + begin = now + tmp; + else + begin = tmp; + } + else /* if (begin_str == NULL) */ + { + begin = now - 86400; + } + + if (end_str != NULL) + { + endptr = NULL; + errno = 0; + tmp = strtol (end_str, &endptr, /* base = */ 0); + if ((endptr == end_str) || (errno != 0)) + return (-1); + end = tmp; + if (tmp <= 0) + end = now + tmp; + else + end = tmp; + } + else /* if (end_str == NULL) */ + { + end = now; + } + + if (begin == end) + return (-1); + + if (begin > end) + { + tmp = begin; + begin = end; + end = tmp; + } + + data->begin = begin; + data->end = end; + + array_append (data->args, "-s"); + array_append_format (data->args, "%li", begin); + array_append (data->args, "-e"); + array_append_format (data->args, "%li", end); + + return (0); +} /* }}} int get_time_args */ + static void emulate_graph (int argc, char **argv) /* {{{ */ { int i; @@ -51,11 +139,14 @@ static int ag_info_print (rrd_info_t *info) /* {{{ */ return (0); } /* }}} int ag_info_print */ -static int output_graph (rrd_info_t *info) /* {{{ */ +static int output_graph (graph_data_t *data) /* {{{ */ { rrd_info_t *img; + char time_buffer[256]; + time_t expires; + int status; - for (img = info; img != NULL; img = img->next) + for (img = data->info; img != NULL; img = img->next) if ((strcmp ("image", img->key) == 0) && (img->type == RD_I_BLO)) break; @@ -64,9 +155,38 @@ static int output_graph (rrd_info_t *info) /* {{{ */ return (ENOENT); printf ("Content-Type: image/png\n" - "Content-Length: %lu\n" - "\n", + "Content-Length: %lu\n", img->value.u_blo.size); + if (data->mtime > 0) + { + int status; + + status = time_to_rfc1123 (data->mtime, time_buffer, sizeof (time_buffer)); + if (status == 0) + printf ("Last-Modified: %s\n", time_buffer); + } + + /* Print Expires header. */ + if (data->end >= data->now) + { + /* The end of the timespan can be seen. */ + long secs_per_pixel; + + /* FIXME: Handle graphs with width != 400. */ + secs_per_pixel = (data->end - data->begin) / 400; + + expires = (time_t) (data->now + secs_per_pixel); + } + else /* if (data->end < data->now) */ + { + expires = (time_t) (data->now + 86400); + } + status = time_to_rfc1123 (expires, time_buffer, sizeof (time_buffer)); + if (status == 0) + printf ("Expires: %s\n", time_buffer); + + printf ("\n"); + fwrite (img->value.u_blo.ptr, img->value.u_blo.size, /* nmemb = */ 1, stdout); @@ -81,10 +201,9 @@ static int output_graph (rrd_info_t *info) /* {{{ */ int action_graph (void) /* {{{ */ { - str_array_t *args; + graph_data_t data; graph_config_t *cfg; graph_instance_t *inst; - rrd_info_t *info; int status; cfg = gl_graph_get_selected (); @@ -95,35 +214,39 @@ int action_graph (void) /* {{{ */ if (inst == NULL) OUTPUT_ERROR ("inst_get_selected (%p) failed.\n", (void *) cfg); - args = array_create (); - if (args == NULL) + data.args = array_create (); + if (data.args == NULL) return (ENOMEM); - array_append (args, "graph"); - array_append (args, "-"); - array_append (args, "--imgformat"); - array_append (args, "PNG"); + array_append (data.args, "graph"); + array_append (data.args, "-"); + array_append (data.args, "--imgformat"); + array_append (data.args, "PNG"); - status = inst_get_rrdargs (cfg, inst, args); + get_time_args (&data); + + status = inst_get_rrdargs (cfg, inst, data.args); if (status != 0) { - array_destroy (args); + array_destroy (data.args); OUTPUT_ERROR ("inst_get_rrdargs failed with status %i.\n", status); } rrd_clear_error (); - info = rrd_graph_v (array_argc (args), array_argv (args)); - if ((info == NULL) || rrd_test_error ()) + data.info = rrd_graph_v (array_argc (data.args), array_argv (data.args)); + if ((data.info == NULL) || rrd_test_error ()) { printf ("Content-Type: text/plain\n\n"); printf ("rrd_graph_v failed: %s\n", rrd_get_error ()); - emulate_graph (array_argc (args), array_argv (args)); + emulate_graph (array_argc (data.args), array_argv (data.args)); } else { int status; - status = output_graph (info); + data.mtime = inst_get_mtime (inst); + + status = output_graph (&data); if (status != 0) { rrd_info_t *ptr; @@ -131,18 +254,18 @@ int action_graph (void) /* {{{ */ printf ("Content-Type: text/plain\n\n"); printf ("output_graph failed. Maybe the \"image\" info was not found?\n\n"); - for (ptr = info; ptr != NULL; ptr = ptr->next) + for (ptr = data.info; ptr != NULL; ptr = ptr->next) { ag_info_print (ptr); } } } - if (info != NULL) - rrd_info_free (info); + if (data.info != NULL) + rrd_info_free (data.info); - array_destroy (args); - args = NULL; + array_destroy (data.args); + data.args = NULL; return (0); } /* }}} int action_graph */