ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/modules/contrib/graphtastical.C
Revision: 1.7
Committed: Sat Sep 22 14:27:27 2007 UTC (19 years, 1 month 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

# User Rev Content
1 pippijn 1.6 /**
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 pippijn 1.1 *
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 pippijn 1.6 *
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 pippijn 1.7 * $Id: graphtastical.C,v 1.6 2007-09-16 18:54:43 pippijn Exp $
44 pippijn 1.1 */
45    
46 pippijn 1.4 #include <boost/foreach.hpp>
47    
48 pippijn 1.1 #include "atheme.h"
49 pippijn 1.3 #include <ermyth/module.h>
50 pippijn 1.1 #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 pippijn 1.7 static char const rcsid[] = "$Id: graphtastical.C,v 1.6 2007-09-16 18:54:43 pippijn Exp $";
57 pippijn 1.3
58 pippijn 1.7 REGISTER_MODULE ("contrib/graphtastical", true, "The Ermyth Team <http://ermyth.xinutec.org>");
59 pippijn 1.1
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 pippijn 1.5 foreach (mychan_t::pair_type &mp, mychan_t::map)
93 pippijn 1.1 {
94 pippijn 1.4 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 pippijn 1.1 }
114 pippijn 1.4
115 pippijn 1.1 fprintf (f, "}\n");
116 pippijn 1.4
117 pippijn 1.1 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 pippijn 1.4
126 pippijn 1.1 /* 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 pippijn 1.3 bool
138     _modinit (module *m)
139 pippijn 1.1 {
140     write_channels_dot_file (NULL);
141    
142     event_add ("write_channels_dot_file", write_channels_dot_file, NULL, 60);
143 pippijn 1.3
144     return true;
145 pippijn 1.1 }
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     */