]> jfr.im git - irc/quakenet/newserv.git/blame - xsb/xsb-postircd.c
LUA: add function for channel chanop notice
[irc/quakenet/newserv.git] / xsb / xsb-postircd.c
CommitLineData
4c551b15
CP
1/* TODO: catch control messages */
2
2172bfc8
CP
3#include <string.h>
4#include <stdio.h>
5#include <stdarg.h>
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"
4c551b15 12#include "../lib/irc_string.h"
2172bfc8 13#include "../core/error.h"
4c551b15
CP
14#include "../localuser/localuser.h"
15#include "../lib/strlfunc.h"
7f32dbdf 16#include "../lib/version.h"
2172bfc8
CP
17#include "xsb.h"
18
7f32dbdf
P
19MODULE_VERSION("");
20
2172bfc8 21static const char *DEFAULT_SERVICE_MASKS[] = { "services*.*.quakenet.org", (char *)0 };
4c551b15 22
2172bfc8
CP
23static array defaultservicemasks_a;
24static sstring **defaultservicemasks;
25
26static void handlemaskprivmsg(int, void *);
4c551b15 27static void handlecontrolregistered(int, void *);
2172bfc8
CP
28static CommandTree *cmds;
29
4c551b15
CP
30static char controlnum[6];
31
32struct messagequeue {
33 struct messagequeue *next;
34 char buf[];
35};
36
37struct messagequeue *head, *tail;
2172bfc8
CP
38
39void _init(void) {
40 const char **p;
41 array *servicemasks;
42
4c551b15
CP
43 controlnum[0] = '\0';
44
2172bfc8 45 cmds = newcommandtree();
4c551b15
CP
46 if(!cmds)
47 return;
48
49 registerhook(HOOK_NICK_MASKPRIVMSG, &handlemaskprivmsg);
50 registerhook(HOOK_CONTROL_REGISTERED, &handlecontrolregistered);
51
2172bfc8
CP
52 array_init(&defaultservicemasks_a, sizeof(sstring *));
53
54 for(p=DEFAULT_SERVICE_MASKS;*p;p++) {
55 int i = array_getfreeslot(&defaultservicemasks_a);
56 defaultservicemasks = (sstring **)defaultservicemasks_a.content;
57
58 defaultservicemasks[i] = getsstring(*p, strlen(*p));
59 }
60
61 servicemasks = getconfigitems("xsb", "servicemask");
62 if(!servicemasks || !servicemasks->cursi)
5b5aa98c 63 Error("xsb", ERR_WARNING, "No service masks in config file (xsb/servicemask), using defaults.");
2172bfc8
CP
64}
65
66void _fini(void) {
67 int i;
4c551b15
CP
68 struct messagequeue *q, *nq;
69
70 if(!cmds)
71 return;
72
73 destroycommandtree(cmds);
74
75 deregisterhook(HOOK_NICK_MASKPRIVMSG, &handlemaskprivmsg);
76 deregisterhook(HOOK_CONTROL_REGISTERED, &handlecontrolregistered);
2172bfc8
CP
77
78 for(i=0;i<defaultservicemasks_a.cursi;i++)
79 freesstring(defaultservicemasks[i]);
80 array_free(&defaultservicemasks_a);
81
4c551b15
CP
82 for(q=head;q;q=nq) {
83 nq = q->next;
84 free(q);
85 }
86
87 head = NULL;
88 tail = NULL;
89}
2172bfc8 90
4c551b15
CP
91void xsb_addcommand(const char *name, const int maxparams, CommandHandler handler) {
92 addcommandtotree(cmds, name, 0, maxparams, handler);
93}
2172bfc8 94
4c551b15
CP
95void xsb_delcommand(const char *name, CommandHandler handler) {
96 deletecommandfromtree(cmds, name, handler);
2172bfc8
CP
97}
98
99static void handlemaskprivmsg(int hooknum, void *args) {
100 void **hargs = (void **)args;
101 nick *source = hargs[0];
102 char *message = hargs[2];
103 Command *cmd;
104 int cargc;
105 char *cargv[50];
106 server *s;
107
108 if(!source)
109 return;
110
111 if(!IsOper(source) || !IsService(source))
112 return;
113
114 cargc = splitline(message, cargv, 50, 0);
115 if(cargc < 2)
116 return;
117
118 if(strcmp(cargv[0], "XSB1"))
119 return;
120
121 s = &serverlist[homeserver(source->numeric)];
122 if(s->linkstate != LS_LINKED) {
123 Error("xsb", ERR_WARNING, "Got XSB message from unlinked server (%s): %s", s->name->content, source->nick);
124 return;
125 }
126
4c551b15 127#ifndef XSB_DEBUG
2172bfc8
CP
128 if(!(s->flags & SMODE_SERVICE)) {
129 Error("xsb", ERR_WARNING, "Got XSB message from non-service server (%s): %s", s->name->content, source->nick);
130 return;
131 }
132#endif
133
134 cmd = findcommandintree(cmds, cargv[1], 1);
135 if(!cmd)
136 return;
137
138 if(cmd->maxparams < (cargc - 2)) {
139 rejoinline(cargv[cmd->maxparams], cargc - (cmd->maxparams));
140 cargc = (cmd->maxparams) + 2;
141 }
142
143 (cmd->handler)(source, cargc - 2, &cargv[2]);
144}
145
4c551b15
CP
146static void directsend(char *buf) {
147 irc_send("%s P %s", controlnum, buf);
2172bfc8
CP
148}
149
4c551b15
CP
150static void handlecontrolregistered(int hooknum, void *args) {
151 nick *np = (nick *)args;
152
153 if(np) {
154 struct messagequeue *q, *nq;
155
156 longtonumeric2(np->numeric, 5, controlnum);
157
158 for(q=head;q;q=nq) {
159 nq = q->next;
160
161 directsend(q->buf);
162 free(q);
163 }
164 head = NULL;
165 tail = NULL;
166 } else {
167 controlnum[0] = '\0';
168 }
2172bfc8
CP
169}
170
4c551b15
CP
171static int getservicemasks(sstring ***masks) {
172 array *aservicemasks = getconfigitems("xsb", "servicemask");
173 if(!aservicemasks || !aservicemasks->cursi)
174 aservicemasks = &defaultservicemasks_a;
175
176 *masks = (sstring **)aservicemasks->content;
177
178 return aservicemasks->cursi;
179}
180
181static void xsb_send(const char *format, ...) {
182 char buf[512];
183 va_list va;
184 size_t len;
185
186 va_start(va, format);
187 len = vsnprintf(buf, sizeof(buf), format, va);
188 va_end(va);
189 if(len >= sizeof(buf))
190 len = sizeof(buf);
191
192 if(controlnum[0]) {
193 directsend(buf);
194 } else {
5b5aa98c 195 struct messagequeue *q = (struct messagequeue *)malloc(sizeof(struct messagequeue) + len + 5);
4c551b15 196
5b5aa98c 197 strlcpy(q->buf, buf, len + 2);
4c551b15
CP
198 q->next = NULL;
199 if(tail) {
200 tail->next = q;
201 } else {
202 head = q;
203 }
204 tail = q;
205 }
206}
207
208void xsb_broadcast(const char *command, server *service, const char *format, ...) {
2172bfc8
CP
209 char buf[512];
210 va_list va;
211 sstring **servicemasks;
2172bfc8 212 int i;
2172bfc8
CP
213
214 va_start(va, format);
215 vsnprintf(buf, sizeof(buf), format, va);
216 va_end(va);
217
4c551b15
CP
218 if(service) {
219 xsb_send("$%s :XSB1 %s %s", service->name->content, command, buf);
220 return;
221 }
2172bfc8 222
4c551b15
CP
223 for(i=getservicemasks(&servicemasks)-1;i>=0;i--)
224 xsb_send("$%s :XSB1 %s %s", servicemasks[i]->content, command, buf);
225}
2172bfc8 226
4c551b15
CP
227void xsb_unicast(const char *command, nick *np, const char *format, ...) {
228 char buf[512];
229 va_list va;
230
231 va_start(va, format);
232 vsnprintf(buf, sizeof(buf), format, va);
233 va_end(va);
2172bfc8 234
4c551b15
CP
235 /* TODO */
236 xsb_send("$%s :XSB1 %s %s", serverlist[homeserver(np->numeric)].name, command, buf);
237 /* xsb_send("%s :XSB1 %s %s", longtonumeric(np->numeric, 5), command, buf);*/
238
2172bfc8 239}
4c551b15
CP
240
241int xsb_isservice(server *service) {
242 int i;
243 sstring **servicemasks;
244 char *name = service->name->content;
245
246 if(!(service->flags & SMODE_SERVICE))
247 return 0;
248
249 for(i=getservicemasks(&servicemasks)-1;i>=0;i--)
250 if(match2strings(servicemasks[i]->content, name))
251 return 1;
252
253 return 0;
254}
255