1 /* Copyright (C) 1999-2004 Timo Sirainen */
2
3 #include "module.h"
4 #include "module-formats.h"
5 #include "signals.h"
6 #include "levels.h"
7 #include "misc.h"
8 #include "settings.h"
9 #include "recode.h"
10
11 #include "irc-servers.h"
12
13 #include "printtext.h"
14
event_whois(IRC_SERVER_REC * server,const char * data)15 static void event_whois(IRC_SERVER_REC *server, const char *data)
16 {
17 char *params, *nick, *user, *host, *realname, *recoded;
18
19 g_return_if_fail(data != NULL);
20
21 params = event_get_params(data, 6, NULL, &nick, &user,
22 &host, NULL, &realname);
23 recoded = recode_in(SERVER(server), realname, nick);
24 printformat(server, nick, MSGLEVEL_CRAP,
25 IRCTXT_WHOIS, nick, user, host, recoded);
26 g_free(params);
27 g_free(recoded);
28 }
29
event_whois_special(IRC_SERVER_REC * server,const char * data)30 static void event_whois_special(IRC_SERVER_REC *server, const char *data)
31 {
32 char *params, *nick, *str;
33
34 g_return_if_fail(data != NULL);
35
36 params = event_get_params(data, 3 | PARAM_FLAG_GETREST, NULL, &nick, &str);
37 printformat(server, nick, MSGLEVEL_CRAP,
38 IRCTXT_WHOIS_SPECIAL, nick, str);
39 g_free(params);
40 }
41
event_whois_idle(IRC_SERVER_REC * server,const char * data)42 static void event_whois_idle(IRC_SERVER_REC *server, const char *data)
43 {
44 char *params, *nick, *secstr, *signonstr, *rest, *timestr;
45 long days, hours, mins, secs;
46 time_t signon;
47
48 g_return_if_fail(data != NULL);
49
50 params = event_get_params(data, 5 | PARAM_FLAG_GETREST, NULL,
51 &nick, &secstr, &signonstr, &rest);
52
53 secs = atol(secstr);
54 signon = strstr(rest, "signon time") == NULL ? 0 :
55 (time_t) atol(signonstr);
56
57 days = secs/3600/24;
58 hours = (secs%(3600*24))/3600;
59 mins = (secs%3600)/60;
60 secs %= 60;
61
62 if (signon == 0)
63 printformat(server, nick, MSGLEVEL_CRAP, IRCTXT_WHOIS_IDLE,
64 nick, days, hours, mins, secs);
65 else {
66 timestr = my_asctime(signon);
67 printformat(server, nick, MSGLEVEL_CRAP,
68 IRCTXT_WHOIS_IDLE_SIGNON,
69 nick, days, hours, mins, secs, timestr);
70 g_free(timestr);
71 }
72 g_free(params);
73 }
74
event_whois_server(IRC_SERVER_REC * server,const char * data)75 static void event_whois_server(IRC_SERVER_REC *server, const char *data)
76 {
77 char *params, *nick, *whoserver, *desc;
78
79 g_return_if_fail(data != NULL);
80
81 params = event_get_params(data, 4, NULL, &nick, &whoserver, &desc);
82 printformat(server, nick, MSGLEVEL_CRAP,
83 IRCTXT_WHOIS_SERVER, nick, whoserver, desc);
84 g_free(params);
85 }
86
event_whois_oper(IRC_SERVER_REC * server,const char * data)87 static void event_whois_oper(IRC_SERVER_REC *server, const char *data)
88 {
89 char *params, *nick, *type;
90
91 g_return_if_fail(data != NULL);
92
93 params = event_get_params(data, 3, NULL, &nick, &type);
94
95 /* Bugfix: http://bugs.irssi.org/?do=details&task_id=99
96 * Author: Geert Hauwaerts <geert@irssi.org>
97 * Date: Wed Sep 15 20:17:24 CEST 2004
98 */
99
100 if ((!strncmp(type, "is an ", 6)) || (!strncmp(type, "is a ", 5))) {
101 type += 5;
102 if (*type == ' ') type++;
103 }
104
105 if (*type == '\0')
106 type = "IRC Operator";
107
108 printformat(server, nick, MSGLEVEL_CRAP,
109 IRCTXT_WHOIS_OPER, nick, type);
110 g_free(params);
111 }
112
event_whois_modes(IRC_SERVER_REC * server,const char * data)113 static void event_whois_modes(IRC_SERVER_REC *server, const char *data)
114 {
115 char *params, *nick, *modes;
116
117 g_return_if_fail(data != NULL);
118
119 params = event_get_params(data, 3 | PARAM_FLAG_GETREST,
120 NULL, &nick, &modes);
121 if (!strncmp(modes, "is using modes ", 15))
122 modes += 15;
123 printformat(server, nick, MSGLEVEL_CRAP,
124 IRCTXT_WHOIS_MODES, nick, modes);
125 g_free(params);
126 }
127
event_whois_realhost(IRC_SERVER_REC * server,const char * data)128 static void event_whois_realhost(IRC_SERVER_REC *server, const char *data)
129 {
130 char *params, *nick, *txt_real, *txt_hostname, *hostname;
131
132 g_return_if_fail(data != NULL);
133
134 /* <yournick> real hostname <nick> <hostname> */
135 params = event_get_params(data, 5, NULL, &nick, &txt_real,
136 &txt_hostname, &hostname);
137 if (g_strcmp0(txt_real, "real") != 0 ||
138 g_strcmp0(txt_hostname, "hostname") != 0) {
139 /* <yournick> <nick> :... from <hostname> */
140 g_free(params);
141 params = event_get_params(data, 3, NULL, &nick, &hostname);
142
143 hostname = strstr(hostname, "from ");
144 if (hostname != NULL) hostname += 5;
145 }
146
147 if (hostname != NULL) {
148 if (!strncmp(hostname, "*@", 2))
149 hostname += 2;
150 printformat(server, nick, MSGLEVEL_CRAP,
151 IRCTXT_WHOIS_REALHOST, nick, hostname, "");
152 } else {
153 event_whois_special(server, data);
154 }
155 g_free(params);
156 }
157
event_whois_usermode326(IRC_SERVER_REC * server,const char * data)158 static void event_whois_usermode326(IRC_SERVER_REC *server, const char *data)
159 {
160 char *params, *nick, *usermode;
161
162 g_return_if_fail(data != NULL);
163
164 /* <yournick> <nick> :has oper privs: <mode> */
165 params = event_get_params(data, 3, NULL, &nick, &usermode);
166 printformat(server, nick, MSGLEVEL_CRAP,
167 IRCTXT_WHOIS_USERMODE, nick, usermode);
168 g_free(params);
169 }
170
event_whois_realhost327(IRC_SERVER_REC * server,const char * data)171 static void event_whois_realhost327(IRC_SERVER_REC *server, const char *data)
172 {
173 char *params, *nick, *hostname, *ip, *text;
174
175 g_return_if_fail(data != NULL);
176
177 /* <yournick> <hostname> <ip> :Real hostname/IP */
178 params = event_get_params(data, 5, NULL, &nick, &hostname, &ip, &text);
179 if (*text != '\0') {
180 printformat(server, nick, MSGLEVEL_CRAP,
181 IRCTXT_WHOIS_REALHOST, nick, hostname, ip);
182 } else {
183 event_whois_special(server, data);
184 }
185 g_free(params);
186 }
187
event_whois_realhost338(IRC_SERVER_REC * server,const char * data)188 static void event_whois_realhost338(IRC_SERVER_REC *server, const char *data)
189 {
190 char *params, *nick, *arg1, *arg2, *arg3;
191
192 g_return_if_fail(data != NULL);
193
194 /*
195 * :<server> 338 <yournick> <nick> <user>@<host> <ip> :Actual user@host, actual IP
196 * (ircu) or
197 * :<server> 338 <yournick> <nick> <ip> :actually using host
198 * (ratbox)
199 */
200 params = event_get_params(data, 5, NULL, &nick, &arg1, &arg2, &arg3);
201 if (*arg3 != '\0') {
202 printformat(server, nick, MSGLEVEL_CRAP,
203 IRCTXT_WHOIS_REALHOST, nick, arg1, arg2);
204 } else if (*arg2 != '\0') {
205 printformat(server, nick, MSGLEVEL_CRAP,
206 IRCTXT_WHOIS_REALHOST, nick, arg1, "");
207 } else {
208 event_whois_special(server, data);
209 }
210 g_free(params);
211 }
212
event_whois_usermode(IRC_SERVER_REC * server,const char * data)213 static void event_whois_usermode(IRC_SERVER_REC *server, const char *data)
214 {
215 char *params, *txt_usermodes, *nick, *usermode;
216
217 g_return_if_fail(data != NULL);
218
219 params = event_get_params(data, 4, NULL, &txt_usermodes,
220 &nick, &usermode);
221
222 if (g_strcmp0(txt_usermodes, "usermodes") == 0) {
223 /* <yournick> usermodes <nick> usermode */
224 printformat(server, nick, MSGLEVEL_CRAP,
225 IRCTXT_WHOIS_USERMODE, nick, usermode);
226 } else {
227 event_whois_special(server, data);
228 }
229 g_free(params);
230 }
231
hide_safe_channel_id(IRC_SERVER_REC * server,char * chans)232 static void hide_safe_channel_id(IRC_SERVER_REC *server, char *chans)
233 {
234 const char *idchan, *nick_flags;
235 char *p, *dest, *end, id;
236 int count, length, chanstart;
237
238 if (!server->isupport_sent)
239 idchan = "!:5";
240 else {
241 idchan = g_hash_table_lookup(server->isupport, "IDCHAN");
242 if (idchan == NULL)
243 return;
244 }
245 nick_flags = server->get_nick_flags(SERVER(server));
246
247 while (*idchan != '\0') {
248 id = *idchan;
249 if (idchan[1] != ':')
250 return;
251
252 length = strtoul(idchan+2, &end, 10);
253 if (*end == ',')
254 end++;
255 else if (*end != '\0')
256 return;
257 idchan = end;
258
259 count = 0;
260 chanstart = TRUE;
261 for (dest = p = chans; *p != '\0'; p++) {
262 if (count > 0)
263 count--;
264 else {
265 if (*p == ' ')
266 chanstart = TRUE;
267 else {
268 if (chanstart && *p == id)
269 count = length;
270 chanstart = chanstart && strchr(nick_flags, *p);
271 }
272 *dest++ = *p;
273 }
274 }
275 *dest = '\0';
276 }
277 }
278
event_whois_channels(IRC_SERVER_REC * server,const char * data)279 static void event_whois_channels(IRC_SERVER_REC *server, const char *data)
280 {
281 char *params, *nick, *chans, *recoded;
282
283 g_return_if_fail(data != NULL);
284
285 params = event_get_params(data, 3, NULL, &nick, &chans);
286
287 /* sure - we COULD print the channel names as-is, but since the
288 colors, bolds, etc. are mostly just to fool people, I think we
289 should show the channel names as they REALLY are so they could
290 even be joined without any extra tricks. */
291 chans = show_lowascii(chans);
292 if (settings_get_bool("whois_hide_safe_channel_id"))
293 hide_safe_channel_id(server, chans);
294 recoded = recode_in(SERVER(server), chans, nick);
295 printformat(server, nick, MSGLEVEL_CRAP,
296 IRCTXT_WHOIS_CHANNELS, nick, recoded);
297 g_free(chans);
298
299 g_free(params);
300 g_free(recoded);
301 }
302
event_whois_away(IRC_SERVER_REC * server,const char * data)303 static void event_whois_away(IRC_SERVER_REC *server, const char *data)
304 {
305 char *params, *nick, *awaymsg, *recoded;
306
307 g_return_if_fail(data != NULL);
308
309 params = event_get_params(data, 3, NULL, &nick, &awaymsg);
310 recoded = recode_in(SERVER(server), awaymsg, nick);
311 printformat(server, nick, MSGLEVEL_CRAP,
312 IRCTXT_WHOIS_AWAY, nick, recoded);
313 g_free(params);
314 g_free(recoded);
315 }
316
event_end_of_whois(IRC_SERVER_REC * server,const char * data)317 static void event_end_of_whois(IRC_SERVER_REC *server, const char *data)
318 {
319 char *params, *nick;
320
321 g_return_if_fail(data != NULL);
322
323 params = event_get_params(data, 2, NULL, &nick);
324 if (server->whois_found) {
325 printformat(server, nick, MSGLEVEL_CRAP,
326 IRCTXT_END_OF_WHOIS, nick);
327 }
328 g_free(params);
329 }
330
event_whois_auth(IRC_SERVER_REC * server,const char * data)331 static void event_whois_auth(IRC_SERVER_REC *server, const char *data)
332 {
333 char *params, *nick, *text;
334
335 g_return_if_fail(data != NULL);
336
337 params = event_get_params(data, 3, NULL, &nick, &text);
338 printformat(server, nick, MSGLEVEL_CRAP,
339 IRCTXT_WHOIS_EXTRA, nick, text);
340 g_free(params);
341 }
342
event_whowas(IRC_SERVER_REC * server,const char * data)343 static void event_whowas(IRC_SERVER_REC *server, const char *data)
344 {
345 char *params, *nick, *user, *host, *realname, *recoded;
346
347 g_return_if_fail(data != NULL);
348
349 params = event_get_params(data, 6, NULL, &nick, &user,
350 &host, NULL, &realname);
351 recoded = recode_in(SERVER(server), realname, nick);
352 printformat(server, nick, MSGLEVEL_CRAP,
353 IRCTXT_WHOWAS, nick, user, host, recoded);
354 g_free(params);
355 g_free(recoded);
356 }
357
event_end_of_whowas(IRC_SERVER_REC * server,const char * data)358 static void event_end_of_whowas(IRC_SERVER_REC *server, const char *data)
359 {
360 char *params, *nick;
361
362 g_return_if_fail(data != NULL);
363
364 params = event_get_params(data, 2, NULL, &nick);
365 if (server->whowas_found) {
366 printformat(server, nick, MSGLEVEL_CRAP,
367 IRCTXT_END_OF_WHOWAS, nick);
368 }
369 g_free(params);
370 }
371
372 struct whois_event_table {
373 int num;
374 void (*func)(IRC_SERVER_REC *, const char *);
375 };
376
377 static struct whois_event_table events[] = {
378 { 312, event_whois_server },
379 { 326, event_whois_usermode326 },
380 { 327, event_whois_realhost327 },
381 { 338, event_whois_realhost338 },
382 { 379, event_whois_modes },
383 { 378, event_whois_realhost },
384 { 377, event_whois_usermode },
385 { 317, event_whois_idle },
386 { 330, event_whois_auth },
387 { 319, event_whois_channels },
388 { 0, NULL }
389 };
390
event_whois_default(IRC_SERVER_REC * server,const char * data)391 static void event_whois_default(IRC_SERVER_REC *server, const char *data)
392 {
393 int i, num;
394
395 num = atoi(current_server_event);
396 for (i = 0; events[i].num != 0; i++) {
397 if (events[i].num == num) {
398 events[i].func(server, data);
399 return;
400 }
401 }
402
403 event_whois_special(server, data);
404 }
405
fe_whois_init(void)406 void fe_whois_init(void)
407 {
408 settings_add_bool("lookandfeel", "whois_hide_safe_channel_id", TRUE);
409
410 signal_add("event 311", (SIGNAL_FUNC) event_whois);
411 signal_add("event 312", (SIGNAL_FUNC) event_whois_server);
412 /* readding this events fixes the printing of /whois -yes *
413 Bug http://bugs.irssi.org/?do=details&task_id=123 */
414 signal_add("event 317", (SIGNAL_FUNC) event_whois_idle);
415 signal_add("event 319", (SIGNAL_FUNC) event_whois_channels);
416 signal_add("event 313", (SIGNAL_FUNC) event_whois_oper);
417 signal_add("event 330", (SIGNAL_FUNC) event_whois_auth);
418 signal_add("event 377", (SIGNAL_FUNC) event_whois_usermode);
419 signal_add("event 378", (SIGNAL_FUNC) event_whois_realhost);
420 signal_add("event 379", (SIGNAL_FUNC) event_whois_modes);
421 signal_add("event 327", (SIGNAL_FUNC) event_whois_realhost327);
422 signal_add("event 326", (SIGNAL_FUNC) event_whois_usermode326);
423 signal_add("event 338", (SIGNAL_FUNC) event_whois_realhost338);
424 signal_add("whois away", (SIGNAL_FUNC) event_whois_away);
425 signal_add("whois oper", (SIGNAL_FUNC) event_whois_oper);
426 signal_add("whowas away", (SIGNAL_FUNC) event_whois_away);
427 signal_add("whois default event", (SIGNAL_FUNC) event_whois_default);
428 signal_add("event 318", (SIGNAL_FUNC) event_end_of_whois);
429 signal_add("event 314", (SIGNAL_FUNC) event_whowas);
430 signal_add("event 369", (SIGNAL_FUNC) event_end_of_whowas);
431 }
432
fe_whois_deinit(void)433 void fe_whois_deinit(void)
434 {
435 signal_remove("event 311", (SIGNAL_FUNC) event_whois);
436 signal_remove("event 312", (SIGNAL_FUNC) event_whois_server);
437 signal_remove("event 317", (SIGNAL_FUNC) event_whois_idle);
438 signal_remove("event 319", (SIGNAL_FUNC) event_whois_channels);
439 signal_remove("event 313", (SIGNAL_FUNC) event_whois_oper);
440 signal_remove("event 330", (SIGNAL_FUNC) event_whois_auth);
441 signal_remove("event 377", (SIGNAL_FUNC) event_whois_usermode);
442 signal_remove("event 378", (SIGNAL_FUNC) event_whois_realhost);
443 signal_remove("event 379", (SIGNAL_FUNC) event_whois_modes);
444 signal_remove("event 327", (SIGNAL_FUNC) event_whois_realhost327);
445 signal_remove("event 326", (SIGNAL_FUNC) event_whois_usermode326);
446 signal_remove("event 338", (SIGNAL_FUNC) event_whois_realhost338);
447 signal_remove("whois away", (SIGNAL_FUNC) event_whois_away);
448 signal_remove("whois oper", (SIGNAL_FUNC) event_whois_oper);
449 signal_remove("whowas away", (SIGNAL_FUNC) event_whois_away);
450 signal_remove("whois default event", (SIGNAL_FUNC) event_whois_default);
451 signal_remove("event 318", (SIGNAL_FUNC) event_end_of_whois);
452 signal_remove("event 314", (SIGNAL_FUNC) event_whowas);
453 signal_remove("event 369", (SIGNAL_FUNC) event_end_of_whowas);
454 }
455