]> jfr.im git - irc/quakenet/newserv.git/blame - glines/glines_handler.c
Make cleanupglines a developer command and fix what it does.
[irc/quakenet/newserv.git] / glines / glines_handler.c
CommitLineData
a44fc5f7
GB
1#include <stdio.h>
2#include <string.h>
a44fc5f7 3#include "../localuser/localuserchannel.h"
a44fc5f7
GB
4#include "glines.h"
5
6/*
7 <prefix> GL <target> [!][+|-|>|<]<mask> [<expiration>] [<lastmod>] [<lifetime>] [:<reason>]
8*/
9
10int handleglinemsg(void *source, int cargc, char **cargv) {
11 char *sender = (char *)source;
a44fc5f7
GB
12 char *mask;
13 char *reason;
14 char *creator;
15 time_t lifetime = 0, expire = 0, lastmod = 0;
16 unsigned int flags = 0;
a44fc5f7
GB
17 long creatornum;
18 gline *agline;
19 nick *np;
cb581522 20 glinebuf gbuf;
a44fc5f7
GB
21
22 /**
23 * Valid GL tokens have X params:
24 * 2: Local modification to a local gline - ignored by services
c26406c8 25 * 4: ulined GL
a44fc5f7
GB
26 * 5: 1.3.x GL Token
27 * 6: 1.4.x GL Token - adds lifetime parameter
28 */
c684f472 29 switch (cargc) {
a44fc5f7
GB
30 case 2:
31 /* local modification which we reject later */
32 break;
c26406c8
GB
33 case 4:
34 /* ulined GL */
35 break;
a44fc5f7
GB
36 case 5:
37 /* 1.3.x GL Token */
38 break;
39 case 6:
40 /* 1.4.0 and above GL token */
41 break;
42 default:
43 Error("gline", ERR_WARNING, "Invalid number of arguments in GL token (%d)", cargc);
44 return CMD_ERROR;
45 }
46
47 /**
48 * Gline creator can be either a nick or a server
49 * 2 long numeric = server
50 * 5 long number = client
51 */
c684f472 52 switch (strlen(source)) {
a44fc5f7
GB
53 case 2:
54 creatornum = numerictolong(sender, 2);
55 if (creatornum < 0) {
56 Error("gline", ERR_WARNING, "Failed to resolve numeric (%s) to server when adding G-Line from network!", sender);
57 creator = "unknown";
58 } else
c684f472 59 if (serverlist[(int)creatornum].name == NULL) {
a44fc5f7
GB
60 Error("gline", ERR_WARNING, "Received gline from non-existant server");
61 return CMD_ERROR;
62 } else {
63 creator = serverlist[(int)creatornum].name->content, HOSTLEN;
64 }
65 break;
66 case 5:
67 creatornum = numerictolong(sender, 5);
c684f472
GB
68 np = getnickbynumeric(creatornum);
69 if (!np) {
a44fc5f7
GB
70 Error("gline", ERR_WARNING, "Failed to resolve numeric (%s) to nick when adding G-Line from network!", sender);
71 creator = "unknown";
72 } else
73 creator = np->nick;
74 break;
75 default:
76 Error("gline", ERR_WARNING, "Invalid numeric '%s' in G-Line message.", sender);
77 return CMD_ERROR;
78 }
79
a44fc5f7
GB
80 /* 2nd param is mask */
81 mask = cargv[1];
82
20447d72
GB
83 /* snircd 1.3.5 can destroy glines, no #if here */
84 if (*mask == '%') {
85 flags |= GLINE_DESTROY;
86 mask++;
87 }
88
a44fc5f7
GB
89 switch (*mask) {
90 case '+':
91 flags |= GLINE_ACTIVATE;
92 mask++;
93 break;
94 case '-':
95 flags |= GLINE_DEACTIVATE;
96 mask++;
97 break;
98 case '>':
99 case '<':
100 Error("gline", ERR_WARNING, "Received local modification from %s - do they realise we're a service?", sender);
101 return CMD_ERROR;
102 case '!':
103 Error("gline", ERR_WARNING, "Received 'forced gline' token from %s", sender);
104 return CMD_ERROR;
105 }
106
107 if (flags & GLINE_ACTIVATE) {
108 /* activate gline */
109 expire = abs_expire(atoi(cargv[2]));
110 switch (cargc) {
111 case 4:
112 /* asuka U:d, no lastmod */
21ae66d1
GB
113 lastmod = 0;
114 lifetime = expire;
a44fc5f7
GB
115 reason = cargv[3];
116 break;
117 case 5:
118 /*asuka lastmod */
119 lastmod = atoi(cargv[3]);
c684f472 120 lifetime = gline_max(lastmod, expire); /* set lifetime = lastmod */
a44fc5f7
GB
121 reason = cargv[4];
122 break;
123 case 6:
124 /* snircd */
125 lastmod = atoi(cargv[3]);
126 lifetime = atoi(cargv[4]);
127 reason = cargv[5];
128 break;
129 default:
130 Error("gline", ERR_WARNING, "Gline Activate with invalid number (%d) of arguments", cargc);
131 return CMD_ERROR;
132 }
133
134 Error("debuggline", ERR_WARNING, "GL Received: Creator %s, Mask %s, Reason %s, Expire %lu, Lastmod %lu, Lifetime %lu", creator, mask, reason, expire, lastmod, lifetime);
135
96662a86 136 agline = findgline(mask);
c684f472
GB
137
138 if (agline) {
dd44e3d8
GB
139 Error("debuggline", ERR_WARNING, "Update for existing gline received for %s - old lastmod %lu, expire %lu, lifetime %lu, reason %s, creator %s", mask, agline->lastmod, agline->expire, agline->lifetime, agline->reason->content, agline->creator->content);
140
141 agline->flags |= GLINE_ACTIVE;
142
143 /* check lastmod then assume the new gline is authoritive */
144 if (lastmod > agline->lastmod) {
145 agline->lastmod = lastmod;
146 agline->expire = expire;
147 agline->lifetime = lifetime;
148 freesstring(agline->creator);
149 agline->creator = getsstring(creator, 255);
150 freesstring(agline->reason);
151 agline->reason = getsstring(reason, 255);
a44fc5f7 152 } else {
dd44e3d8
GB
153 Error("debuggline", ERR_WARNING, "received a gline with a lower lastmod");
154 /* Don't send our gline as that might cause loops in case we don't understand the gline properly. */
155 }
156
157 return CMD_OK;
a44fc5f7 158 } else {
cb581522
GB
159 glinebufinit(&gbuf, 0);
160 glinebufadd(&gbuf, mask, creator, reason, expire, lastmod, lifetime);
161 glinebufflush(&gbuf, 0);
a44fc5f7
GB
162 }
163 } else if (flags & GLINE_DEACTIVATE) {
164 /* deactivate gline */
96662a86
GB
165 agline = findgline(mask);
166
167 if (agline) {
a44fc5f7
GB
168 switch (cargc) {
169 case 2:
170 /* asuka U:d, no last mod */
171 removegline(agline);
172 break;
173 case 5:
174 /* asuka last mod */
175 lastmod = atoi(cargv[3]);
20447d72
GB
176
177 if (flags & GLINE_DESTROY)
178 gline_destroy(agline, lastmod, 0);
179 else
180 gline_deactivate(agline, lastmod, 0);
181
a44fc5f7
GB
182 break;
183 case 6:
184 /* snircd */
185 lastmod = atoi(cargv[3]);
20447d72
GB
186
187 if (flags & GLINE_DESTROY)
188 gline_destroy(agline, lastmod, 0);
189 else
190 gline_deactivate(agline, lastmod, 0);
191
a44fc5f7
GB
192 break;
193 default:
194 Error("gline", ERR_WARNING, "Gline Deactivate with invalid number (%d) of arguments", cargc);
195 return CMD_ERROR;
196 }
c684f472 197
a44fc5f7
GB
198 return CMD_OK;
199 } else {
200 Error("gline", ERR_WARNING, "Gline addition - adding deactivated gline - mask not found (%s)", mask);
201 expire = abs_expire(atoi(cargv[2]));
202 switch (cargc) {
203 case 4:
204 /* asuka U:d, no lastmod */
205 reason = cargv[3];
206 break;
207 case 5:
208 /*asuka lastmod */
209 lastmod = atoi(cargv[3]);
c684f472 210 lifetime = gline_max(lastmod, expire); /* set lifetime = lastmod */
a44fc5f7
GB
211 reason = cargv[4];
212 break;
213 case 6:
214 /* snircd */
215 lastmod = atoi(cargv[3]);
216 lifetime = atoi(cargv[4]);
217 reason = cargv[5];
218 break;
219 default:
220 Error("gline", ERR_WARNING, "Gline DeActivate with invalid number (%d) of arguments", cargc);
221 return CMD_ERROR;
222 }
223
cb581522
GB
224 glinebufinit(&gbuf, 0);
225 agline = glinebufadd(&gbuf, mask, creator, reason, expire, lastmod, lifetime);
c684f472
GB
226
227 if (!agline) {
cb581522 228 glinebufabandon(&gbuf);
a44fc5f7 229 Error("gline", ERR_WARNING, "gline_add failed");
c684f472
GB
230 return CMD_ERROR;
231 }
232
233 gline_deactivate(agline, lastmod, 0);
cb581522 234 glinebufflush(&gbuf, 0);
c684f472
GB
235
236 return CMD_OK;
a44fc5f7
GB
237 }
238 } else {
239 /* modification - only snircd 1.4.x */
96662a86
GB
240 agline = findgline(mask);
241
242 if (agline) {
a44fc5f7
GB
243 expire = abs_expire(atoi(cargv[2]));
244 lastmod = atoi(cargv[3]);
245 lifetime = atoi(cargv[4]);
246 reason = cargv[5];
247
c684f472 248 if (lastmod > agline->lastmod) {
a44fc5f7
GB
249 agline->lastmod = lastmod;
250 agline->expire = expire;
251 agline->lifetime = lifetime;
252 agline->creator = getsstring(creator, 255);
253 freesstring(agline->reason);
254 agline->reason = getsstring(reason, 255);
255 } else {
256 Error("debuggline", ERR_WARNING, "received a gline modification with a lower lastmod");
a44fc5f7 257 }
c684f472 258
a44fc5f7
GB
259 return CMD_OK;
260 } else {
c684f472 261 Error("gline", ERR_WARNING, "Received modification for G-Line that does not exist for mask %s", mask);
a44fc5f7
GB
262 return CMD_ERROR;
263 }
264 }
c684f472 265
a44fc5f7
GB
266 return CMD_OK;
267}
268
a44fc5f7 269void handleglinestats(int hooknum, void *arg) {
c684f472 270 if ((long)arg > 10) {
a44fc5f7
GB
271 char message[100];
272 int glcount = 0;
273 gline *gl;
274
c684f472 275 for(gl = glinelist; gl; gl = gl->next)
a44fc5f7 276 glcount++;
a44fc5f7 277
c684f472 278 snprintf(message, sizeof(message), "G-Lines :%7d glines", glcount);
a44fc5f7
GB
279 triggerhook(HOOK_CORE_STATSREPLY, message);
280 }
281}
282