]> jfr.im git - irc/quakenet/newserv.git/blame - trusts/trusts_master.c
PROXYSCAN: gline for 12h now by default.
[irc/quakenet/newserv.git] / trusts / trusts_master.c
CommitLineData
82a316e7
CP
1#include <stdlib.h>
2#include <stdarg.h>
3#include <stdio.h>
4#include <string.h>
35449aa5 5#include "../core/hooks.h"
82a316e7
CP
6#include "../core/config.h"
7#include "../core/error.h"
8#include "../lib/sha1.h"
9#include "../lib/hmac.h"
10#include "../xsb/xsb.h"
11#include "../control/control.h"
35449aa5
CP
12#include "trusts.h"
13
82a316e7
CP
14static void broadcast(SHA1_CTX *c, unsigned int replicationid, unsigned int lineno, char *command, char *format, ...) {
15 char buf[512], buf2[600];
16 va_list va;
17 int len;
18
19 va_start(va, format);
20 vsnprintf(buf, sizeof(buf), format, va);
21 va_end(va);
22
23 len = snprintf(buf2, sizeof(buf2), "%u %u %s", replicationid, lineno, buf);
24 xsb_broadcast(command, NULL, "%s", buf2);
25
26 if(len > (sizeof(buf2) - 1))
27 len = sizeof(buf2) - 1;
28 if(len < 0)
29 len = 0;
30
31 buf2[len] = '\n';
32
33 SHA1Update(c, (unsigned char *)buf2, len + 1);
34}
35
36static void replicate(int forced) {
37 SHA1_CTX s;
38 unsigned int lineno, lines;
39 unsigned char digest[SHA1_DIGESTSIZE];
40 char digestbuf[SHA1_DIGESTSIZE*2+1];
41 static unsigned int replicationid = 0;
42 trustgroup *tg;
43 trusthost *th;
44
45 if(++replicationid > 10000)
46 replicationid = 1;
47
48 for(lines=2,tg=tglist;tg;tg=tg->next) {
49 lines++;
50 for(th=tg->hosts;th;th=th->next)
51 lines++;
52 }
53
54 SHA1Init(&s);
55 lineno = 1;
56 broadcast(&s, replicationid, lineno++, "trinit", "%d %u", forced, lines);
57
58 for(tg=tglist;tg;tg=tg->next) {
59 broadcast(&s, replicationid, lineno++, "trdata", "G %s", dumptg(tg, 0));
60
61 for(th=tg->hosts;th;th=th->next)
62 broadcast(&s, replicationid, lineno++, "trdata", "H %s", dumpth(th, 0));
63 }
64
65 SHA1Final(digest, &s);
66 xsb_broadcast("trfini", NULL, "%u %u %s", replicationid, lineno, hmac_printhex(digest, digestbuf, SHA1_DIGESTSIZE));
67}
68
69static int xsb_tr_requeststart(void *source, int argc, char **argv) {
70 static time_t last = 0;
71 time_t t = time(NULL);
72
73 if(t - last > 5) {
74 last = t;
75
76 replicate(0);
77 }
78
79 return CMD_OK;
80}
81
82static void groupadded(int hooknum, void *arg) {
83 trustgroup *tg = arg;
84
85 xsb_broadcast("traddgroup", NULL, "%s", dumptg(tg, 0));
86}
87
88static void groupremoved(int hooknum, void *arg) {
89 trustgroup *tg = arg;
90
91 xsb_broadcast("trdelgroup", NULL, "%u", tg->id);
92}
93
94static void hostadded(int hooknum, void *arg) {
95 trusthost *th = arg;
96
97 xsb_broadcast("traddhost", NULL, "%s", dumpth(th, 0));
98}
99
100static void hostremoved(int hooknum, void *arg) {
101 trusthost *th = arg;
102
103 xsb_broadcast("trdelhost", NULL, "%u", th->id);
104}
105
2ab0a1e7
CP
106static void groupmodified(int hooknum, void *arg) {
107 trustgroup *tg = arg;
108
109 xsb_broadcast("trmodifygroup", NULL, "%s", dumptg(tg, 0));
110}
111
82a316e7
CP
112static int trusts_cmdtrustforceresync(void *source, int argc, char **argv) {
113 nick *np = source;
114
115 controlreply(np, "Resync in progress. . .");
116 replicate(1);
117 controlreply(np, "Resync complete.");
118
119 return CMD_OK;
120}
121
122static int commandsregistered, loaded;
123static void __dbloaded(int hooknum, void *arg) {
35449aa5
CP
124 if(commandsregistered)
125 return;
82a316e7 126
35449aa5
CP
127 commandsregistered = 1;
128
82a316e7
CP
129 xsb_addcommand("trrequeststart", 0, xsb_tr_requeststart);
130
131 registerhook(HOOK_TRUSTS_ADDGROUP, groupadded);
132 registerhook(HOOK_TRUSTS_DELGROUP, groupremoved);
133 registerhook(HOOK_TRUSTS_ADDHOST, hostadded);
134 registerhook(HOOK_TRUSTS_DELGROUP, hostremoved);
2ab0a1e7 135 registerhook(HOOK_TRUSTS_MODIFYGROUP, groupmodified);
82a316e7
CP
136
137 /* we've just reloaded */
138 /* if we're not online, no problem, other nodes will ask us individually */
139 if(trusts_fullyonline())
140 replicate(1);
141
142 registercontrolhelpcmd("trustforceresync", NO_DEVELOPER, 0, trusts_cmdtrustforceresync, "Usage: trustforceresync");
35449aa5
CP
143}
144
82a316e7 145static void __dbclosed(int hooknum, void *arg) {
35449aa5
CP
146 if(!commandsregistered)
147 return;
148 commandsregistered = 0;
149
82a316e7
CP
150 xsb_delcommand("trrequeststart", xsb_tr_requeststart);
151
152 registerhook(HOOK_TRUSTS_ADDGROUP, groupadded);
153 registerhook(HOOK_TRUSTS_DELGROUP, groupremoved);
154 registerhook(HOOK_TRUSTS_ADDHOST, hostadded);
155 registerhook(HOOK_TRUSTS_DELGROUP, hostremoved);
2ab0a1e7 156 registerhook(HOOK_TRUSTS_MODIFYGROUP, groupmodified);
82a316e7
CP
157
158 deregistercontrolcmd("trustforceresync", trusts_cmdtrustforceresync);
35449aa5
CP
159}
160
161void _init(void) {
82a316e7
CP
162 sstring *m;
163
164 m = getconfigitem("trusts", "master");
165 if(!m || (atoi(m->content) != 1)) {
166 Error("trusts_master", ERR_ERROR, "Not a master server, not loaded.");
167 return;
168 }
35449aa5 169
82a316e7
CP
170 loaded = 1;
171
172 registerhook(HOOK_TRUSTS_DB_LOADED, __dbloaded);
173 registerhook(HOOK_TRUSTS_DB_CLOSED, __dbclosed);
174
175 if(trustsdbloaded) {
176 /* this will force a sync if we're online */
177 /* if we're not we'll be asked to sync when we come online */
178 __dbloaded(0, NULL);
179 } else {
180 if(!trusts_loaddb())
181 Error("trusts_master", ERR_ERROR, "Unable to load database.");
182
183 /* do nothing else, other servers will ask us when we come online */
184 /* also the __dbloaded hook will be triggered */
185 }
35449aa5
CP
186}
187
188void _fini(void) {
82a316e7
CP
189 if(!loaded)
190 return;
191
192 deregisterhook(HOOK_TRUSTS_DB_LOADED, __dbloaded);
193 deregisterhook(HOOK_TRUSTS_DB_CLOSED, __dbclosed);
194
195 trusts_closedb(0);
35449aa5 196
82a316e7 197 __dbclosed(0, NULL);
35449aa5 198}