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"
20 static const char *DEFAULT_SERVICE_MASKS
[] = { "services*.*.quakenet.org", (char *)0 };
22 static array defaultservicemasks_a
;
23 static sstring
**defaultservicemasks
;
25 static void handlemaskprivmsg(int, void *);
26 static void handlecontrolregistered(int, void *);
27 static CommandTree
*cmds
;
29 static char controlnum
[6];
32 struct messagequeue
*next
;
36 struct messagequeue
*head
, *tail
;
44 cmds
= newcommandtree();
48 registerhook(HOOK_NICK_MASKPRIVMSG
, &handlemaskprivmsg
);
49 registerhook(HOOK_CONTROL_REGISTERED
, &handlecontrolregistered
);
51 array_init(&defaultservicemasks_a
, sizeof(sstring
*));
53 for(p
=DEFAULT_SERVICE_MASKS
;*p
;p
++) {
54 int i
= array_getfreeslot(&defaultservicemasks_a
);
55 defaultservicemasks
= (sstring
**)defaultservicemasks_a
.content
;
57 defaultservicemasks
[i
] = getsstring(*p
, strlen(*p
));
60 servicemasks
= getconfigitems("xsb", "servicemask");
61 if(!servicemasks
|| !servicemasks
->cursi
)
62 Error("xsb", ERR_WARNING
, "No service masks in config file (xsb/servicemask), using defaults");
67 struct messagequeue
*q
, *nq
;
72 destroycommandtree(cmds
);
74 deregisterhook(HOOK_NICK_MASKPRIVMSG
, &handlemaskprivmsg
);
75 deregisterhook(HOOK_CONTROL_REGISTERED
, &handlecontrolregistered
);
77 for(i
=0;i
<defaultservicemasks_a
.cursi
;i
++)
78 freesstring(defaultservicemasks
[i
]);
79 array_free(&defaultservicemasks_a
);
90 void xsb_addcommand(const char *name
, const int maxparams
, CommandHandler handler
) {
91 addcommandtotree(cmds
, name
, 0, maxparams
, handler
);
94 void xsb_delcommand(const char *name
, CommandHandler handler
) {
95 deletecommandfromtree(cmds
, name
, handler
);
98 static void handlemaskprivmsg(int hooknum
, void *args
) {
99 void **hargs
= (void **)args
;
100 nick
*source
= hargs
[0];
101 char *message
= hargs
[2];
110 if(!IsOper(source
) || !IsService(source
))
113 cargc
= splitline(message
, cargv
, 50, 0);
117 if(strcmp(cargv
[0], "XSB1"))
120 s
= &serverlist
[homeserver(source
->numeric
)];
121 if(s
->linkstate
!= LS_LINKED
) {
122 Error("xsb", ERR_WARNING
, "Got XSB message from unlinked server (%s): %s", s
->name
->content
, source
->nick
);
127 if(!(s
->flags
& SMODE_SERVICE
)) {
128 Error("xsb", ERR_WARNING
, "Got XSB message from non-service server (%s): %s", s
->name
->content
, source
->nick
);
133 cmd
= findcommandintree(cmds
, cargv
[1], 1);
137 if(cmd
->maxparams
< (cargc
- 2)) {
138 rejoinline(cargv
[cmd
->maxparams
], cargc
- (cmd
->maxparams
));
139 cargc
= (cmd
->maxparams
) + 2;
142 (cmd
->handler
)(source
, cargc
- 2, &cargv
[2]);
145 static void directsend(char *buf
) {
146 irc_send("%s P %s", controlnum
, buf
);
149 static void handlecontrolregistered(int hooknum
, void *args
) {
150 nick
*np
= (nick
*)args
;
153 struct messagequeue
*q
, *nq
;
155 longtonumeric2(np
->numeric
, 5, controlnum
);
166 controlnum
[0] = '\0';
170 static int getservicemasks(sstring
***masks
) {
171 array
*aservicemasks
= getconfigitems("xsb", "servicemask");
172 if(!aservicemasks
|| !aservicemasks
->cursi
)
173 aservicemasks
= &defaultservicemasks_a
;
175 *masks
= (sstring
**)aservicemasks
->content
;
177 return aservicemasks
->cursi
;
180 static void xsb_send(const char *format
, ...) {
185 va_start(va
, format
);
186 len
= vsnprintf(buf
, sizeof(buf
), format
, va
);
188 if(len
>= sizeof(buf
))
194 struct messagequeue
*q
= (struct messagequeue
*)malloc(sizeof(struct messagequeue
) + len
);
196 strlcpy(q
->buf
, buf
, len
+ 1);
207 void xsb_broadcast(const char *command
, server
*service
, const char *format
, ...) {
210 sstring
**servicemasks
;
213 va_start(va
, format
);
214 vsnprintf(buf
, sizeof(buf
), format
, va
);
218 xsb_send("$%s :XSB1 %s %s", service
->name
->content
, command
, buf
);
222 for(i
=getservicemasks(&servicemasks
)-1;i
>=0;i
--)
223 xsb_send("$%s :XSB1 %s %s", servicemasks
[i
]->content
, command
, buf
);
226 void xsb_unicast(const char *command
, nick
*np
, const char *format
, ...) {
230 va_start(va
, format
);
231 vsnprintf(buf
, sizeof(buf
), format
, va
);
235 xsb_send("$%s :XSB1 %s %s", serverlist
[homeserver(np
->numeric
)].name
, command
, buf
);
236 /* xsb_send("%s :XSB1 %s %s", longtonumeric(np->numeric, 5), command, buf);*/
240 int xsb_isservice(server
*service
) {
242 sstring
**servicemasks
;
243 char *name
= service
->name
->content
;
245 if(!(service
->flags
& SMODE_SERVICE
))
248 for(i
=getservicemasks(&servicemasks
)-1;i
>=0;i
--)
249 if(match2strings(servicemasks
[i
]->content
, name
))