]> jfr.im git - irc/quakenet/newserv.git/blame - glines2/gline_handler.c
Merge.
[irc/quakenet/newserv.git] / glines2 / gline_handler.c
CommitLineData
1151d736
P
1#include <string.h>
2
3#include "../control/control.h"
4#include "../nick/nick.h"
5#include "../localuser/localuserchannel.h"
6#include "../core/hooks.h"
7#include "../server/server.h"
8#include "../parser/parser.h"
9#include "../core/schedule.h"
10#include "../lib/array.h"
11#include "../lib/base64.h"
12#include "../lib/irc_string.h"
13#include "../lib/splitline.h"
14#include "gline.h"
15
16/*
17 <prefix> GL <target> [!][+|-|>|<]<mask> [<expiration>] [<lastmod>]
18 [<lifetime>] [:<reason>]
19*/
20
21int handleglinemsg(void* source, int cargc, char** cargv) {
22 char* sender = (char*)source;
23 char* target;
24 char* mask;
25 char* reason;
26 sstring *creator;
27 time_t lifetime = 0, expires = 0, lastmod = 0;
28 unsigned int flags = 0;
29 int numlen;
30 long creatornum;
31 gline *agline;
32
33 nick* np;
34
35 int i;
36 for (i = 0; i <cargc; i++) {
37 Error("debuggline", ERR_WARNING, "Token %d is - %s", i, cargv[i]);
38 }
39
40 /* valid GL tokens have X params */
41 switch ( cargc ) {
1ce4eeea
P
42 case 2:
43 /* local modification which we reject later */
44 break;
1151d736
P
45 case 5:
46 /* 1.3.x GL Token */
47 break;
48 case 6:
49 /* 1.4.0 and above GL token */
50 break;
51 default:
52 Error("gline", ERR_WARNING, "Invalid number of arguments in GL token (%d)", cargc);
53 return CMD_ERROR;
54 }
55
56 /* gline creator can be either a nick or a server */
57 numlen = strlen(source);
58 switch (numlen) {
59 case 2:
60 creatornum = numerictolong(sender, 2);
61 if (creatornum < 0) {
62 Error("gline", ERR_WARNING, "Failed to resolve numeric to server (%s) when adding G-Line!", sender);
63 creator = getsstring("unknown", HOSTLEN);
64 } else
65 creator = getsstring(serverlist[(int)creatornum].name->content, HOSTLEN);
66 break;
67 case 5:
68 creatornum = numerictolong(sender, 5);
69 if (!(np = getnickbynumeric(creatornum))) {
70 Error("gline", ERR_WARNING, "Failed to resolve numeric to nick when adding G-Line!", sender);
71 creator = getsstring("unknown", HOSTLEN);
72 } else
73 creator = getsstring( np->nick, NICKLEN);
74 break;
75 default:
76 Error("gline", ERR_WARNING, "Invalid numeric '%s' in G-Line message.", sender);
77 }
78
79 /* 1st param is target */
80 target = cargv[0];
81
82 /* 2nd param is mask */
83 mask = cargv[1];
84
85 if (*mask == '!') {
86 Error("gline", ERR_DEBUG, " forced flag ");
87 mask++;
88 }
89
90 switch (*mask) {
91 case '+':
92 flags |= GLINE_ACTIVATE;
93 mask++;
94 break;
95 case '-':
96 flags |= GLINE_DEACTIVATE;
97 mask++;
98 break;
99 case '>':
100 case '<':
1ce4eeea 101 Error("gline", ERR_WARNING, "Received local modification from %s - do they realise we're a service?", sender);
1151d736
P
102 return CMD_ERROR;
103 }
104
105 /* anything other than a global G-Line is irrelevant */
106 if (strcmp(target, "*")) {
107 Error("gline", ERR_WARNING, "Received local g-line from %s - do they realise we're a service?", sender);
108 return CMD_ERROR;
109 }
110
111 if (flags & GLINE_ACTIVATE) {
112 /* activate gline */
113 expires = abs_expire(atoi(cargv[2]));
114 switch (cargc) {
115 case 4:
116 /* asuka U:d, no lastmod */
117 reason = cargv[3];
118 break;
119 case 5:
120 /*asuka lastmod */
121 lastmod = atoi(cargv[3]);
122 lifetime = gline_max(lastmod,expires); /* set lifetime = lastmod */
123 reason = cargv[4];
124 break;
125 case 6:
126 /* snircd */
127 lastmod = atoi(cargv[3]);
128 lifetime = atoi(cargv[4]);
129 reason = cargv[5];
130 break;
131 default:
132 Error("gline", ERR_WARNING, "Gline Activate with invalid number (%d) of arguments", cargc);
133 return CMD_ERROR;
134 }
135
136 Error("debuggline", ERR_WARNING, "GL Received: Creator %s, Mask %s, Reason %s, Expire %lu, Lastmod %lu, Lifetime %lu", creator->content, mask, reason, expires, lastmod, lifetime);
137 if ( (agline=gline_find(mask)) ) {
138 if (agline->flags & GLINE_ACTIVE ) {
139 Error("debuggline", ERR_WARNING, "Duplicate Gline recieved for %s - old lastmod %lu, expire %lu, lifetime %lu, reason %s, creator %s", mask, agline->lastmod, agline->expires, agline->lifetime, agline->reason->content, agline->creator->content );
140 } else {
141 /* we're reactivating a gline - check lastmod then assume the new gline is authoritive */
142 if ( lastmod > agline->lastmod ) {
143 agline->lastmod = lastmod;
144 agline->expires = expires;
145 agline->lifetime = lifetime;
146 agline->creator = creator;
147 freesstring(agline->reason);
148 agline->reason = getsstring(reason, 255);
149 agline->flags |= GLINE_ACTIVE;
150 } else {
151 Error("debuggline", ERR_WARNING, "received a gline with a lower lastmod");
152 /* @@@TODO resend our gline ? */
153 }
154 }
155 /* TODO */
156 return CMD_ERROR;
157 } else {
158 gline_add( creatornum, creator, mask, reason, expires, lastmod, lifetime);
159 }
160 } else if (flags & GLINE_DEACTIVATE) {
161 /* deactivate gline */
162 if ((agline = gline_find(mask))) {
163 switch (cargc) {
164 case 2:
165 /* asuka U:d, no last mod */
166 removegline(agline);
167 break;
168 case 5:
169 /* asuka last mod */
170 lastmod = atoi(cargv[3]);
171 gline_deactivate(agline, lastmod, 0);
172 break;
173 case 6:
174 /* snircd */
175 lastmod = atoi(cargv[3]);
176 gline_deactivate(agline, lastmod, 0);
177 break;
178 default:
179 Error("gline", ERR_WARNING, "Gline Deactivate with invalid number (%d) of arguments", cargc);
180 return CMD_ERROR;
181 }
182 return CMD_OK;
183 } else {
184 Error("gline", ERR_WARNING, "Gline addition - adding deactivated gline - mask not found (%s)", mask);
185 expires = abs_expire(atoi(cargv[2]));
186 switch (cargc) {
187 case 4:
188 /* asuka U:d, no lastmod */
189 reason = cargv[3];
190 break;
191 case 5:
192 /*asuka lastmod */
193 lastmod = atoi(cargv[3]);
194 lifetime = gline_max(lastmod,expires); /* set lifetime = lastmod */
195 reason = cargv[4];
196 break;
197 case 6:
198 /* snircd */
199 lastmod = atoi(cargv[3]);
200 lifetime = atoi(cargv[4]);
201 reason = cargv[5];
202 break;
203 default:
204 Error("gline", ERR_WARNING, "Gline DeActivate with invalid number (%d) of arguments", cargc);
205 return CMD_ERROR;
206 }
207
208 agline = gline_add( creatornum, creator, mask, reason, expires, lastmod, lifetime);
209 gline_deactivate(agline, lastmod, 0);
210 return CMD_ERROR;
211 }
212 } else {
213 /* modification - only snircd 1.4.x */
1ce4eeea
P
214 if ((agline = gline_find(mask))) {
215 expires = abs_expire(atoi(cargv[2]));
216 lastmod = atoi(cargv[3]);
217 lifetime = atoi(cargv[4]);
218 reason = cargv[5];
219
220 if ( lastmod > agline->lastmod ) {
221 agline->lastmod = lastmod;
222 agline->expires = expires;
223 agline->lifetime = lifetime;
224 agline->creator = creator;
225 freesstring(agline->reason);
226 agline->reason = getsstring(reason, 255);
227 } else {
228 Error("debuggline", ERR_WARNING, "received a gline modification with a lower lastmod");
229 /* @@@TODO resend our gline ? */
230 }
231 return CMD_OK;
232 } else {
233 Error("gline", ERR_WARNING, "Received modification for gline that does not exist for mask %s", mask);
234 return CMD_ERROR;
235 }
1151d736
P
236 }
237
238 Error("debuggline", ERR_WARNING, "Creator %s", creator->content);
239 return CMD_OK;
240}
241
242
243int gline_deactivate(gline *agline, time_t lastmod, int propagate) {
244 agline->flags &= ~GLINE_ACTIVE;
245 agline->lastmod = lastmod;
246}