]> jfr.im git - irc/quakenet/newserv.git/blame - xsb/xsb.c
merge
[irc/quakenet/newserv.git] / xsb / xsb.c
CommitLineData
2172bfc8
CP
1#include <string.h>
2#include <stdio.h>
3#include <stdarg.h>
4#include "../core/hooks.h"
5#include "../lib/splitline.h"
6#include "../core/config.h"
7#include "../irc/irc.h"
8#include "../lib/array.h"
9#include "../lib/base64.h"
10#include "../core/error.h"
11#include "../server/server.h"
12#include "../control/control.h"
13#include "xsb.h"
14
15static const char *DEFAULT_SERVICE_MASKS[] = { "services*.*.quakenet.org", (char *)0 };
16static array defaultservicemasks_a;
17static sstring **defaultservicemasks;
18
19static void handlemaskprivmsg(int, void *);
20static CommandTree *cmds;
21
22#define DEBUG
23
24void _init(void) {
25 const char **p;
26 array *servicemasks;
27
28 cmds = newcommandtree();
29 if(cmds)
30 registerhook(HOOK_NICK_MASKPRIVMSG, &handlemaskprivmsg);
31
32 array_init(&defaultservicemasks_a, sizeof(sstring *));
33
34 for(p=DEFAULT_SERVICE_MASKS;*p;p++) {
35 int i = array_getfreeslot(&defaultservicemasks_a);
36 defaultservicemasks = (sstring **)defaultservicemasks_a.content;
37
38 defaultservicemasks[i] = getsstring(*p, strlen(*p));
39 }
40
41 servicemasks = getconfigitems("xsb", "servicemask");
42 if(!servicemasks || !servicemasks->cursi)
43 Error("xsb", ERR_WARNING, "No service masks in config file (xsb/servicemask), using defaults");
44}
45
46void _fini(void) {
47 int i;
48
49 for(i=0;i<defaultservicemasks_a.cursi;i++)
50 freesstring(defaultservicemasks[i]);
51 array_free(&defaultservicemasks_a);
52
53 if(!cmds)
54 return;
55
56 deregisterhook(HOOK_NICK_MASKPRIVMSG, &handlemaskprivmsg);
57
58 destroycommandtree(cmds);
59}
60
61static void handlemaskprivmsg(int hooknum, void *args) {
62 void **hargs = (void **)args;
63 nick *source = hargs[0];
64 char *message = hargs[2];
65 Command *cmd;
66 int cargc;
67 char *cargv[50];
68 server *s;
69
70 if(!source)
71 return;
72
73 if(!IsOper(source) || !IsService(source))
74 return;
75
76 cargc = splitline(message, cargv, 50, 0);
77 if(cargc < 2)
78 return;
79
80 if(strcmp(cargv[0], "XSB1"))
81 return;
82
83 s = &serverlist[homeserver(source->numeric)];
84 if(s->linkstate != LS_LINKED) {
85 Error("xsb", ERR_WARNING, "Got XSB message from unlinked server (%s): %s", s->name->content, source->nick);
86 return;
87 }
88
89#ifndef DEBUG
90 if(!(s->flags & SMODE_SERVICE)) {
91 Error("xsb", ERR_WARNING, "Got XSB message from non-service server (%s): %s", s->name->content, source->nick);
92 return;
93 }
94#endif
95
96 cmd = findcommandintree(cmds, cargv[1], 1);
97 if(!cmd)
98 return;
99
100 if(cmd->maxparams < (cargc - 2)) {
101 rejoinline(cargv[cmd->maxparams], cargc - (cmd->maxparams));
102 cargc = (cmd->maxparams) + 2;
103 }
104
105 (cmd->handler)(source, cargc - 2, &cargv[2]);
106}
107
108void xsb_addcommand(const char *name, const int maxparams, CommandHandler handler) {
109 addcommandtotree(cmds, name, 0, maxparams, handler);
110}
111
112void xsb_delcommand(const char *name, CommandHandler handler) {
113 deletecommandfromtree(cmds, name, handler);
114}
115
116void xsb_command(const char *command, const char *format, ...) {
117 char buf[512];
118 va_list va;
119 sstring **servicemasks;
120 array *aservicemasks;
121 int i;
122 char *controlnum;
123
124 va_start(va, format);
125 vsnprintf(buf, sizeof(buf), format, va);
126 va_end(va);
127
128 aservicemasks = getconfigitems("xsb", "servicemask");
129 if(!aservicemasks || !aservicemasks->cursi)
130 aservicemasks = &defaultservicemasks_a;
131
132 servicemasks = (sstring **)aservicemasks->content;
133
134 controlnum = longtonumeric(mynick->numeric, 5);
135
136 for(i=0;i<aservicemasks->cursi;i++)
137 irc_send("%s P $%s :XSB1 %s %s", controlnum, servicemasks[i]->content, command, buf);
138}