"show graph" action: Add page showing one instance of a graph.
[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_list.h"
11 #include "utils_cgi.h"
12
13 #include <fcgiapp.h>
14 #include <fcgi_stdio.h>
15
16 #define RESULT_LIMIT 50
17
18 struct callback_data_s
19 {
20   graph_config_t *cfg;
21   int limit;
22   _Bool first;
23 };
24 typedef struct callback_data_s callback_data_t;
25
26 static int print_graph_inst_html (graph_config_t *cfg, /* {{{ */
27     graph_instance_t *inst,
28     void *user_data)
29 {
30   callback_data_t *data = user_data;
31   char params[1024];
32   char desc[1024];
33
34   if (data->cfg != cfg)
35   {
36     if (data->cfg != NULL)
37       printf ("  </ul></li>\n");
38
39     memset (desc, 0, sizeof (desc));
40     graph_get_title (cfg, desc, sizeof (desc));
41     html_escape_buffer (desc, sizeof (desc));
42
43     printf ("  <li class=\"graph\">%s\n"
44         "  <ul class=\"instance_list\">\n", desc);
45
46     data->cfg = cfg;
47   }
48
49   memset (params, 0, sizeof (params));
50   inst_get_params (cfg, inst, params, sizeof (params));
51   html_escape_buffer (params, sizeof (params));
52
53   memset (desc, 0, sizeof (desc));
54   inst_describe (cfg, inst, desc, sizeof (desc));
55   html_escape_buffer (desc, sizeof (desc));
56
57   printf ("    <li class=\"instance\"><a href=\"%s?action=show_graph;%s\">%s</a></li>\n",
58       script_name (), params, desc);
59
60   if (data->limit > 0)
61     data->limit--;
62
63   /* Abort scan if limit is reached. */
64   if (data->limit == 0)
65     return (1);
66
67   return (0);
68 } /* }}} int print_graph_inst_html */
69
70 struct page_data_s
71 {
72   const char *search_term;
73 };
74 typedef struct page_data_s page_data_t;
75
76 static int print_search_result (void *user_data) /* {{{ */
77 {
78   page_data_t *pg_data = user_data;
79   callback_data_t cb_data = { NULL, /* limit = */ RESULT_LIMIT, /* first = */ 1 };
80
81   if (pg_data->search_term != NULL)
82   {
83     char *search_term_html = html_escape (pg_data->search_term);
84     printf ("    <h2>Search results for &quot;%s&quot;</h2>\n",
85         search_term_html);
86     free (search_term_html);
87   }
88
89   printf ("    <ul id=\"search-output\" class=\"graph_list\">\n");
90   if (pg_data->search_term == NULL)
91     gl_instance_get_all (print_graph_inst_html, /* user_data = */ &cb_data);
92   else
93   {
94     char *term_lc = strtolower_copy (pg_data->search_term);
95     gl_search (term_lc, print_graph_inst_html, /* user_data = */ &cb_data);
96     free (term_lc);
97   }
98
99   if (cb_data.cfg != NULL)
100     printf ("      </ul></li>\n");
101
102   printf ("    </ul>\n");
103
104   return (0);
105 } /* }}} int print_search_result */
106
107 struct print_host_list_data_s
108 {
109   str_array_t *array;
110   char *last_host;
111 };
112 typedef struct print_host_list_data_s print_host_list_data_t;
113
114 static int print_host_list_callback (graph_config_t *cfg, /* {{{ */
115     graph_instance_t *inst, void *user_data)
116 {
117   print_host_list_data_t *data = user_data;
118   graph_ident_t *ident;
119   const char *host;
120
121   /* make compiler happy */
122   cfg = NULL;
123
124   ident = inst_get_selector (inst);
125   if (ident == NULL)
126     return (-1);
127
128   host = ident_get_host (ident);
129   if (host == NULL)
130   {
131     ident_destroy (ident);
132     return (-1);
133   }
134
135   if (IS_ALL (host))
136     return (0);
137
138   if ((data->last_host != NULL)
139       && (strcmp (data->last_host, host) == 0))
140   {
141     ident_destroy (ident);
142     return (0);
143   }
144
145   free (data->last_host);
146   data->last_host = strdup (host);
147
148   array_append (data->array, host);
149
150   ident_destroy (ident);
151   return (0);
152 } /* }}} int print_host_list_callback */
153
154 static int print_host_list (__attribute__((unused)) void *user_data) /* {{{ */
155 {
156   print_host_list_data_t data;
157   int hosts_argc;
158   char **hosts_argv;
159   int i;
160
161   data.array = array_create ();
162   data.last_host = NULL;
163
164   gl_instance_get_all (print_host_list_callback, &data);
165
166   free (data.last_host);
167   data.last_host = NULL;
168
169   array_sort (data.array);
170
171   hosts_argc = array_argc (data.array);
172   hosts_argv = array_argv (data.array);
173
174   if (hosts_argc < 1)
175   {
176     array_destroy (data.array);
177     return (0);
178   }
179
180   printf ("<ul id=\"host-list\">\n");
181   for (i = 0; i < hosts_argc; i++)
182   {
183     char *host = hosts_argv[i];
184     char *host_html;
185
186     if ((data.last_host != NULL) && (strcmp (data.last_host, host) == 0))
187       continue;
188     data.last_host = host;
189
190     host_html = html_escape (host);
191
192     printf ("  <li><a href=\"%s?action=list_graphs&search=%s\">%s</a></li>\n",
193         script_name (), host_html, host_html);
194
195     free (host_html);
196   }
197   printf ("</ul>\n");
198
199   array_destroy (data.array);
200
201   return (0);
202 } /* }}} int print_host_list */
203
204 static int list_graphs_html (const char *term) /* {{{ */
205 {
206   page_data_t pg_data;
207   page_callbacks_t pg_callbacks = PAGE_CALLBACKS_INIT;
208   char title[512];
209
210   if (term != NULL)
211     snprintf (title, sizeof (title), "c4: Graphs matching \"%s\"", term);
212   else
213     strncpy (title, "c4: List of all graphs", sizeof (title));
214   title[sizeof (title) - 1] = 0;
215
216   memset (&pg_data, 0, sizeof (pg_data));
217   pg_data.search_term = term;
218
219   pg_callbacks.top_right = html_print_search_box;
220   pg_callbacks.middle_left = print_host_list;
221   pg_callbacks.middle_center = print_search_result;
222
223   html_print_page (title, &pg_callbacks, &pg_data);
224
225   return (0);
226 } /* }}} int list_graphs_html */
227
228 int action_list_graphs (void) /* {{{ */
229 {
230   char *search;
231   int status;
232
233   gl_update ();
234
235   search = strtolower_copy (param ("search"));
236
237   status = list_graphs_html (search);
238
239   free (search);
240
241   return (status);
242 } /* }}} int action_list_graphs */
243
244 /* vim: set sw=2 sts=2 et fdm=marker : */