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