]>
jfr.im git - irc/quakenet/newserv.git/blob - trusts/trusts_slave.c
6 #include "../core/hooks.h"
7 #include "../core/config.h"
8 #include "../core/error.h"
9 #include "../control/control.h"
10 #include "../xsb/xsb.h"
11 #include "../lib/sha1.h"
12 #include "../lib/hmac.h"
13 #include "../lib/irc_string.h"
14 #include "../core/schedule.h"
15 #include "../server/server.h"
18 static int syncing
, synced
;
19 static sstring
*masterserver
;
21 static unsigned int curlineno
, totallines
;
24 void trusts_replication_createtables(void);
25 void trusts_replication_swap(void);
26 void trusts_replication_complete(int);
28 static void __abandonreplication(const char *fn
, int line
, char *error
, ...) {
30 char buf
[512], buf2
[600];
33 vsnprintf(buf
, sizeof(buf
), "%s", ap
);
36 snprintf(buf2
, sizeof(buf2
), "Error replicating (function: %s, line: %d): %s", fn
, line
, buf
);
38 Error("trusts_slave", ERR_ERROR
, "%s", buf2
);
45 #define abandonreplication(x, ...) __abandonreplication(__FUNCTION__, __LINE__, x , # __VA_ARGS__)
47 void trusts_replication_complete(int error
) {
49 abandonreplication("final replication stage: error %d", error
);
52 Error("trusts_slave", ERR_INFO
, "Replication complete!");
54 if(!trusts_loaddb()) {
55 abandonreplication("couldn't load database");
62 static char *extractline(char *buf
, int reset
, int update
, int final
) {
63 unsigned char n
= '\n';
65 unsigned int lineno
, id
;
66 static unsigned int curid
;
68 if(sscanf(buf
, "%u %u %n", &id
, &lineno
, &chars
) != 2) {
69 abandonreplication("bad number for sscanf result");
74 abandonreplication("bad number of characters");
78 if(reset
&& (lineno
!= 1)) {
79 abandonreplication("bad initial line number");
89 /* will happen if two are sent at once, but that's ok */
93 if(lineno
!= curlineno
) {
94 abandonreplication("unexpected line number");
95 Error("trusts_slave", ERR_ERROR
, "Didn't get expected line number (%u vs. %u).", lineno
, curlineno
);
98 if(lineno
> totallines
) {
99 abandonreplication("too many lines");
100 Error("trusts_slave", ERR_ERROR
, "Too many lines received!");
109 SHA1Update(&s
, (unsigned char *)buf
, strlen(buf
));
110 SHA1Update(&s
, &n
, 1);
117 /* trinit id lineno force totallines */
118 static int xsb_trinit(void *source
, int argc
, char **argv
) {
123 abandonreplication("bad number of args");
127 buf
= extractline(argv
[0], 1, 0, 1);
131 if((sscanf(buf
, "%u %u", &forced
, &totallines
) != 2)) {
132 abandonreplication("bad number for sscanf result");
137 abandonreplication("bad number of lines");
141 if(!forced
|| synced
)
144 if(!extractline(argv
[0], 1, 1, 0))
147 trusts_replication_createtables();
151 Error("trusts_slave", ERR_INFO
, "Replication in progress. . .");
155 /* trdata id lines type data */
156 static int xsb_trdata(void *source
, int argc
, char **argv
) {
163 abandonreplication("bad number of args");
167 buf
= extractline(argv
[0], 0, 1, 0);
171 if(buf
[0] && (buf
[1] == ' ')) {
174 if(!parsetg(&buf
[2], &tg
, 0)) {
175 abandonreplication("bad trustgroup line");
176 Error("trusts_slave", ERR_ERROR
, "Bad trustgroup line: %s", buf
);
179 trustsdb_inserttg("replication_groups", &tg
);
181 freesstring(tg
.name
);
182 freesstring(tg
.createdby
);
183 freesstring(tg
.contact
);
184 freesstring(tg
.comment
);
186 } else if(buf
[0] == 'H') {
190 if(!parseth(&buf
[2], &th
, &tgid
, 0)) {
191 abandonreplication("bad trusthost line");
192 Error("trusts_slave", ERR_ERROR
, "Bad trusthost line: %s", buf
);
195 trustsdb_insertth("replication_hosts", &th
, tgid
);
197 abandonreplication("bad trust type");
199 Error("trusts_slave", ERR_ERROR
, "Bad trust type: %c", buf
[0]);
203 abandonreplication("malformed line");
205 Error("trusts_slave", ERR_ERROR
, "Malformed data line: %s", buf
);
211 /* trfini id lines sha */
212 static int xsb_trfini(void *source
, int argc
, char **argv
) {
213 char *buf
, digestbuf
[SHA1_DIGESTSIZE
* 2 + 1];
214 unsigned char digest
[SHA1_DIGESTSIZE
];
220 abandonreplication("bad number of args");
224 buf
= extractline(argv
[0], 0, 1, 1);
228 if((totallines
+ 1) != curlineno
) {
229 abandonreplication("wrong number of lines received");
230 Error("trusts_slave", ERR_ERROR
, "Wrong number of lines received (%u vs. %u).", totallines
, curlineno
- 1);
234 SHA1Final(digest
, &s
);
235 if(strcasecmp(hmac_printhex(digest
, digestbuf
, SHA1_DIGESTSIZE
), buf
)) {
236 abandonreplication("digest mismatch");
237 Error("trusts_slave", ERR_ERROR
, "Digest mismatch.");
241 Error("trusts_slave", ERR_INFO
, "Data verification successful.");
243 trusts_replication_swap();
250 static int xsb_traddgroup(void *source
, int argc
, char **argv
) {
257 abandonreplication("bad number of arguments");
261 if(!parsetg(argv
[0], &tg
, 0)) {
262 abandonreplication("bad trustgroup line");
263 Error("trusts_slave", ERR_ERROR
, "Bad trustgroup line: %s", argv
[0]);
269 freesstring(tg
.name
);
270 freesstring(tg
.createdby
);
271 freesstring(tg
.contact
);
272 freesstring(tg
.comment
);
275 abandonreplication("unable to add trustgroup");
282 static int xsb_traddhost(void *source
, int argc
, char **argv
) {
290 abandonreplication("bad number of arguments");
294 if(!parseth(argv
[0], &th
, &tgid
, 0)) {
295 abandonreplication("bad trusthost line");
296 Error("trusts_slave", ERR_ERROR
, "Bad trusthost line: %s", argv
[0]);
300 th
.group
= tg_inttotg(tgid
);
302 abandonreplication("unable to lookup trustgroup");
307 abandonreplication("unable to add trusthost");
314 static int xsb_trdelhost(void *source
, int argc
, char **argv
) {
319 abandonreplication("bad number of arguments");
326 static int xsb_trdelgroup(void *source
, int argc
, char **argv
) {
331 abandonreplication("bad number of arguments");
338 static int trusts_cmdtrustresync(void *source
, int argc
, char **argv
) {
342 controlreply(np
, "Synchronisation is already in progress.");
347 xsb_broadcast("trrequestsync", NULL
, "%s", "");
348 controlreply(np
, "Synchronisation request sent.");
354 static void *syncsched
;
356 static void checksynced(void *arg
) {
357 if(!synced
|| !syncing
)
358 xsb_broadcast("trrequestsync", NULL
, "%s", "");
361 static void __serverlinked(int hooknum
, void *arg
) {
362 int servernum
= (int)(long)arg
;
364 if(!ircd_strcmp(serverlist
[servernum
].name
->content
, masterserver
->content
)) {
365 syncing
= synced
= 0;
366 xsb_broadcast("trrequestsync", NULL
, "%s", "");
373 m
= getconfigitem("trusts", "master");
374 if(m
&& (atoi(m
->content
) != 0)) {
375 Error("trusts_slave", ERR_ERROR
, "Not a slave server, not loaded.");
379 masterserver
= getcopyconfigitem("trusts", "masterserver", "", 255);
380 if(!masterserver
|| !masterserver
->content
|| !masterserver
->content
[0]) {
381 Error("trusts_slave", ERR_ERROR
, "No master server defined.");
382 freesstring(masterserver
);
388 registercontrolhelpcmd("trustresync", NO_DEVELOPER
, 0, trusts_cmdtrustresync
, "Usage: trustresync");
390 xsb_addcommand("trinit", 1, xsb_trinit
);
391 xsb_addcommand("trdata", 1, xsb_trdata
);
392 xsb_addcommand("trfini", 1, xsb_trfini
);
393 xsb_addcommand("traddhost", 1, xsb_traddhost
);
394 xsb_addcommand("traddgroup", 1, xsb_traddgroup
);
395 xsb_addcommand("trdelhost", 1, xsb_trdelhost
);
396 xsb_addcommand("trdelgroup", 1, xsb_trdelgroup
);
398 registerhook(HOOK_SERVER_LINKED
, __serverlinked
);
399 syncsched
= schedulerecurring(time(NULL
)+5, 0, 60, checksynced
, NULL
);
401 if(trusts_fullyonline())
402 xsb_broadcast("trrequestsync", NULL
, "%s", "");
409 freesstring(masterserver
);
411 deregistercontrolcmd("trustresync", trusts_cmdtrustresync
);
413 xsb_delcommand("trinit", xsb_trinit
);
414 xsb_delcommand("trdata", xsb_trdata
);
415 xsb_delcommand("trfini", xsb_trfini
);
416 xsb_delcommand("traddhost", xsb_traddhost
);
417 xsb_delcommand("traddgroup", xsb_traddgroup
);
418 xsb_delcommand("trdelhost", xsb_trdelhost
);
419 xsb_delcommand("trdelgroup", xsb_trdelgroup
);
421 deregisterhook(HOOK_SERVER_LINKED
, __serverlinked
);
423 deleteschedule(syncsched
, checksynced
, NULL
);