5 #include "../core/hooks.h"
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"
14 static void broadcast(SHA1_CTX
*c
, unsigned int replicationid
, unsigned int lineno
, char *command
, char *format
, ...) {
15 char buf
[512], buf2
[600];
20 vsnprintf(buf
, sizeof(buf
), format
, va
);
23 len
= snprintf(buf2
, sizeof(buf2
), "%u %u %s", replicationid
, lineno
, buf
);
24 xsb_broadcast(command
, NULL
, "%s", buf2
);
26 if(len
> (sizeof(buf2
) - 1))
27 len
= sizeof(buf2
) - 1;
33 SHA1Update(c
, (unsigned char *)buf2
, len
+ 1);
36 static void replicate(int forced
) {
38 unsigned int lineno
, lines
;
39 unsigned char digest
[SHA1_DIGESTSIZE
];
40 char digestbuf
[SHA1_DIGESTSIZE
*2+1];
41 static unsigned int replicationid
= 0;
45 if(++replicationid
> 10000)
48 for(lines
=2,tg
=tglist
;tg
;tg
=tg
->next
) {
50 for(th
=tg
->hosts
;th
;th
=th
->next
)
56 broadcast(&s
, replicationid
, lineno
++, "trinit", "%d %u", forced
, lines
);
58 for(tg
=tglist
;tg
;tg
=tg
->next
) {
59 broadcast(&s
, replicationid
, lineno
++, "trdata", "G %s", dumptg(tg
, 0));
61 for(th
=tg
->hosts
;th
;th
=th
->next
)
62 broadcast(&s
, replicationid
, lineno
++, "trdata", "H %s", dumpth(th
, 0));
65 SHA1Final(digest
, &s
);
66 xsb_broadcast("trfini", NULL
, "%u %u %s", replicationid
, lineno
, hmac_printhex(digest
, digestbuf
, SHA1_DIGESTSIZE
));
69 static int xsb_tr_requeststart(void *source
, int argc
, char **argv
) {
70 static time_t last
= 0;
71 time_t t
= time(NULL
);
82 static void groupadded(int hooknum
, void *arg
) {
85 xsb_broadcast("traddgroup", NULL
, "%s", dumptg(tg
, 0));
88 static void groupremoved(int hooknum
, void *arg
) {
91 xsb_broadcast("trdelgroup", NULL
, "%u", tg
->id
);
94 static void hostadded(int hooknum
, void *arg
) {
97 xsb_broadcast("traddhost", NULL
, "%s", dumpth(th
, 0));
100 static void hostremoved(int hooknum
, void *arg
) {
103 xsb_broadcast("trdelhost", NULL
, "%u", th
->id
);
106 static int trusts_cmdtrustforceresync(void *source
, int argc
, char **argv
) {
109 controlreply(np
, "Resync in progress. . .");
111 controlreply(np
, "Resync complete.");
116 static int commandsregistered
, loaded
;
117 static void __dbloaded(int hooknum
, void *arg
) {
118 if(commandsregistered
)
121 commandsregistered
= 1;
123 xsb_addcommand("trrequeststart", 0, xsb_tr_requeststart
);
125 registerhook(HOOK_TRUSTS_ADDGROUP
, groupadded
);
126 registerhook(HOOK_TRUSTS_DELGROUP
, groupremoved
);
127 registerhook(HOOK_TRUSTS_ADDHOST
, hostadded
);
128 registerhook(HOOK_TRUSTS_DELGROUP
, hostremoved
);
130 /* we've just reloaded */
131 /* if we're not online, no problem, other nodes will ask us individually */
132 if(trusts_fullyonline())
135 registercontrolhelpcmd("trustforceresync", NO_DEVELOPER
, 0, trusts_cmdtrustforceresync
, "Usage: trustforceresync");
138 static void __dbclosed(int hooknum
, void *arg
) {
139 if(!commandsregistered
)
141 commandsregistered
= 0;
143 xsb_delcommand("trrequeststart", xsb_tr_requeststart
);
145 registerhook(HOOK_TRUSTS_ADDGROUP
, groupadded
);
146 registerhook(HOOK_TRUSTS_DELGROUP
, groupremoved
);
147 registerhook(HOOK_TRUSTS_ADDHOST
, hostadded
);
148 registerhook(HOOK_TRUSTS_DELGROUP
, hostremoved
);
150 deregistercontrolcmd("trustforceresync", trusts_cmdtrustforceresync
);
156 m
= getconfigitem("trusts", "master");
157 if(!m
|| (atoi(m
->content
) != 1)) {
158 Error("trusts_master", ERR_ERROR
, "Not a master server, not loaded.");
164 registerhook(HOOK_TRUSTS_DB_LOADED
, __dbloaded
);
165 registerhook(HOOK_TRUSTS_DB_CLOSED
, __dbclosed
);
168 /* this will force a sync if we're online */
169 /* if we're not we'll be asked to sync when we come online */
173 Error("trusts_master", ERR_ERROR
, "Unable to load database.");
175 /* do nothing else, other servers will ask us when we come online */
176 /* also the __dbloaded hook will be triggered */
184 deregisterhook(HOOK_TRUSTS_DB_LOADED
, __dbloaded
);
185 deregisterhook(HOOK_TRUSTS_DB_CLOSED
, __dbclosed
);