ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/modules/contrib/graphtastical.C
Revision: 1.7
Committed: Sat Sep 22 14:27:27 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +3 -3 lines
Log Message:
split up ermyth into ermyth-modules, libermyth (currently just ermyth-util) and ermyth-core

File Contents

# Content
1 /**
2 * graphtastical.C: Create a .dot file from Ermyth's database.
3 *
4 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
5 * Rights to this code are as documented in COPYING.
6 *
7 * Creates a .dot file for use with neato which displays
8 * user->channel relationships.
9 *
10 * == How to generate the graphs and How It Works ==
11 * Graphtastical creates a .dot file for graphviz's neato
12 * filter to use. The DOT language describes a graph's
13 * structure to graphviz in an opaque way.
14 *
15 * Because Graphviz nodes use unique identifiers for
16 * interconnection, the channels.dot file contains also
17 * information about social networks.
18 *
19 * Eventually Graphtastical will dump other graph datafiles
20 * too.
21 *
22 * To make a file from the data dumped by Graphtastical,
23 * the following commands will do:
24 *
25 * $ cat channels.dot | neato -Tgif -o map-channels.gif
26 * $ cat channels.dot | neato -Tsvg -o map-channels.svg
27 *
28 * Some maps (for larger networks) are going to be large,
29 * so you may want to provide links to both the GIF and
30 * SVG files as some people may only be able to make use of
31 * one or the other. Why that is, I'm not sure, and I'm not
32 * covering it here.
33 *
34 * == Privacy concerns ==
35 * If you are running Graphtastical on a network that has
36 * privacy concerns; you probably shouldn't.
37 *
38 *
39 * Portions of this file were derived from sources bearing the following license:
40 * Copyright © 2007 William Pitcock
41 * Rights to this code are as documented in doc/pod/license.pod.
42 *
43 * $Id: graphtastical.C,v 1.6 2007-09-16 18:54:43 pippijn Exp $
44 */
45
46 #include <boost/foreach.hpp>
47
48 #include "atheme.h"
49 #include <ermyth/module.h>
50 #include <account/chanacs.h>
51 #include <account/mychan.h>
52 #include <account/myuser.h>
53 #include <account/kline.h>
54 #include <account/svsignore.h>
55
56 static char const rcsid[] = "$Id: graphtastical.C,v 1.6 2007-09-16 18:54:43 pippijn Exp $";
57
58 REGISTER_MODULE ("contrib/graphtastical", true, "The Ermyth Team <http://ermyth.xinutec.org>");
59
60 /* write channels.dot */
61 static void
62 write_channels_dot_file (void *arg)
63 {
64 // myuser_t *mu;
65 mychan_t *mc;
66 chanacs_t *ca;
67 // kline_t *k;
68 // svsignore_t *svsignore;
69 // soper_t *soper;
70 node_t *n;//, *tn, *tn2;
71 FILE *f;
72 int errno1, was_errored = 0;
73 int root = 1;
74 mychan_t *pmc;
75
76 errno = 0;
77
78 /* write to a temporary file first */
79 if (!(f = fopen (DATADIR "/channels.dot.new", "w")))
80 {
81 errno1 = errno;
82 slog (LG_ERROR, "graphtastical: cannot create channels.dot.new: %s", strerror (errno1));
83 return;
84 }
85
86 fprintf (f, "graph channels {\n");
87 fprintf (f, "edge [color=blue len=7.5 fontsize=10]\n");
88 fprintf (f, "node [fontsize=10]\n");
89
90 slog (LG_DEBUG, "graphtastical: dumping mychans");
91
92 foreach (mychan_t::pair_type &mp, mychan_t::map)
93 {
94 mc = mp.second;
95 fprintf (f, "\"%s\"", mc->name);
96
97 if (!root)
98 fprintf (f, "-- \"%s\"", pmc->name);
99
100 pmc = mc;
101
102 fprintf (f, "[fontsize=10]\n");
103
104 LIST_FOREACH (n, mc->chanacs.head)
105 {
106 ca = (chanacs_t *) n->data;
107
108 if (ca->level & CA_AKICK)
109 continue;
110
111 fprintf (f, "\"%s\" -- \"%s\" [fontsize=10]\n", ca->myuser ? ca->myuser->name : ca->host, mc->name);
112 }
113 }
114
115 fprintf (f, "}\n");
116
117 was_errored = ferror (f);
118 was_errored |= fclose (f);
119 if (was_errored)
120 {
121 errno1 = errno;
122 slog (LG_ERROR, "graphtastical: cannot write to channels.dot.new: %s", strerror (errno1));
123 return;
124 }
125
126 /* now, replace the old database with the new one, using an atomic rename */
127 unlink (DATADIR "/channels.dot");
128
129 if ((rename (DATADIR "/channels.dot.new", DATADIR "/channels.dot")) < 0)
130 {
131 errno1 = errno;
132 slog (LG_ERROR, "graphtastical: cannot rename channels.dot.new to channels.dot: %s", strerror (errno1));
133 return;
134 }
135 }
136
137 bool
138 _modinit (module *m)
139 {
140 write_channels_dot_file (NULL);
141
142 event_add ("write_channels_dot_file", write_channels_dot_file, NULL, 60);
143
144 return true;
145 }
146
147 void
148 _moddeinit (void)
149 {
150 event_delete (write_channels_dot_file, NULL);
151 }
152
153 /* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs
154 * vim:ts=8
155 * vim:sw=8
156 * vim:noexpandtab
157 */