#include "system.h"
#include "avl_tree.h"
+#include "config.h"
#include "connection.h"
#include "device.h"
#include "edge.h"
#include "subnet.h"
#include "utils.h"
+static bool graph_changed = true;
+
/* Implementation of Kruskal's algorithm.
Running time: O(EN)
Please note that sorting on weight is already done by add_edge().
{
mst_kruskal();
sssp_bfs();
+ graph_changed = true;
+}
+
+
+
+/* Dump nodes and edges to a graphviz file.
+
+ The file can be converted to an image with
+ dot -Tpng graph_filename -o image_filename.png -Gconcentrate=true
+*/
+
+void dump_graph(void)
+{
+ avl_node_t *node;
+ node_t *n;
+ edge_t *e;
+ char *filename = NULL, *tmpname = NULL;
+ FILE *file;
+
+ if(!graph_changed || !get_config_string(lookup_config(config_tree, "GraphDumpFile"), &filename))
+ return;
+
+ graph_changed = false;
+
+ ifdebug(PROTOCOL) logger(LOG_NOTICE, "Dumping graph");
+
+ if(filename[0] == '|') {
+ file = popen(filename + 1, "w");
+ } else {
+ asprintf(&tmpname, "%s.new", filename);
+ file = fopen(tmpname, "w");
+ }
+
+ if(!file) {
+ logger(LOG_ERR, "Unable to open graph dump file %s: %s", filename, strerror(errno));
+ free(tmpname);
+ return;
+ }
+
+ fprintf(file, "digraph {\n");
+
+ /* dump all nodes first */
+ for(node = node_tree->head; node; node = node->next) {
+ n = node->data;
+ fprintf(file, " %s [label = \"%s\"];\n", n->name, n->name);
+ }
+
+ /* now dump all edges */
+ for(node = edge_weight_tree->head; node; node = node->next) {
+ e = node->data;
+ fprintf(file, " %s -> %s;\n", e->from->name, e->to->name);
+ }
+
+ fprintf(file, "}\n");
+
+ fclose(file);
+
+ if(filename[0] != '|') {
+ rename(tmpname, filename);
+ free(tmpname);
+ }
}
fd_set readset, writeset;
struct timeval tv;
int r, maxfd;
- time_t last_ping_check, last_config_check;
+ time_t last_ping_check, last_config_check, last_graph_dump;
event_t *event;
cp();
last_ping_check = now;
last_config_check = now;
+ last_graph_dump = now;
+
srand(now);
running = true;
try_outgoing_connections();
}
+
+ /* Dump graph if wanted every 60 seconds*/
+
+ if(last_graph_dump + 60 < now) {
+ dump_graph();
+ last_graph_dump = now;
+ }
}
return 0;