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