5 #include "../core/hooks.h"
6 #include "../core/config.h"
7 #include "../core/error.h"
8 #include "../lib/version.h"
9 #include "../lib/sha1.h"
10 #include "../lib/hmac.h"
11 #include "../xsb/xsb.h"
12 #include "../control/control.h"
17 static void broadcast(SHA1_CTX
*c
, unsigned int replicationid
, unsigned int lineno
, char *command
, char *format
, ...) {
18 char buf
[512], buf2
[600];
23 vsnprintf(buf
, sizeof(buf
), format
, va
);
26 len
= snprintf(buf2
, sizeof(buf2
), "%u %u %s", replicationid
, lineno
, buf
);
27 xsb_broadcast(command
, NULL
, "%s", buf2
);
29 if(len
> (sizeof(buf2
) - 1))
30 len
= sizeof(buf2
) - 1;
36 SHA1Update(c
, (unsigned char *)buf2
, len
+ 1);
39 static void replicate(int forced
) {
41 unsigned int lineno
, lines
;
42 unsigned char digest
[SHA1_DIGESTSIZE
];
43 char digestbuf
[SHA1_DIGESTSIZE
*2+1];
44 static unsigned int replicationid
= 0;
48 if(++replicationid
> 10000)
51 for(lines
=2,tg
=tglist
;tg
;tg
=tg
->next
) {
53 for(th
=tg
->hosts
;th
;th
=th
->next
)
59 broadcast(&s
, replicationid
, lineno
++, "trinit", "%d %u", forced
, lines
);
61 for(tg
=tglist
;tg
;tg
=tg
->next
) {
62 broadcast(&s
, replicationid
, lineno
++, "trdata", "G %s", dumptg(tg
, 0));
64 for(th
=tg
->hosts
;th
;th
=th
->next
)
65 broadcast(&s
, replicationid
, lineno
++, "trdata", "H %s", dumpth(th
, 0));
68 SHA1Final(digest
, &s
);
69 xsb_broadcast("trfini", NULL
, "%u %u %s", replicationid
, lineno
, hmac_printhex(digest
, digestbuf
, SHA1_DIGESTSIZE
));
72 static int xsb_tr_requeststart(void *source
, int argc
, char **argv
) {
73 static time_t last
= 0;
74 time_t t
= time(NULL
);
85 static void groupadded(int hooknum
, void *arg
) {
88 xsb_broadcast("traddgroup", NULL
, "%s", dumptg(tg
, 0));
91 static void groupremoved(int hooknum
, void *arg
) {
94 xsb_broadcast("trdelgroup", NULL
, "%u", tg
->id
);
97 static void hostadded(int hooknum
, void *arg
) {
100 xsb_broadcast("traddhost", NULL
, "%s", dumpth(th
, 0));
103 static void hostremoved(int hooknum
, void *arg
) {
106 xsb_broadcast("trdelhost", NULL
, "%u", th
->id
);
109 static void groupmodified(int hooknum
, void *arg
) {
110 trustgroup
*tg
= arg
;
112 xsb_broadcast("trmodifygroup", NULL
, "%s", dumptg(tg
, 0));
115 static void hostmodified(int hooknum
, void *arg
) {
118 xsb_broadcast("trmodifyhost", NULL
, "%s", dumpth(th
, 0));
121 static int trusts_cmdtrustforceresync(void *source
, int argc
, char **argv
) {
124 controlreply(np
, "Resync in progress. . .");
126 controlreply(np
, "Resync complete.");
131 static int commandsregistered
, loaded
;
132 static void __dbloaded(int hooknum
, void *arg
) {
133 if(commandsregistered
)
136 commandsregistered
= 1;
138 xsb_addcommand("trrequeststart", 0, xsb_tr_requeststart
);
140 registerhook(HOOK_TRUSTS_ADDGROUP
, groupadded
);
141 registerhook(HOOK_TRUSTS_DELGROUP
, groupremoved
);
142 registerhook(HOOK_TRUSTS_ADDHOST
, hostadded
);
143 registerhook(HOOK_TRUSTS_DELHOST
, hostremoved
);
144 registerhook(HOOK_TRUSTS_MODIFYGROUP
, groupmodified
);
145 registerhook(HOOK_TRUSTS_MODIFYHOST
, hostmodified
);
147 /* we've just reloaded */
148 /* if we're not online, no problem, other nodes will ask us individually */
149 if(trusts_fullyonline())
152 registercontrolhelpcmd("trustforceresync", NO_DEVELOPER
, 0, trusts_cmdtrustforceresync
, "Usage: trustforceresync");
155 static void __dbclosed(int hooknum
, void *arg
) {
156 if(!commandsregistered
)
158 commandsregistered
= 0;
160 xsb_delcommand("trrequeststart", xsb_tr_requeststart
);
162 registerhook(HOOK_TRUSTS_ADDGROUP
, groupadded
);
163 registerhook(HOOK_TRUSTS_DELGROUP
, groupremoved
);
164 registerhook(HOOK_TRUSTS_ADDHOST
, hostadded
);
165 registerhook(HOOK_TRUSTS_DELGROUP
, hostremoved
);
166 registerhook(HOOK_TRUSTS_MODIFYGROUP
, groupmodified
);
167 registerhook(HOOK_TRUSTS_MODIFYHOST
, hostmodified
);
169 deregistercontrolcmd("trustforceresync", trusts_cmdtrustforceresync
);
175 m
= getconfigitem("trusts", "master");
176 if(!m
|| (atoi(m
->content
) != 1)) {
177 Error("trusts_master", ERR_ERROR
, "Not a master server, not loaded.");
183 registerhook(HOOK_TRUSTS_DB_LOADED
, __dbloaded
);
184 registerhook(HOOK_TRUSTS_DB_CLOSED
, __dbclosed
);
187 /* this will force a sync if we're online */
188 /* if we're not we'll be asked to sync when we come online */
192 Error("trusts_master", ERR_ERROR
, "Unable to load database.");
194 /* do nothing else, other servers will ask us when we come online */
195 /* also the __dbloaded hook will be triggered */
203 deregisterhook(HOOK_TRUSTS_DB_LOADED
, __dbloaded
);
204 deregisterhook(HOOK_TRUSTS_DB_CLOSED
, __dbclosed
);