1 /* TODO: catch control messages */
6 #include "../core/hooks.h"
7 #include "../lib/splitline.h"
8 #include "../core/config.h"
9 #include "../irc/irc.h"
10 #include "../lib/array.h"
11 #include "../lib/base64.h"
12 #include "../lib/irc_string.h"
13 #include "../core/error.h"
14 #include "../localuser/localuser.h"
15 #include "../lib/strlfunc.h"
18 static const char *DEFAULT_SERVICE_MASKS
[] = { "services*.*.quakenet.org", (char *)0 };
20 static array defaultservicemasks_a
;
21 static sstring
**defaultservicemasks
;
23 static void handlemaskprivmsg(int, void *);
24 static void handlecontrolregistered(int, void *);
25 static CommandTree
*cmds
;
27 static char controlnum
[6];
30 struct messagequeue
*next
;
34 struct messagequeue
*head
, *tail
;
42 cmds
= newcommandtree();
46 registerhook(HOOK_NICK_MASKPRIVMSG
, &handlemaskprivmsg
);
47 registerhook(HOOK_CONTROL_REGISTERED
, &handlecontrolregistered
);
49 array_init(&defaultservicemasks_a
, sizeof(sstring
*));
51 for(p
=DEFAULT_SERVICE_MASKS
;*p
;p
++) {
52 int i
= array_getfreeslot(&defaultservicemasks_a
);
53 defaultservicemasks
= (sstring
**)defaultservicemasks_a
.content
;
55 defaultservicemasks
[i
] = getsstring(*p
, strlen(*p
));
58 servicemasks
= getconfigitems("xsb", "servicemask");
59 if(!servicemasks
|| !servicemasks
->cursi
)
60 Error("xsb", ERR_WARNING
, "No service masks in config file (xsb/servicemask), using defaults.");
65 struct messagequeue
*q
, *nq
;
70 destroycommandtree(cmds
);
72 deregisterhook(HOOK_NICK_MASKPRIVMSG
, &handlemaskprivmsg
);
73 deregisterhook(HOOK_CONTROL_REGISTERED
, &handlecontrolregistered
);
75 for(i
=0;i
<defaultservicemasks_a
.cursi
;i
++)
76 freesstring(defaultservicemasks
[i
]);
77 array_free(&defaultservicemasks_a
);
88 void xsb_addcommand(const char *name
, const int maxparams
, CommandHandler handler
) {
89 addcommandtotree(cmds
, name
, 0, maxparams
, handler
);
92 void xsb_delcommand(const char *name
, CommandHandler handler
) {
93 deletecommandfromtree(cmds
, name
, handler
);
96 static void handlemaskprivmsg(int hooknum
, void *args
) {
97 void **hargs
= (void **)args
;
98 nick
*source
= hargs
[0];
99 char *message
= hargs
[2];
108 if(!IsOper(source
) || !IsService(source
))
111 cargc
= splitline(message
, cargv
, 50, 0);
115 if(strcmp(cargv
[0], "XSB1"))
118 s
= &serverlist
[homeserver(source
->numeric
)];
119 if(s
->linkstate
!= LS_LINKED
) {
120 Error("xsb", ERR_WARNING
, "Got XSB message from unlinked server (%s): %s", s
->name
->content
, source
->nick
);
125 if(!(s
->flags
& SMODE_SERVICE
)) {
126 Error("xsb", ERR_WARNING
, "Got XSB message from non-service server (%s): %s", s
->name
->content
, source
->nick
);
131 cmd
= findcommandintree(cmds
, cargv
[1], 1);
135 if(cmd
->maxparams
< (cargc
- 2)) {
136 rejoinline(cargv
[cmd
->maxparams
], cargc
- (cmd
->maxparams
));
137 cargc
= (cmd
->maxparams
) + 2;
140 (cmd
->handler
)(source
, cargc
- 2, &cargv
[2]);
143 static void directsend(char *buf
) {
144 irc_send("%s P %s", controlnum
, buf
);
147 static void handlecontrolregistered(int hooknum
, void *args
) {
148 nick
*np
= (nick
*)args
;
151 struct messagequeue
*q
, *nq
;
153 longtonumeric2(np
->numeric
, 5, controlnum
);
164 controlnum
[0] = '\0';
168 static int getservicemasks(sstring
***masks
) {
169 array
*aservicemasks
= getconfigitems("xsb", "servicemask");
170 if(!aservicemasks
|| !aservicemasks
->cursi
)
171 aservicemasks
= &defaultservicemasks_a
;
173 *masks
= (sstring
**)aservicemasks
->content
;
175 return aservicemasks
->cursi
;
178 static void xsb_send(const char *format
, ...) {
183 va_start(va
, format
);
184 len
= vsnprintf(buf
, sizeof(buf
), format
, va
);
186 if(len
>= sizeof(buf
))
192 struct messagequeue
*q
= (struct messagequeue
*)malloc(sizeof(struct messagequeue
) + len
+ 5);
194 strlcpy(q
->buf
, buf
, len
+ 2);
205 void xsb_broadcast(const char *command
, server
*service
, const char *format
, ...) {
208 sstring
**servicemasks
;
211 va_start(va
, format
);
212 vsnprintf(buf
, sizeof(buf
), format
, va
);
216 xsb_send("$%s :XSB1 %s %s", service
->name
->content
, command
, buf
);
220 for(i
=getservicemasks(&servicemasks
)-1;i
>=0;i
--)
221 xsb_send("$%s :XSB1 %s %s", servicemasks
[i
]->content
, command
, buf
);
224 void xsb_unicast(const char *command
, nick
*np
, const char *format
, ...) {
228 va_start(va
, format
);
229 vsnprintf(buf
, sizeof(buf
), format
, va
);
233 xsb_send("$%s :XSB1 %s %s", serverlist
[homeserver(np
->numeric
)].name
, command
, buf
);
234 /* xsb_send("%s :XSB1 %s %s", longtonumeric(np->numeric, 5), command, buf);*/
238 int xsb_isservice(server
*service
) {
240 sstring
**servicemasks
;
241 char *name
= service
->name
->content
;
243 if(!(service
->flags
& SMODE_SERVICE
))
246 for(i
=getservicemasks(&servicemasks
)-1;i
>=0;i
--)
247 if(match2strings(servicemasks
[i
]->content
, name
))