X-Git-Url: https://git.octo.it/?p=collection4.git;a=blobdiff_plain;f=src%2Faction_graph.c;h=b3b815f66c943e399f34e687729ca8e47f294d70;hp=f43f997a0afec28e530786d5fa5d2f6703e7662e;hb=e3fb09073a64cc051c11c4a1bdcec493f937b764;hpb=ac01708cd45b167bab068525f16575a702d59793 diff --git a/src/action_graph.c b/src/action_graph.c index f43f997..b3b815f 100644 --- a/src/action_graph.c +++ b/src/action_graph.c @@ -1,3 +1,28 @@ +/** + * collection4 - action_graph.c + * Copyright (C) 2010 Florian octo Forster + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authors: + * Florian octo Forster + **/ + +#include "config.h" + #include #include #include @@ -12,80 +37,26 @@ #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 -static int get_time_args (str_array_t *args) /* {{{ */ +struct graph_data_s { - const char *begin_str; - const char *end_str; + rrd_args_t *args; + rrd_info_t *info; + time_t mtime; + time_t expires; long now; long begin; long end; - char *endptr; - long tmp; - - begin_str = param ("begin"); - end_str = param ("end"); - - now = (long) time (NULL); - - 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; - } - - array_append (args, "-s"); - array_append_format (args, "%li", begin); - array_append (args, "-e"); - array_append_format (args, "%li", end); - - return (0); -} /* }}} int get_time_args */ +}; +typedef struct graph_data_s graph_data_t; static void emulate_graph (int argc, char **argv) /* {{{ */ { @@ -119,11 +90,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; @@ -132,9 +106,39 @@ 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 ("X-Generator: "PACKAGE_STRING"\n"); + printf ("\n"); + fwrite (img->value.u_blo.ptr, img->value.u_blo.size, /* nmemb = */ 1, stdout); @@ -149,12 +153,14 @@ 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; + int argc; + char **argv; + cfg = gl_graph_get_selected (); if (cfg == NULL) OUTPUT_ERROR ("gl_graph_get_selected () failed.\n"); @@ -163,37 +169,54 @@ 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 = ra_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->options, "graph"); + array_append (data.args->options, "-"); + array_append (data.args->options, "--imgformat"); + array_append (data.args->options, "PNG"); - get_time_args (args); + status = get_time_args (&data.begin, &data.end, &data.now); + if (status == 0) + { + array_append (data.args->options, "-s"); + array_append_format (data.args->options, "%li", data.begin); + array_append (data.args->options, "-e"); + array_append_format (data.args->options, "%li", data.end); + } - status = inst_get_rrdargs (cfg, inst, args); + status = inst_get_rrdargs (cfg, inst, data.args); if (status != 0) { - array_destroy (args); + ra_destroy (data.args); OUTPUT_ERROR ("inst_get_rrdargs failed with status %i.\n", status); } + argc = ra_argc (data.args); + argv = ra_argv (data.args); + if ((argc < 0) || (argv == NULL)) + { + ra_destroy (data.args); + return (-1); + } + rrd_clear_error (); - info = rrd_graph_v (array_argc (args), array_argv (args)); - if ((info == NULL) || rrd_test_error ()) + data.info = rrd_graph_v (argc, argv); + 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 (argc, argv); } else { int status; - status = output_graph (info); + data.mtime = inst_get_mtime (inst); + + status = output_graph (&data); if (status != 0) { rrd_info_t *ptr; @@ -201,18 +224,19 @@ 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; + ra_argv_free (argv); + ra_destroy (data.args); + data.args = NULL; return (0); } /* }}} int action_graph */