From 31b23d64eb3ba6161b3217bc123e074b9862fdae Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Sun, 20 Jun 2010 20:44:58 +0200 Subject: [PATCH 01/16] share/collection.conf: Add "Load" graph. --- share/collection.conf | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/share/collection.conf b/share/collection.conf index eb33fe0..998a433 100644 --- a/share/collection.conf +++ b/share/collection.conf @@ -274,6 +274,32 @@ Host "/any/" + Plugin "load" + PluginInstance "" + Type "load" + TypeInstance "" + + Title "System load" + + + DSName "longterm" + Legend "15m" + Color "ff0000" + + + DSName "midterm" + Legend " 5m" + Color "0000ff" + + + DSName "shortterm" + Legend " 1m " + Color "00ff00" + + + + + Host "/any/" Plugin "memory" PluginInstance "" Type "memory" -- 2.11.0 From 5168f69eefd02bd6cfd4060cff4f4862f5a2a66c Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Sun, 20 Jun 2010 20:59:19 +0200 Subject: [PATCH 02/16] .gitignore: Add a couple more automatically generated files. --- .gitignore | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index b58b4ea..939ad4a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,11 @@ *.o -scanner.c -parser.c -parser.h +Makefile +Makefile.in + +/configure +/config.log +/config.status +src/config.h +src/scanner.c +src/parser.c +src/parser.h -- 2.11.0 From 96c41b0aed8e2b9f6a5fa70dbba77465a2da4173 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Sun, 20 Jun 2010 21:39:05 +0200 Subject: [PATCH 03/16] src/common.[ch]: Implement "strtolower" and "strtolower_copy". --- src/common.c | 22 ++++++++++++++++++++++ src/common.h | 3 +++ 2 files changed, 25 insertions(+) diff --git a/src/common.c b/src/common.c index 2b6b5eb..4916b3c 100644 --- a/src/common.c +++ b/src/common.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -190,4 +191,25 @@ int print_debug (const char *format, ...) /* {{{ */ return (status); } /* }}} int print_debug */ +char *strtolower (char *str) /* {{{ */ +{ + unsigned int i; + + if (str == NULL) + return (NULL); + + for (i = 0; str[i] != 0; i++) + str[i] = (char) tolower ((int) str[i]); + + return (str); +} /* }}} char *strtolower */ + +char *strtolower_copy (const char *str) +{ + if (str == NULL) + return (NULL); + + return (strdup (str)); +} + /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/common.h b/src/common.h index 2b5662f..ad589e7 100644 --- a/src/common.h +++ b/src/common.h @@ -20,5 +20,8 @@ int ds_list_from_rrd_file (char *file, uint32_t get_random_color (void); +char *strtolower (char *str); +char *strtolower_copy (const char *str); + #endif /* COMMON_H */ /* vim: set sw=2 sts=2 et fdm=marker : */ -- 2.11.0 From 7ef6ca1ae6310242938b74bd1e79c51e4373534f Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Sun, 20 Jun 2010 21:39:33 +0200 Subject: [PATCH 04/16] "list graph" action: Search case-independent. --- src/action_list_graphs.c | 12 ++++++++++-- src/graph.c | 2 ++ src/graph_instance.c | 2 ++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/action_list_graphs.c b/src/action_list_graphs.c index 131a6fb..f00c6b3 100644 --- a/src/action_list_graphs.c +++ b/src/action_list_graphs.c @@ -227,17 +227,25 @@ static int list_graphs_html (const char *term) /* {{{ */ int action_list_graphs (void) /* {{{ */ { const char *format; + const char *search; + int status; gl_update (); + search = strtolower_copy (param ("search")); + format = param ("format"); if (format == NULL) format = "html"; if (strcmp ("json", format) == 0) - return (list_graphs_json (param ("search"))); + status = list_graphs_json (search); else - return (list_graphs_html (param ("search"))); + status = list_graphs_html (search); + + free (search); + + return (status); } /* }}} int action_list_graphs */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/graph.c b/src/graph.c index da4b5ea..d314bcc 100644 --- a/src/graph.c +++ b/src/graph.c @@ -284,6 +284,8 @@ int graph_search (graph_config_t *cfg, const char *term, /* {{{ */ return (status); } + strtolower (buffer); + if (strstr (buffer, term) != NULL) { status = inst_foreach (cfg->instances, graph_search_submit, &data); diff --git a/src/graph_instance.c b/src/graph_instance.c index 45dcefb..73aeb1b 100644 --- a/src/graph_instance.c +++ b/src/graph_instance.c @@ -435,6 +435,8 @@ int inst_search (graph_config_t *cfg, graph_instance_t *inst, /* {{{ */ return (status); } + strtolower (buffer); + /* no match */ if (strstr (buffer, term) == NULL) continue; -- 2.11.0 From 18acc4106233bdc59011a0a87d2f4a3373d65c9b Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 21 Jun 2010 10:39:32 +0200 Subject: [PATCH 05/16] src/utils_array.[ch]: Implement "array_sort". --- src/utils_array.c | 18 ++++++++++++++++++ src/utils_array.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/src/utils_array.c b/src/utils_array.c index 5aaabbc..e7ac51e 100644 --- a/src/utils_array.c +++ b/src/utils_array.c @@ -12,6 +12,14 @@ struct str_array_s size_t size; }; +static int sort_callback (const void *v0, const void *v1) /* {{{ */ +{ + const char *c0 = v0; + const char *c1 = v1; + + return (strcmp (c0, c1)); +} /* }}} int sort_callback */ + str_array_t *array_create (void) /* {{{ */ { str_array_t *a; @@ -76,6 +84,16 @@ int array_append_format (str_array_t *a, const char *format, ...) /* {{{ */ return (array_append (a, buffer)); } /* }}} int array_append_format */ +int array_sort (str_array_t *a) /* {{{ */ +{ + if (a == NULL) + return (EINVAL); + + qsort (a->ptr, a->size, sizeof (*a->ptr), sort_callback); + + return (0); +} /* }}} int array_sort */ + int array_argc (str_array_t *a) /* {{{ */ { if (a == NULL) diff --git a/src/utils_array.h b/src/utils_array.h index 917bea9..141dbaa 100644 --- a/src/utils_array.h +++ b/src/utils_array.h @@ -10,6 +10,8 @@ int array_append (str_array_t *a, const char *entry); int array_append_format (str_array_t *a, const char *format, ...) __attribute__((format(printf,2,3))); +int array_sort (str_array_t *a); + int array_argc (str_array_t *); char **array_argv (str_array_t *); -- 2.11.0 From b13fce25f7de6f9319fd609bb0fa262c974c1c98 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 21 Jun 2010 10:40:29 +0200 Subject: [PATCH 06/16] src/utils_cgi.c: Fix minor problems with the HTML escape functions. --- src/utils_cgi.c | 5 ++++- src/utils_cgi.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/utils_cgi.c b/src/utils_cgi.c index 9efa01f..fb9a1fb 100644 --- a/src/utils_cgi.c +++ b/src/utils_cgi.c @@ -328,7 +328,7 @@ char *html_escape_copy (char *dest, const char *src, size_t n) /* {{{ */ break; } - return (src); + return (dest); } /* }}} char *html_escape_copy */ #undef COPY_ENTITY @@ -347,6 +347,9 @@ char *html_escape (const char *string) /* {{{ */ { char buffer[4096]; + if (string == NULL) + return (NULL); + html_escape_copy (buffer, string, sizeof (buffer)); return (strdup (buffer)); diff --git a/src/utils_cgi.h b/src/utils_cgi.h index b9b8c09..3204b62 100644 --- a/src/utils_cgi.h +++ b/src/utils_cgi.h @@ -18,4 +18,5 @@ char *html_escape (const char *string); char *html_escape_buffer (char *buffer, size_t buffer_size); char *html_escape_copy (char *dest, const char *src, size_t n); +/* vim: set sw=2 sts=2 et fdm=marker : */ #endif /* UTILS_CGI_H */ -- 2.11.0 From 7879274a21ee7dcb30253e96b4dca792c38ae931 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 21 Jun 2010 10:41:39 +0200 Subject: [PATCH 07/16] "list graphs" action: Move the overall HTML structure into src/utils_cgi.c. --- src/action_list_graphs.c | 183 ++++++++++++++++++++++++++++++++++++++++------- src/utils_cgi.c | 80 +++++++++++++++++++++ src/utils_cgi.h | 24 +++++++ 3 files changed, 261 insertions(+), 26 deletions(-) diff --git a/src/action_list_graphs.c b/src/action_list_graphs.c index f00c6b3..dad4367 100644 --- a/src/action_list_graphs.c +++ b/src/action_list_graphs.c @@ -4,6 +4,7 @@ #include #include "action_list_graphs.h" +#include "common.h" #include "graph.h" #include "graph_ident.h" #include "graph_list.h" @@ -12,6 +13,8 @@ #include #include +#define RESULT_LIMIT 50 + struct callback_data_s { graph_config_t *cfg; @@ -115,7 +118,7 @@ static int list_graphs_json (const char *term) /* {{{ */ printf ("\n"); data.cfg = NULL; - data.limit = 20; + data.limit = RESULT_LIMIT; data.first = 1; printf ("[\n"); @@ -176,50 +179,178 @@ static int print_graph_inst_html (graph_config_t *cfg, /* {{{ */ return (0); } /* }}} int print_graph_inst_html */ -static int list_graphs_html (const char *term) /* {{{ */ +struct page_data_s { - callback_data_t data = { NULL, /* limit = */ 20, /* first = */ 1 }; - char *term_html; + const char *search_term; +}; +typedef struct page_data_s page_data_t; - term_html = NULL; - if (term != NULL) - term_html = html_escape (term); +static int print_search_box (void *user_data) /* {{{ */ +{ + page_data_t *data = user_data; + char *term_html; - printf ("Content-Type: text/html\n\n"); + if (data == NULL) + { + fprintf (stderr, "print_search_box: data == NULL\n"); + return (EINVAL); + } - printf ("\n \n"); - if (term != NULL) - printf (" c4: Graphs matching "%s"\n", term); - else - printf (" c4: List of all graphs\n"); - printf (" \n"); - printf (" \n" - " \n"); - printf (" \n \n"); + term_html = html_escape (data->search_term); printf ("
\n" " \n" " \n" " \n" "
\n", - script_name (), (term_html != NULL) ? term_html : ""); + script_name (), + (term_html != NULL) ? term_html : ""); free (term_html); + return (0); +} /* }}} int print_search_box */ + +static int print_search_result (void *user_data) /* {{{ */ +{ + page_data_t *pg_data = user_data; + callback_data_t cb_data = { NULL, /* limit = */ RESULT_LIMIT, /* first = */ 1 }; + printf ("
    \n"); - if (term == NULL) - gl_instance_get_all (print_graph_inst_html, /* user_data = */ &data); + if (pg_data->search_term == NULL) + gl_instance_get_all (print_graph_inst_html, /* user_data = */ &cb_data); else - gl_search (term, print_graph_inst_html, /* user_data = */ &data); + { + char *term_lc = strtolower_copy (pg_data->search_term); + gl_search (term_lc, print_graph_inst_html, /* user_data = */ &cb_data); + free (term_lc); + } - if (data.cfg != NULL) + if (cb_data.cfg != NULL) printf ("
\n"); printf (" \n"); - printf (" \n\n"); + return (0); +} /* }}} int print_search_result */ + +struct print_host_list_data_s +{ + str_array_t *array; + char *last_host; +}; +typedef struct print_host_list_data_s print_host_list_data_t; + +static int print_host_list_callback (graph_config_t *cfg, /* {{{ */ + graph_instance_t *inst, void *user_data) +{ + print_host_list_data_t *data = user_data; + graph_ident_t *ident; + const char *host; + + /* make compiler happy */ + cfg = NULL; + + ident = inst_get_selector (inst); + if (ident == NULL) + return (-1); + + host = ident_get_host (ident); + if (host == NULL) + { + ident_destroy (ident); + return (-1); + } + + if (IS_ALL (host)) + return (0); + + if ((data->last_host != NULL) + && (strcmp (data->last_host, host) == 0)) + { + ident_destroy (ident); + return (0); + } + + free (data->last_host); + data->last_host = strdup (host); + + array_append (data->array, host); + + ident_destroy (ident); + return (0); +} /* }}} int print_host_list_callback */ + +static int print_host_list (__attribute__((unused)) void *user_data) /* {{{ */ +{ + print_host_list_data_t data; + int hosts_argc; + char **hosts_argv; + int i; + + data.array = array_create (); + data.last_host = NULL; + + gl_instance_get_all (print_host_list_callback, &data); + + free (data.last_host); + data.last_host = NULL; + + array_sort (data.array); + + hosts_argc = array_argc (data.array); + hosts_argv = array_argv (data.array); + + if (hosts_argc < 1) + { + array_destroy (data.array); + return (0); + } + + printf ("
    \n"); + for (i = 0; i < hosts_argc; i++) + { + char *host = hosts_argv[i]; + char *host_html; + + if ((data.last_host != NULL) && (strcmp (data.last_host, host) == 0)) + continue; + data.last_host = host; + + host_html = html_escape (host); + + printf ("
  • %s
  • \n", + script_name (), host_html, host_html); + + free (host_html); + } + printf ("
\n"); + + array_destroy (data.array); + + return (0); +} /* }}} int print_host_list */ + +static int list_graphs_html (const char *term) /* {{{ */ +{ + page_data_t pg_data; + page_callbacks_t pg_callbacks = PAGE_CALLBACKS_INIT; + char title[512]; + + if (term != NULL) + snprintf (title, sizeof (title), "c4: Graphs matching \"%s\"", term); + else + strncpy (title, "c4: List of all graphs", sizeof (title)); + title[sizeof (title) - 1] = 0; + + memset (&pg_data, 0, sizeof (pg_data)); + pg_data.search_term = term; + + pg_callbacks.top_right = print_search_box; + pg_callbacks.middle_left = print_host_list; + pg_callbacks.middle_center = print_search_result; + + html_print_page (title, &pg_callbacks, &pg_data); return (0); } /* }}} int list_graphs_html */ @@ -227,7 +358,7 @@ static int list_graphs_html (const char *term) /* {{{ */ int action_list_graphs (void) /* {{{ */ { const char *format; - const char *search; + char *search; int status; gl_update (); diff --git a/src/utils_cgi.c b/src/utils_cgi.c index fb9a1fb..daf9765 100644 --- a/src/utils_cgi.c +++ b/src/utils_cgi.c @@ -7,6 +7,9 @@ #include "utils_cgi.h" +#include +#include + struct parameter_s { char *key; @@ -355,4 +358,81 @@ char *html_escape (const char *string) /* {{{ */ return (strdup (buffer)); } /* }}} char *html_escape */ +int html_print_page (const char *title, /* {{{ */ + const page_callbacks_t *cb, void *user_data) +{ + char *title_html; + + printf ("Content-Type: text/html\n\n"); + + if (title == NULL) + title = "c4: collection4 graph interface"; + + title_html = html_escape (title); + + printf ("\n" + " \n" + " %s\n" + " \n" + " \n" + " \n" + " \n", + title_html); + + printf (" \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "
"); + if (cb->top_left != NULL) + (*cb->top_left) (user_data); + printf (""); + if (cb->top_center != NULL) + (*cb->top_center) (user_data); + else + printf ("

%s

", title_html); + printf ("
"); + if (cb->top_right != NULL) + (*cb->top_right) (user_data); + printf ("
"); + if (cb->middle_left != NULL) + (*cb->middle_left) (user_data); + printf (""); + if (cb->middle_center != NULL) + (*cb->middle_center) (user_data); + printf (""); + if (cb->middle_right != NULL) + (*cb->middle_right) (user_data); + printf ("
"); + if (cb->bottom_left != NULL) + (*cb->bottom_left) (user_data); + printf (""); + if (cb->bottom_center != NULL) + (*cb->bottom_center) (user_data); + printf (""); + if (cb->bottom_right != NULL) + (*cb->bottom_right) (user_data); + printf ("
\n" + " \n" + "\n"); + + free (title_html); + return (0); +} /* }}} int html_print_page */ + /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/utils_cgi.h b/src/utils_cgi.h index 3204b62..20f806c 100644 --- a/src/utils_cgi.h +++ b/src/utils_cgi.h @@ -3,6 +3,27 @@ #include +typedef int (*page_callback_t) (void *user_data); + +struct page_callbacks_s +{ + page_callback_t top_left; + page_callback_t top_center; + page_callback_t top_right; + page_callback_t middle_left; + page_callback_t middle_center; + page_callback_t middle_right; + page_callback_t bottom_left; + page_callback_t bottom_center; + page_callback_t bottom_right; +}; +typedef struct page_callbacks_s page_callbacks_t; + +#define PAGE_CALLBACKS_INIT \ +{ NULL, NULL, NULL, \ + NULL, NULL, NULL, \ + NULL, NULL, NULL } + int param_init (void); void param_finish (void); @@ -18,5 +39,8 @@ char *html_escape (const char *string); char *html_escape_buffer (char *buffer, size_t buffer_size); char *html_escape_copy (char *dest, const char *src, size_t n); +int html_print_page (const char *title, + const page_callbacks_t *cb, void *user_data); + /* vim: set sw=2 sts=2 et fdm=marker : */ #endif /* UTILS_CGI_H */ -- 2.11.0 From 203ada258a6e4144a89f6920e8754074d41ca550 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 21 Jun 2010 10:41:59 +0200 Subject: [PATCH 08/16] share/style.css: Add some basic styles for the table layout. --- share/style.css | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/share/style.css b/share/style.css index aafe97c..d5b1161 100644 --- a/share/style.css +++ b/share/style.css @@ -3,11 +3,42 @@ body font-family: sans-serif; } +#layout-table +{ + width: 100%; +} + +#layout-top-left, +#layout-middle-left, +#layout-bottom-left +{ + width: 10%; + min-width: 250px; +} + +#layout-top-center, +#layout-middle-center, +#layout-bottom-center +{ +} + +#layout-top-right, +#layout-middle-right, +#layout-bottom-right +{ + width: 10%; + min-width: 300px; +} + +#layout-middle td +{ + vertical-align: top; +} + ul.graph_list { margin: 0; padding: 1ex; - width: 50ex; } li.graph -- 2.11.0 From c4939342ce1aa40bc845f0d2c826c21cc56d17d7 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 21 Jun 2010 10:52:26 +0200 Subject: [PATCH 09/16] src/utils_cgi.[ch]: Move "html_print_search_box" to here. --- src/action_list_graphs.c | 28 +--------------------------- src/utils_cgi.c | 19 +++++++++++++++++++ src/utils_cgi.h | 2 ++ 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/action_list_graphs.c b/src/action_list_graphs.c index dad4367..a236517 100644 --- a/src/action_list_graphs.c +++ b/src/action_list_graphs.c @@ -185,32 +185,6 @@ struct page_data_s }; typedef struct page_data_s page_data_t; -static int print_search_box (void *user_data) /* {{{ */ -{ - page_data_t *data = user_data; - char *term_html; - - if (data == NULL) - { - fprintf (stderr, "print_search_box: data == NULL\n"); - return (EINVAL); - } - - term_html = html_escape (data->search_term); - - printf ("
\n" - " \n" - " \n" - " \n" - "
\n", - script_name (), - (term_html != NULL) ? term_html : ""); - - free (term_html); - - return (0); -} /* }}} int print_search_box */ - static int print_search_result (void *user_data) /* {{{ */ { page_data_t *pg_data = user_data; @@ -346,7 +320,7 @@ static int list_graphs_html (const char *term) /* {{{ */ memset (&pg_data, 0, sizeof (pg_data)); pg_data.search_term = term; - pg_callbacks.top_right = print_search_box; + pg_callbacks.top_right = html_print_search_box; pg_callbacks.middle_left = print_host_list; pg_callbacks.middle_center = print_search_result; diff --git a/src/utils_cgi.c b/src/utils_cgi.c index daf9765..9030eb8 100644 --- a/src/utils_cgi.c +++ b/src/utils_cgi.c @@ -435,4 +435,23 @@ int html_print_page (const char *title, /* {{{ */ return (0); } /* }}} int html_print_page */ +int html_print_search_box (__attribute__((unused)) void *user_data) /* {{{ */ +{ + char *term_html; + + term_html = html_escape (param ("search")); + + printf ("
\n" + " \n" + " \n" + " \n" + "
\n", + script_name (), + (term_html != NULL) ? term_html : ""); + + free (term_html); + + return (0); +} /* }}} int html_print_search_box */ + /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/utils_cgi.h b/src/utils_cgi.h index 20f806c..e8e847e 100644 --- a/src/utils_cgi.h +++ b/src/utils_cgi.h @@ -42,5 +42,7 @@ char *html_escape_copy (char *dest, const char *src, size_t n); int html_print_page (const char *title, const page_callbacks_t *cb, void *user_data); +int html_print_search_box (void *user_data); + /* vim: set sw=2 sts=2 et fdm=marker : */ #endif /* UTILS_CGI_H */ -- 2.11.0 From 30478870f2afaf991ee19ab7b4c22d3ddcd7b8cd Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 21 Jun 2010 11:01:59 +0200 Subject: [PATCH 10/16] "search json" action: Move the JSON callback method into an own action. --- share/collection.js | 2 +- src/Makefile.am | 1 + src/action_list_graphs.c | 130 +++------------------------------------ src/action_search_json.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++ src/action_search_json.h | 7 +++ src/main.c | 2 + 6 files changed, 174 insertions(+), 122 deletions(-) create mode 100644 src/action_search_json.c create mode 100644 src/action_search_json.h diff --git a/share/collection.js b/share/collection.js index de79a99..026d434 100644 --- a/share/collection.js +++ b/share/collection.js @@ -29,7 +29,7 @@ $(document).ready(function() { { var term = $("#search-input").val (); $.getJSON ("collection.fcgi", - { "action": "list_graphs", "format": "json", "search": term}, + { "action": "search_json", "q": term}, function(data) { var i; diff --git a/src/Makefile.am b/src/Makefile.am index ac11e9f..a77f669 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,6 +17,7 @@ collection_fcgi_SOURCES = main.c \ oconfig.c oconfig.h aux_types.h scanner.l parser.y \ action_graph.c action_graph.h \ action_list_graphs.c action_list_graphs.h \ + action_search_json.c action_search_json.h \ common.c common.h \ filesystem.c filesystem.h \ graph_types.h \ diff --git a/src/action_list_graphs.c b/src/action_list_graphs.c index a236517..922308b 100644 --- a/src/action_list_graphs.c +++ b/src/action_list_graphs.c @@ -23,118 +23,6 @@ struct callback_data_s }; typedef struct callback_data_s callback_data_t; -static int json_begin_graph (graph_config_t *cfg) /* {{{ */ -{ - char desc[1024]; - - if (cfg == NULL) - return (EINVAL); - - graph_get_title (cfg, desc, sizeof (desc)); - - printf ("{\"title\":\"%s\",\"instances\":[", desc); - - return (0); -} /* }}} int json_begin_graph */ - -static int json_end_graph (void) /* {{{ */ -{ - printf ("]}"); - - return (0); -} /* }}} int json_end_graph */ - -static int json_print_instance (graph_config_t *cfg, /* {{{ */ - graph_instance_t *inst) -{ - char params[1024]; - char desc[1024]; - - if ((cfg == NULL) || (inst == NULL)) - return (EINVAL); - - memset (desc, 0, sizeof (desc)); - inst_describe (cfg, inst, desc, sizeof (desc)); - - memset (params, 0, sizeof (params)); - inst_get_params (cfg, inst, params, sizeof (params)); - - printf ("{\"description\":\"%s\",\"params\":\"%s\"}", - desc, params); - - return (0); -} /* }}} int json_print_instance */ - -static int print_graph_inst_json (graph_config_t *cfg, /* {{{ */ - graph_instance_t *inst, - void *user_data) -{ - callback_data_t *data = user_data; - - if (data->cfg != cfg) - { - if (!data->first) - { - json_end_graph (); - printf (",\n"); - } - json_begin_graph (cfg); - - data->cfg = cfg; - data->first = 0; - } - else /* if (not first instance) */ - { - printf (",\n"); - } - - json_print_instance (cfg, inst); - - if (data->limit > 0) - data->limit--; - - if (data->limit == 0) - return (1); - - return (0); -} /* }}} int print_graph_inst_json */ - -static int list_graphs_json (const char *term) /* {{{ */ -{ - callback_data_t data; - - time_t now; - char time_buffer[128]; - int status; - - printf ("Content-Type: application/json\n"); - - now = time (NULL); - status = time_to_rfc1123 (now + 300, time_buffer, sizeof (time_buffer)); - if (status == 0) - printf ("Expires: %s\n" - "Cache-Control: public\n", - time_buffer); - printf ("\n"); - - data.cfg = NULL; - data.limit = RESULT_LIMIT; - data.first = 1; - - printf ("[\n"); - if (term == NULL) - gl_instance_get_all (print_graph_inst_json, /* user_data = */ &data); - else - gl_search (term, print_graph_inst_json, /* user_data = */ &data); - - if (!data.first) - json_end_graph (); - - printf ("\n]"); - - return (0); -} /* }}} int list_graphs_json */ - static int print_graph_inst_html (graph_config_t *cfg, /* {{{ */ graph_instance_t *inst, void *user_data) @@ -190,6 +78,14 @@ static int print_search_result (void *user_data) /* {{{ */ page_data_t *pg_data = user_data; callback_data_t cb_data = { NULL, /* limit = */ RESULT_LIMIT, /* first = */ 1 }; + if (pg_data->search_term != NULL) + { + char *search_term_html = html_escape (pg_data->search_term); + printf ("

Search results for "%s"

\n", + search_term_html); + free (search_term_html); + } + printf ("
    \n"); if (pg_data->search_term == NULL) gl_instance_get_all (print_graph_inst_html, /* user_data = */ &cb_data); @@ -331,7 +227,6 @@ static int list_graphs_html (const char *term) /* {{{ */ int action_list_graphs (void) /* {{{ */ { - const char *format; char *search; int status; @@ -339,14 +234,7 @@ int action_list_graphs (void) /* {{{ */ search = strtolower_copy (param ("search")); - format = param ("format"); - if (format == NULL) - format = "html"; - - if (strcmp ("json", format) == 0) - status = list_graphs_json (search); - else - status = list_graphs_html (search); + status = list_graphs_html (search); free (search); diff --git a/src/action_search_json.c b/src/action_search_json.c new file mode 100644 index 0000000..0786a8f --- /dev/null +++ b/src/action_search_json.c @@ -0,0 +1,154 @@ +#include +#include +#include +#include + +#include "action_search_json.h" +#include "common.h" +#include "graph.h" +#include "graph_ident.h" +#include "graph_list.h" +#include "utils_cgi.h" + +#include +#include + +#define RESULT_LIMIT 10 + +struct callback_data_s +{ + graph_config_t *cfg; + int limit; + _Bool first; +}; +typedef struct callback_data_s callback_data_t; + +static int json_begin_graph (graph_config_t *cfg) /* {{{ */ +{ + char desc[1024]; + + if (cfg == NULL) + return (EINVAL); + + graph_get_title (cfg, desc, sizeof (desc)); + + printf ("{\"title\":\"%s\",\"instances\":[", desc); + + return (0); +} /* }}} int json_begin_graph */ + +static int json_end_graph (void) /* {{{ */ +{ + printf ("]}"); + + return (0); +} /* }}} int json_end_graph */ + +static int json_print_instance (graph_config_t *cfg, /* {{{ */ + graph_instance_t *inst) +{ + char params[1024]; + char desc[1024]; + + if ((cfg == NULL) || (inst == NULL)) + return (EINVAL); + + memset (desc, 0, sizeof (desc)); + inst_describe (cfg, inst, desc, sizeof (desc)); + + memset (params, 0, sizeof (params)); + inst_get_params (cfg, inst, params, sizeof (params)); + + printf ("{\"description\":\"%s\",\"params\":\"%s\"}", + desc, params); + + return (0); +} /* }}} int json_print_instance */ + +static int json_print_graph_instance (graph_config_t *cfg, /* {{{ */ + graph_instance_t *inst, + void *user_data) +{ + callback_data_t *data = user_data; + + if (data->cfg != cfg) + { + if (!data->first) + { + json_end_graph (); + printf (",\n"); + } + json_begin_graph (cfg); + + data->cfg = cfg; + data->first = 0; + } + else /* if (not first instance) */ + { + printf (",\n"); + } + + json_print_instance (cfg, inst); + + if (data->limit > 0) + data->limit--; + + if (data->limit == 0) + return (1); + + return (0); +} /* }}} int json_print_graph_instance */ + +static int list_graphs_json (const char *term) /* {{{ */ +{ + callback_data_t data; + + time_t now; + char time_buffer[128]; + int status; + + printf ("Content-Type: application/json\n"); + + now = time (NULL); + status = time_to_rfc1123 (now + 300, time_buffer, sizeof (time_buffer)); + if (status == 0) + printf ("Expires: %s\n" + "Cache-Control: public\n", + time_buffer); + printf ("\n"); + + data.cfg = NULL; + data.limit = RESULT_LIMIT; + data.first = 1; + + printf ("[\n"); + if (term == NULL) + gl_instance_get_all (json_print_graph_instance, /* user_data = */ &data); + else + gl_search (term, json_print_graph_instance, /* user_data = */ &data); + + if (!data.first) + json_end_graph (); + + printf ("\n]"); + + return (0); +} /* }}} int list_graphs_json */ + +int action_search_json (void) /* {{{ */ +{ + char *search; + int status; + + gl_update (); + + search = strtolower_copy (param ("q")); + + status = list_graphs_json (search); + + free (search); + + return (status); +} /* }}} int action_search_json */ + +/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/action_search_json.h b/src/action_search_json.h new file mode 100644 index 0000000..1bc19c6 --- /dev/null +++ b/src/action_search_json.h @@ -0,0 +1,7 @@ +#ifndef ACTION_SEARCH_JSON +#define ACTION_SEARCH_JSON 1 + +int action_search_json (void); + +#endif /* ACTION_SEARCH_JSON */ +/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/main.c b/src/main.c index 5c2b146..13add00 100644 --- a/src/main.c +++ b/src/main.c @@ -15,6 +15,7 @@ #include "action_graph.h" #include "action_list_graphs.h" +#include "action_search_json.h" /* Include this last, so the macro magic of doesn't interfere * with our own header files. */ @@ -34,6 +35,7 @@ static const action_t actions[] = { { "graph", action_graph }, { "list_graphs", action_list_graphs }, + { "search_json", action_search_json }, { "usage", action_usage } }; static const size_t actions_num = sizeof (actions) / sizeof (actions[0]); -- 2.11.0 From 25849a1143a916b31fb9782a6cf10399849f88ef Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 21 Jun 2010 11:38:37 +0200 Subject: [PATCH 11/16] "show graph" action: Add page showing one instance of a graph. --- src/Makefile.am | 1 + src/action_list_graphs.c | 2 +- src/action_show_graph.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++ src/action_show_graph.h | 7 +++ src/main.c | 2 + 5 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 src/action_show_graph.c create mode 100644 src/action_show_graph.h diff --git a/src/Makefile.am b/src/Makefile.am index a77f669..ea4e837 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,6 +18,7 @@ collection_fcgi_SOURCES = main.c \ action_graph.c action_graph.h \ action_list_graphs.c action_list_graphs.h \ action_search_json.c action_search_json.h \ + action_show_graph.c action_show_graph.h \ common.c common.h \ filesystem.c filesystem.h \ graph_types.h \ diff --git a/src/action_list_graphs.c b/src/action_list_graphs.c index 922308b..7c8768a 100644 --- a/src/action_list_graphs.c +++ b/src/action_list_graphs.c @@ -54,7 +54,7 @@ static int print_graph_inst_html (graph_config_t *cfg, /* {{{ */ inst_describe (cfg, inst, desc, sizeof (desc)); html_escape_buffer (desc, sizeof (desc)); - printf ("
  • %s
  • \n", + printf ("
  • %s
  • \n", script_name (), params, desc); if (data->limit > 0) diff --git a/src/action_show_graph.c b/src/action_show_graph.c new file mode 100644 index 0000000..40ebcd3 --- /dev/null +++ b/src/action_show_graph.c @@ -0,0 +1,142 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "action_show_graph.h" +#include "common.h" +#include "graph_list.h" +#include "utils_cgi.h" + +#include +#include + +#define OUTPUT_ERROR(...) do { \ + printf ("Content-Type: text/plain\n\n"); \ + printf (__VA_ARGS__); \ + return (0); \ +} while (0) + +struct show_graph_data_s +{ + graph_config_t *cfg; + graph_instance_t *inst; +}; +typedef struct show_graph_data_s show_graph_data_t; + +static int show_instance_list_cb (graph_instance_t *inst, /* {{{ */ + void *user_data) +{ + show_graph_data_t *data = user_data; + char descr[128]; + char params[1024]; + + memset (descr, 0, sizeof (descr)); + inst_describe (data->cfg, inst, descr, sizeof (descr)); + html_escape_buffer (descr, sizeof (descr)); + + if (inst == data->inst) + { + printf ("
  • %s
  • \n", descr); + return (0); + } + + memset (params, 0, sizeof (params)); + inst_get_params (data->cfg, inst, params, sizeof (params)); + html_escape_buffer (params, sizeof (params)); + + printf ("
  • %s
  • \n", + script_name (), params, descr); + + return (0); +} /* }}} int show_instance_list_cb */ + +static int show_instance_list (void *user_data) /* {{{ */ +{ + show_graph_data_t *data = user_data; + graph_instance_t *inst; + char title[128]; + + memset (title, 0, sizeof (title)); + graph_get_title (data->cfg, title, sizeof (title)); + html_escape_buffer (title, sizeof (title)); + + printf ("
      \n" + "
    • %s\n" + "
        \n", title); + + inst = graph_get_instances (data->cfg); + inst_foreach (inst, show_instance_list_cb, user_data); + + printf ("
      \n" + "
    \n"); + + return (0); +} /* }}} int show_instance_list */ + +static int show_graph (void *user_data) /* {{{ */ +{ + show_graph_data_t *data = user_data; + char title[128]; + char descr[128]; + char params[1024]; + + memset (title, 0, sizeof (title)); + graph_get_title (data->cfg, title, sizeof (title)); + html_escape_buffer (title, sizeof (title)); + + memset (descr, 0, sizeof (descr)); + inst_describe (data->cfg, data->inst, descr, sizeof (descr)); + html_escape_buffer (descr, sizeof (descr)); + + memset (params, 0, sizeof (params)); + inst_get_params (data->cfg, data->inst, params, sizeof (params)); + html_escape_buffer (params, sizeof (params)); + + printf ("
    \n", + script_name (), params, title, descr); + + return (0); +} /* }}} int show_graph */ + +int action_show_graph (void) /* {{{ */ +{ + page_callbacks_t pg_callbacks = PAGE_CALLBACKS_INIT; + show_graph_data_t pg_data; + + char title[128]; + char descr[128]; + char html_title[128]; + + pg_data.cfg = gl_graph_get_selected (); + if (pg_data.cfg == NULL) + OUTPUT_ERROR ("gl_graph_get_selected () failed.\n"); + + pg_data.inst = inst_get_selected (pg_data.cfg); + if (pg_data.inst == NULL) + OUTPUT_ERROR ("inst_get_selected (%p) failed.\n", (void *) pg_data.cfg); + + memset (title, 0, sizeof (title)); + graph_get_title (pg_data.cfg, title, sizeof (title)); + + memset (descr, 0, sizeof (descr)); + inst_describe (pg_data.cfg, pg_data.inst, descr, sizeof (descr)); + + snprintf (html_title, sizeof (html_title), "Graph \"%s / %s\"", + title, descr); + html_title[sizeof (html_title) - 1] = 0; + + pg_callbacks.top_right = html_print_search_box; + pg_callbacks.middle_center = show_graph; + pg_callbacks.middle_left = show_instance_list; + + html_print_page (html_title, &pg_callbacks, &pg_data); + + return (0); +} /* }}} int action_graph */ + +/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/action_show_graph.h b/src/action_show_graph.h new file mode 100644 index 0000000..5b5e78a --- /dev/null +++ b/src/action_show_graph.h @@ -0,0 +1,7 @@ +#ifndef ACTION_SHOW_GRAPH_H +#define ACTION_SHOW_GRAPH_H 1 + +int action_show_graph (void); + +#endif /* ACTION_SHOW_GRAPH_H */ +/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/main.c b/src/main.c index 13add00..5fd34d1 100644 --- a/src/main.c +++ b/src/main.c @@ -16,6 +16,7 @@ #include "action_graph.h" #include "action_list_graphs.h" #include "action_search_json.h" +#include "action_show_graph.h" /* Include this last, so the macro magic of doesn't interfere * with our own header files. */ @@ -36,6 +37,7 @@ static const action_t actions[] = { "graph", action_graph }, { "list_graphs", action_list_graphs }, { "search_json", action_search_json }, + { "show_graph", action_show_graph }, { "usage", action_usage } }; static const size_t actions_num = sizeof (actions) / sizeof (actions[0]); -- 2.11.0 From dc45c37c2c3fe9ae46e3bbbc46654eba0c2672e6 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 21 Jun 2010 12:30:07 +0200 Subject: [PATCH 12/16] src/graph.[ch]: Implement "graph_inst_foreach". --- src/graph.c | 6 ++++++ src/graph.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/src/graph.c b/src/graph.c index d314bcc..a503bfe 100644 --- a/src/graph.c +++ b/src/graph.c @@ -269,6 +269,12 @@ static int graph_search_submit (graph_instance_t *inst, /* {{{ */ return ((*data->callback) (data->cfg, inst, data->user_data)); } /* }}} int graph_search_submit */ +int graph_inst_foreach (graph_config_t *cfg, /* {{{ */ + inst_callback_t cb, void *user_data) +{ + return (inst_foreach (cfg->instances, cb, user_data)); +} /* }}} int graph_inst_foreach */ + int graph_search (graph_config_t *cfg, const char *term, /* {{{ */ graph_inst_callback_t callback, void *user_data) diff --git a/src/graph.h b/src/graph.h index 57a866f..98014c5 100644 --- a/src/graph.h +++ b/src/graph.h @@ -29,6 +29,9 @@ int graph_add_def (graph_config_t *cfg, graph_def_t *def); _Bool graph_matches (graph_config_t *cfg, const graph_ident_t *ident); +int graph_inst_foreach (graph_config_t *cfg, + inst_callback_t cb, void *user_data); + int graph_search (graph_config_t *cfg, const char *term, graph_inst_callback_t callback, void *user_data); -- 2.11.0 From 5e630d84e5baa7b105ff83f81555c1e62f5a68ba Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 21 Jun 2010 12:30:28 +0200 Subject: [PATCH 13/16] src/graph.[ch]: Implement "graph_get_params". --- src/graph.c | 29 +++++++++++++++++++++++++++++ src/graph.h | 2 ++ 2 files changed, 31 insertions(+) diff --git a/src/graph.c b/src/graph.c index a503bfe..6b89859 100644 --- a/src/graph.c +++ b/src/graph.c @@ -204,6 +204,35 @@ int graph_get_title (graph_config_t *cfg, /* {{{ */ return (0); } /* }}} int graph_get_title */ +int graph_get_params (graph_config_t *cfg, /* {{{ */ + char *buffer, size_t buffer_size) +{ + buffer[0] = 0; + +#define COPY_FIELD(field) do { \ + const char *str = ident_get_##field (cfg->select); \ + char uri_str[1024]; \ + uri_escape (uri_str, str, sizeof (uri_str)); \ + strlcat (buffer, #field, buffer_size); \ + strlcat (buffer, "=", buffer_size); \ + strlcat (buffer, uri_str, buffer_size); \ +} while (0) + + COPY_FIELD(host); + strlcat (buffer, ";", buffer_size); + COPY_FIELD(plugin); + strlcat (buffer, ";", buffer_size); + COPY_FIELD(plugin_instance); + strlcat (buffer, ";", buffer_size); + COPY_FIELD(type); + strlcat (buffer, ";", buffer_size); + COPY_FIELD(type_instance); + +#undef COPY_FIELD + + return (0); +} /* }}} int graph_get_params */ + graph_ident_t *graph_get_selector (graph_config_t *cfg) /* {{{ */ { if (cfg == NULL) diff --git a/src/graph.h b/src/graph.h index 98014c5..7f1115c 100644 --- a/src/graph.h +++ b/src/graph.h @@ -19,6 +19,8 @@ int graph_add_file (graph_config_t *cfg, const graph_ident_t *file); int graph_get_title (graph_config_t *cfg, char *buffer, size_t buffer_size); +int graph_get_params (graph_config_t *cfg, char *buffer, size_t buffer_size); + graph_ident_t *graph_get_selector (graph_config_t *cfg); graph_instance_t *graph_get_instances (graph_config_t *cfg); -- 2.11.0 From 173727f52463a5e2f60e7363456f90905d67e669 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 21 Jun 2010 12:31:27 +0200 Subject: [PATCH 14/16] "show graph" action: Implement displaying _graphs_ (rather than instances). A "breadcrump" field has been added, too. --- src/action_show_graph.c | 116 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 94 insertions(+), 22 deletions(-) diff --git a/src/action_show_graph.c b/src/action_show_graph.c index 40ebcd3..5aaf25a 100644 --- a/src/action_show_graph.c +++ b/src/action_show_graph.c @@ -8,6 +8,7 @@ #include "action_show_graph.h" #include "common.h" +#include "graph_ident.h" #include "graph_list.h" #include "utils_cgi.h" @@ -27,6 +28,54 @@ struct show_graph_data_s }; typedef struct show_graph_data_s show_graph_data_t; +static void show_breadcrump_field (const char *str) /* {{{ */ +{ + if ((str == NULL) || (str[0] == 0)) + printf ("none"); + else if (IS_ANY (str)) + printf ("any"); + else if (IS_ALL (str)) + printf ("all"); + else + { + char *str_html = html_escape (str); + printf ("%s", + script_name (), str_html, str_html); + free (str_html); + } +} /* }}} void show_breadcrump_field */ + +static int show_breadcrump (show_graph_data_t *data) /* {{{ */ +{ + graph_ident_t *ident; + char *prefix; + + if (data->inst != NULL) + { + prefix = "Instance"; + ident = inst_get_selector (data->inst); + } + else + { + prefix = "Graph"; + ident = graph_get_selector (data->cfg); + } + + printf ("
    %s: "", prefix); + show_breadcrump_field (ident_get_host (ident)); + printf (" / "); + show_breadcrump_field (ident_get_plugin (ident)); + printf (" – "); + show_breadcrump_field (ident_get_plugin_instance (ident)); + printf (" / "); + show_breadcrump_field (ident_get_type (ident)); + printf (" – "); + show_breadcrump_field (ident_get_type_instance (ident)); + printf (""
    \n"); + + return (0); +} /* }}} int show_breadcrump */ + static int show_instance_list_cb (graph_instance_t *inst, /* {{{ */ void *user_data) { @@ -48,7 +97,8 @@ static int show_instance_list_cb (graph_instance_t *inst, /* {{{ */ inst_get_params (data->cfg, inst, params, sizeof (params)); html_escape_buffer (params, sizeof (params)); - printf ("
  • %s
  • \n", + printf ("
  • " + "%s
  • \n", script_name (), params, descr); return (0); @@ -57,19 +107,23 @@ static int show_instance_list_cb (graph_instance_t *inst, /* {{{ */ static int show_instance_list (void *user_data) /* {{{ */ { show_graph_data_t *data = user_data; - graph_instance_t *inst; char title[128]; + char params[1024]; memset (title, 0, sizeof (title)); graph_get_title (data->cfg, title, sizeof (title)); html_escape_buffer (title, sizeof (title)); + memset (params, 0, sizeof (params)); + graph_get_params (data->cfg, params, sizeof (params)); + html_escape_buffer (params, sizeof (params)); + printf ("
      \n" - "
    • %s\n" - "
        \n", title); + "
      • %s\n" + "
          \n", + script_name (), params, title); - inst = graph_get_instances (data->cfg); - inst_foreach (inst, show_instance_list_cb, user_data); + graph_inst_foreach (data->cfg, show_instance_list_cb, user_data); printf ("
        \n" "
      \n"); @@ -77,13 +131,15 @@ static int show_instance_list (void *user_data) /* {{{ */ return (0); } /* }}} int show_instance_list */ -static int show_graph (void *user_data) /* {{{ */ +static int show_instance (void *user_data) /* {{{ */ { show_graph_data_t *data = user_data; char title[128]; char descr[128]; char params[1024]; + show_breadcrump (data); + memset (title, 0, sizeof (title)); graph_get_title (data->cfg, title, sizeof (title)); html_escape_buffer (title, sizeof (title)); @@ -101,6 +157,14 @@ static int show_graph (void *user_data) /* {{{ */ script_name (), params, title, descr); return (0); +} /* }}} int show_instance */ + +static int show_graph (void *user_data) +{ + show_graph_data_t *data = user_data; + + show_breadcrump (data); + return (show_instance_list (user_data)); } /* }}} int show_graph */ int action_show_graph (void) /* {{{ */ @@ -109,32 +173,40 @@ int action_show_graph (void) /* {{{ */ show_graph_data_t pg_data; char title[128]; - char descr[128]; - char html_title[128]; pg_data.cfg = gl_graph_get_selected (); if (pg_data.cfg == NULL) OUTPUT_ERROR ("gl_graph_get_selected () failed.\n"); - pg_data.inst = inst_get_selected (pg_data.cfg); - if (pg_data.inst == NULL) - OUTPUT_ERROR ("inst_get_selected (%p) failed.\n", (void *) pg_data.cfg); - memset (title, 0, sizeof (title)); graph_get_title (pg_data.cfg, title, sizeof (title)); - memset (descr, 0, sizeof (descr)); - inst_describe (pg_data.cfg, pg_data.inst, descr, sizeof (descr)); + pg_data.inst = inst_get_selected (pg_data.cfg); + if (pg_data.inst != NULL) + { + char descr[128]; + char html_title[128]; + + memset (descr, 0, sizeof (descr)); + inst_describe (pg_data.cfg, pg_data.inst, descr, sizeof (descr)); - snprintf (html_title, sizeof (html_title), "Graph \"%s / %s\"", - title, descr); - html_title[sizeof (html_title) - 1] = 0; + snprintf (html_title, sizeof (html_title), "Graph \"%s / %s\"", + title, descr); + html_title[sizeof (html_title) - 1] = 0; - pg_callbacks.top_right = html_print_search_box; - pg_callbacks.middle_center = show_graph; - pg_callbacks.middle_left = show_instance_list; + pg_callbacks.top_right = html_print_search_box; + pg_callbacks.middle_center = show_instance; + pg_callbacks.middle_left = show_instance_list; - html_print_page (html_title, &pg_callbacks, &pg_data); + html_print_page (html_title, &pg_callbacks, &pg_data); + } + else /* if (pg_data.inst == NULL) */ + { + pg_callbacks.top_right = html_print_search_box; + pg_callbacks.middle_center = show_graph; + + html_print_page (title, &pg_callbacks, &pg_data); + } return (0); } /* }}} int action_graph */ -- 2.11.0 From 29ed9845a482b6eb5b4ced51fef43129be0e2fd3 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 21 Jun 2010 15:26:16 +0200 Subject: [PATCH 15/16] "list graphs" action: Limit the number of graphs and instances separately. --- src/action_list_graphs.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/src/action_list_graphs.c b/src/action_list_graphs.c index 7c8768a..e32b999 100644 --- a/src/action_list_graphs.c +++ b/src/action_list_graphs.c @@ -18,8 +18,12 @@ struct callback_data_s { graph_config_t *cfg; - int limit; - _Bool first; + int graph_index; + int graph_limit; + _Bool graph_more; + int inst_index; + int inst_limit; + _Bool inst_more; }; typedef struct callback_data_s callback_data_t; @@ -33,6 +37,13 @@ static int print_graph_inst_html (graph_config_t *cfg, /* {{{ */ if (data->cfg != cfg) { + data->graph_index++; + if (data->graph_index >= data->graph_limit) + { + data->graph_more = 1; + return (1); + } + if (data->cfg != NULL) printf ("
    \n"); @@ -44,6 +55,19 @@ static int print_graph_inst_html (graph_config_t *cfg, /* {{{ */ "
      \n", desc); data->cfg = cfg; + data->inst_index = -1; + data->inst_more = 0; + } + + data->inst_index++; + if (data->inst_index >= data->inst_limit) + { + if (!data->inst_more) + { + printf ("
    • More ...
    • \n"); + data->inst_more = 1; + } + return (0); } memset (params, 0, sizeof (params)); @@ -57,13 +81,6 @@ static int print_graph_inst_html (graph_config_t *cfg, /* {{{ */ printf ("
    • %s
    • \n", script_name (), params, desc); - if (data->limit > 0) - data->limit--; - - /* Abort scan if limit is reached. */ - if (data->limit == 0) - return (1); - return (0); } /* }}} int print_graph_inst_html */ @@ -76,7 +93,9 @@ typedef struct page_data_s page_data_t; static int print_search_result (void *user_data) /* {{{ */ { page_data_t *pg_data = user_data; - callback_data_t cb_data = { NULL, /* limit = */ RESULT_LIMIT, /* first = */ 1 }; + callback_data_t cb_data = { /* cfg = */ NULL, + /* graph_index = */ -1, /* graph_limit = */ 20, /* graph_more = */ 0, + /* inst_index = */ -1, /* inst_limit = */ 5, /* inst more = */ 0 }; if (pg_data->search_term != NULL) { @@ -99,6 +118,11 @@ static int print_search_result (void *user_data) /* {{{ */ if (cb_data.cfg != NULL) printf ("
    \n"); + if (cb_data.graph_more) + { + printf ("
  • More ...
  • \n"); + } + printf ("
\n"); return (0); -- 2.11.0 From 04aa292008516f3add56b9bd87ce9c57b0366cc1 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 21 Jun 2010 15:26:46 +0200 Subject: [PATCH 16/16] src/common.c: Fix a very stupid bug in "strtolower_copy". --- src/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 4916b3c..d6047c4 100644 --- a/src/common.c +++ b/src/common.c @@ -209,7 +209,7 @@ char *strtolower_copy (const char *str) if (str == NULL) return (NULL); - return (strdup (str)); + return (strtolower (strdup (str))); } /* vim: set sw=2 sts=2 et fdm=marker : */ -- 2.11.0