"list graphs" action: Support searching for plugin- and type-instances.
[collection4.git] / src / action_list_graphs.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <errno.h>
5
6 #include "action_list_graphs.h"
7 #include "common.h"
8 #include "graph.h"
9 #include "graph_ident.h"
10 #include "graph_instance.h"
11 #include "graph_list.h"
12 #include "utils_cgi.h"
13
14 #include <fcgiapp.h>
15 #include <fcgi_stdio.h>
16
17 #define RESULT_LIMIT 50
18
19 struct callback_data_s
20 {
21   graph_config_t *cfg;
22   int graph_index;
23   int graph_limit;
24   _Bool graph_more;
25   int inst_index;
26   int inst_limit;
27   _Bool inst_more;
28 };
29 typedef struct callback_data_s callback_data_t;
30
31 static int print_graph_inst_html (graph_config_t *cfg, /* {{{ */
32     graph_instance_t *inst,
33     void *user_data)
34 {
35   callback_data_t *data = user_data;
36   char params[1024];
37   char desc[1024];
38
39   if (data->cfg != cfg)
40   {
41     data->graph_index++;
42     if (data->graph_index >= data->graph_limit)
43     {
44       data->graph_more = 1;
45       return (1);
46     }
47
48     if (data->cfg != NULL)
49       printf ("  </ul></li>\n");
50
51     memset (desc, 0, sizeof (desc));
52     graph_get_title (cfg, desc, sizeof (desc));
53     html_escape_buffer (desc, sizeof (desc));
54
55     printf ("  <li class=\"graph\">%s\n"
56         "  <ul class=\"instance_list\">\n", desc);
57
58     data->cfg = cfg;
59     data->inst_index = -1;
60     data->inst_more = 0;
61   }
62
63   data->inst_index++;
64   if (data->inst_index >= data->inst_limit)
65   {
66     if (!data->inst_more)
67     {
68       printf ("    <li class=\"instance more\">More ...</li>\n");
69       data->inst_more = 1;
70     }
71     return (0);
72   }
73
74   memset (params, 0, sizeof (params));
75   inst_get_params (cfg, inst, params, sizeof (params));
76   html_escape_buffer (params, sizeof (params));
77
78   memset (desc, 0, sizeof (desc));
79   inst_describe (cfg, inst, desc, sizeof (desc));
80   html_escape_buffer (desc, sizeof (desc));
81
82   printf ("    <li class=\"instance\"><a href=\"%s?action=show_graph;%s\">%s</a></li>\n",
83       script_name (), params, desc);
84
85   return (0);
86 } /* }}} int print_graph_inst_html */
87
88 struct page_data_s
89 {
90   const char *search_term;
91 };
92 typedef struct page_data_s page_data_t;
93
94 static int print_search_result (void *user_data) /* {{{ */
95 {
96   page_data_t *pg_data = user_data;
97   callback_data_t cb_data = { /* cfg = */ NULL,
98     /* graph_index = */ -1, /* graph_limit = */ 20, /* graph_more = */ 0,
99     /* inst_index = */  -1, /* inst_limit = */   5, /* inst more = */  0 };
100
101   if (pg_data->search_term != NULL)
102   {
103     char *search_term_html = html_escape (pg_data->search_term);
104     printf ("    <h2>Search results for &quot;%s&quot;</h2>\n",
105         search_term_html);
106     free (search_term_html);
107   }
108
109   printf ("    <ul id=\"search-output\" class=\"graph_list\">\n");
110   if (pg_data->search_term == NULL)
111     gl_instance_get_all (print_graph_inst_html, /* user_data = */ &cb_data);
112   else
113   {
114     char *term_lc = strtolower_copy (pg_data->search_term);
115
116     if (strncmp ("host:", term_lc, strlen ("host:")) == 0)
117       gl_search_field (GIF_HOST, term_lc + strlen ("host:"),
118           print_graph_inst_html, /* user_data = */ &cb_data);
119     else if (strncmp ("plugin:", term_lc, strlen ("plugin:")) == 0)
120       gl_search_field (GIF_PLUGIN, term_lc + strlen ("plugin:"),
121           print_graph_inst_html, /* user_data = */ &cb_data);
122     else if (strncmp ("plugin_instance:", term_lc, strlen ("plugin_instance:")) == 0)
123       gl_search_field (GIF_PLUGIN_INSTANCE, term_lc + strlen ("plugin_instance:"),
124           print_graph_inst_html, /* user_data = */ &cb_data);
125     else if (strncmp ("type:", term_lc, strlen ("type:")) == 0)
126       gl_search_field (GIF_TYPE, term_lc + strlen ("type:"),
127           print_graph_inst_html, /* user_data = */ &cb_data);
128     else if (strncmp ("type_instance:", term_lc, strlen ("type_instance:")) == 0)
129       gl_search_field (GIF_TYPE_INSTANCE, term_lc + strlen ("type_instance:"),
130           print_graph_inst_html, /* user_data = */ &cb_data);
131     else
132       gl_search (term_lc,
133           print_graph_inst_html, /* user_data = */ &cb_data);
134
135     free (term_lc);
136   }
137
138   if (cb_data.cfg != NULL)
139     printf ("      </ul></li>\n");
140
141   if (cb_data.graph_more)
142   {
143     printf ("    <li class=\"graph more\">More ...</li>\n");
144   }
145
146   printf ("    </ul>\n");
147
148   return (0);
149 } /* }}} int print_search_result */
150
151 struct print_host_list_data_s
152 {
153   str_array_t *array;
154   char *last_host;
155 };
156 typedef struct print_host_list_data_s print_host_list_data_t;
157
158 static int print_host_list_callback (graph_config_t *cfg, /* {{{ */
159     graph_instance_t *inst, void *user_data)
160 {
161   print_host_list_data_t *data = user_data;
162   graph_ident_t *ident;
163   const char *host;
164
165   /* make compiler happy */
166   cfg = NULL;
167
168   ident = inst_get_selector (inst);
169   if (ident == NULL)
170     return (-1);
171
172   host = ident_get_host (ident);
173   if (host == NULL)
174   {
175     ident_destroy (ident);
176     return (-1);
177   }
178
179   if (IS_ALL (host))
180     return (0);
181
182   if ((data->last_host != NULL)
183       && (strcmp (data->last_host, host) == 0))
184   {
185     ident_destroy (ident);
186     return (0);
187   }
188
189   free (data->last_host);
190   data->last_host = strdup (host);
191
192   array_append (data->array, host);
193
194   ident_destroy (ident);
195   return (0);
196 } /* }}} int print_host_list_callback */
197
198 static int print_host_list (__attribute__((unused)) void *user_data) /* {{{ */
199 {
200   print_host_list_data_t data;
201   int hosts_argc;
202   char **hosts_argv;
203   int i;
204
205   data.array = array_create ();
206   data.last_host = NULL;
207
208   gl_instance_get_all (print_host_list_callback, &data);
209
210   free (data.last_host);
211   data.last_host = NULL;
212
213   array_sort (data.array);
214
215   hosts_argc = array_argc (data.array);
216   hosts_argv = array_argv (data.array);
217
218   if (hosts_argc < 1)
219   {
220     array_destroy (data.array);
221     return (0);
222   }
223
224   printf ("<div><h3>List of hosts</h3>\n"
225       "<ul id=\"host-list\">\n");
226   for (i = 0; i < hosts_argc; i++)
227   {
228     char *host = hosts_argv[i];
229     char *host_html;
230
231     if ((data.last_host != NULL) && (strcmp (data.last_host, host) == 0))
232       continue;
233     data.last_host = host;
234
235     host_html = html_escape (host);
236
237     printf ("  <li><a href=\"%s?action=list_graphs&q=host:%s\">%s</a></li>\n",
238         script_name (), host_html, host_html);
239
240     free (host_html);
241   }
242   printf ("</ul></div>\n");
243
244   array_destroy (data.array);
245
246   return (0);
247 } /* }}} int print_host_list */
248
249 static int list_graphs_html (const char *term) /* {{{ */
250 {
251   page_data_t pg_data;
252   page_callbacks_t pg_callbacks = PAGE_CALLBACKS_INIT;
253   char title[512];
254
255   if (term != NULL)
256     snprintf (title, sizeof (title), "c4: Graphs matching \"%s\"", term);
257   else
258     strncpy (title, "c4: List of all graphs", sizeof (title));
259   title[sizeof (title) - 1] = 0;
260
261   memset (&pg_data, 0, sizeof (pg_data));
262   pg_data.search_term = term;
263
264   pg_callbacks.top_right = html_print_search_box;
265   pg_callbacks.middle_left = print_host_list;
266   pg_callbacks.middle_center = print_search_result;
267
268   html_print_page (title, &pg_callbacks, &pg_data);
269
270   return (0);
271 } /* }}} int list_graphs_html */
272
273 int action_list_graphs (void) /* {{{ */
274 {
275   char *search;
276   int status;
277
278   gl_update ();
279
280   search = strtolower_copy (param ("q"));
281   status = list_graphs_html (search);
282   free (search);
283
284   return (status);
285 } /* }}} int action_list_graphs */
286
287 /* vim: set sw=2 sts=2 et fdm=marker : */