diff options
Diffstat (limited to 'src/fe-common/irc/fe-whois.c')
-rw-r--r-- | src/fe-common/irc/fe-whois.c | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/src/fe-common/irc/fe-whois.c b/src/fe-common/irc/fe-whois.c new file mode 100644 index 0000000..b0eeb19 --- /dev/null +++ b/src/fe-common/irc/fe-whois.c @@ -0,0 +1,456 @@ +/* Copyright (C) 1999-2004 Timo Sirainen */ + +#include "module.h" +#include <irssi/src/fe-common/irc/module-formats.h> +#include <irssi/src/core/signals.h> +#include <irssi/src/core/levels.h> +#include <irssi/src/core/misc.h> +#include <irssi/src/core/settings.h> +#include <irssi/src/core/recode.h> + +#include <irssi/src/irc/core/irc-servers.h> + +#include <irssi/src/fe-common/core/printtext.h> + +static void event_whois(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *user, *host, *realname, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 6, NULL, &nick, &user, + &host, NULL, &realname); + recoded = recode_in(SERVER(server), realname, nick); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS, nick, user, host, recoded); + g_free(params); + g_free(recoded); +} + +static void event_whois_special(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *str; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3 | PARAM_FLAG_GETREST, NULL, &nick, &str); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_SPECIAL, nick, str); + g_free(params); +} + +static void event_whois_idle(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *secstr, *signonstr, *rest, *timestr; + long days, hours, mins, secs; + time_t signon; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 5 | PARAM_FLAG_GETREST, NULL, + &nick, &secstr, &signonstr, &rest); + + secs = atol(secstr); + signon = strstr(rest, "signon time") == NULL ? 0 : + (time_t) atol(signonstr); + + days = secs/3600/24; + hours = (secs%(3600*24))/3600; + mins = (secs%3600)/60; + secs %= 60; + + if (signon == 0) + printformat(server, nick, MSGLEVEL_CRAP, IRCTXT_WHOIS_IDLE, + nick, days, hours, mins, secs); + else { + timestr = my_asctime(signon); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_IDLE_SIGNON, + nick, days, hours, mins, secs, timestr); + g_free(timestr); + } + g_free(params); +} + +static void event_whois_server(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *whoserver, *desc; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 4, NULL, &nick, &whoserver, &desc); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_SERVER, nick, whoserver, desc); + g_free(params); +} + +static void event_whois_oper(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *type; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &nick, &type); + + /* Bugfix: http://bugs.irssi.org/?do=details&task_id=99 + * Author: Geert Hauwaerts <geert@irssi.org> + * Date: Wed Sep 15 20:17:24 CEST 2004 + */ + + if ((!strncmp(type, "is an ", 6)) || (!strncmp(type, "is a ", 5))) { + type += 5; + if (*type == ' ') type++; + } + + if (*type == '\0') + type = "IRC Operator"; + + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_OPER, nick, type); + g_free(params); +} + +static void event_whois_modes(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *modes; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3 | PARAM_FLAG_GETREST, + NULL, &nick, &modes); + if (!strncmp(modes, "is using modes ", 15)) + modes += 15; + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_MODES, nick, modes); + g_free(params); +} + +static void event_whois_realhost(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *txt_real, *txt_hostname, *hostname; + + g_return_if_fail(data != NULL); + + /* <yournick> real hostname <nick> <hostname> */ + params = event_get_params(data, 5, NULL, &nick, &txt_real, + &txt_hostname, &hostname); + if (g_strcmp0(txt_real, "real") != 0 || + g_strcmp0(txt_hostname, "hostname") != 0) { + /* <yournick> <nick> :... from <hostname> */ + g_free(params); + params = event_get_params(data, 3, NULL, &nick, &hostname); + + hostname = strstr(hostname, "from "); + if (hostname != NULL) hostname += 5; + } + + if (hostname != NULL) { + if (!strncmp(hostname, "*@", 2)) + hostname += 2; + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_REALHOST, nick, hostname, ""); + } else { + event_whois_special(server, data); + } + g_free(params); +} + +static void event_whois_usermode326(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *usermode; + + g_return_if_fail(data != NULL); + + /* <yournick> <nick> :has oper privs: <mode> */ + params = event_get_params(data, 3, NULL, &nick, &usermode); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_USERMODE, nick, usermode); + g_free(params); +} + +static void event_whois_realhost327(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *hostname, *ip, *text; + + g_return_if_fail(data != NULL); + + /* <yournick> <hostname> <ip> :Real hostname/IP */ + params = event_get_params(data, 5, NULL, &nick, &hostname, &ip, &text); + if (*text != '\0') { + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_REALHOST, nick, hostname, ip); + } else { + event_whois_special(server, data); + } + g_free(params); +} + +static void event_whois_realhost338(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *arg1, *arg2, *arg3; + + g_return_if_fail(data != NULL); + + /* + * :<server> 338 <yournick> <nick> <user>@<host> <ip> :Actual user@host, actual IP + * (ircu) or + * :<server> 338 <yournick> <nick> <ip> :actually using host + * (ratbox) + */ + params = event_get_params(data, 5, NULL, &nick, &arg1, &arg2, &arg3); + if (*arg3 != '\0') { + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_REALHOST, nick, arg1, arg2); + } else if (*arg2 != '\0') { + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_REALHOST, nick, arg1, ""); + } else { + event_whois_special(server, data); + } + g_free(params); +} + +static void event_whois_usermode(IRC_SERVER_REC *server, const char *data) +{ + char *params, *txt_usermodes, *nick, *usermode; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 4, NULL, &txt_usermodes, + &nick, &usermode); + + if (g_strcmp0(txt_usermodes, "usermodes") == 0) { + /* <yournick> usermodes <nick> usermode */ + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_USERMODE, nick, usermode); + } else { + event_whois_special(server, data); + } + g_free(params); +} + +static void hide_safe_channel_id(IRC_SERVER_REC *server, char *chans) +{ + const char *idchan, *nick_flags; + char *p, *dest, *end, id; + int count, length, chanstart; + + if (!server->isupport_sent) + idchan = "!:5"; + else { + idchan = g_hash_table_lookup(server->isupport, "IDCHAN"); + if (idchan == NULL) + return; + } + nick_flags = server->get_nick_flags(SERVER(server)); + + while (*idchan != '\0') { + id = *idchan; + if (idchan[1] != ':') + return; + + length = strtoul(idchan+2, &end, 10); + if (*end == ',') + end++; + else if (*end != '\0') + return; + idchan = end; + + count = 0; + chanstart = TRUE; + for (dest = p = chans; *p != '\0'; p++) { + if (count > 0) + count--; + else { + if (*p == ' ') + chanstart = TRUE; + else { + if (chanstart && *p == id) + count = length; + chanstart = chanstart && strchr(nick_flags, *p); + } + *dest++ = *p; + } + } + *dest = '\0'; + } +} + +static void event_whois_channels(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *chans, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &nick, &chans); + + /* sure - we COULD print the channel names as-is, but since the + colors, bolds, etc. are mostly just to fool people, I think we + should show the channel names as they REALLY are so they could + even be joined without any extra tricks. */ + chans = show_lowascii(chans); + if (settings_get_bool("whois_hide_safe_channel_id")) + hide_safe_channel_id(server, chans); + recoded = recode_in(SERVER(server), chans, nick); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_CHANNELS, nick, recoded); + g_free(chans); + + g_free(params); + g_free(recoded); +} + +static void event_whois_away(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *awaymsg, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &nick, &awaymsg); + recoded = recode_in(SERVER(server), awaymsg, nick); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_AWAY, nick, recoded); + g_free(params); + g_free(recoded); +} + +static void event_end_of_whois(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &nick); + if (server->whois_found) { + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_END_OF_WHOIS, nick); + } + g_free(params); +} + +static void event_whois_auth(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *text; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 3, NULL, &nick, &text); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOIS_EXTRA, nick, text); + g_free(params); +} + +static void event_whowas(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick, *user, *host, *realname, *recoded; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 6, NULL, &nick, &user, + &host, NULL, &realname); + recoded = recode_in(SERVER(server), realname, nick); + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_WHOWAS, nick, user, host, recoded); + g_free(params); + g_free(recoded); +} + +static void event_end_of_whowas(IRC_SERVER_REC *server, const char *data) +{ + char *params, *nick; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &nick); + if (server->whowas_found) { + printformat(server, nick, MSGLEVEL_CRAP, + IRCTXT_END_OF_WHOWAS, nick); + } + g_free(params); +} + +struct whois_event_table { + int num; + void (*func)(IRC_SERVER_REC *, const char *); +}; + +static struct whois_event_table events[] = { + { 312, event_whois_server }, + { 326, event_whois_usermode326 }, + { 327, event_whois_realhost327 }, + { 338, event_whois_realhost338 }, + { 379, event_whois_modes }, + { 378, event_whois_realhost }, + { 377, event_whois_usermode }, + { 317, event_whois_idle }, + { 330, event_whois_auth }, + { 319, event_whois_channels }, + { 0, NULL } +}; + +static void event_whois_default(IRC_SERVER_REC *server, const char *data) +{ + int i, num; + + num = atoi(current_server_event); + for (i = 0; events[i].num != 0; i++) { + if (events[i].num == num) { + events[i].func(server, data); + return; + } + } + + event_whois_special(server, data); +} + +void fe_whois_init(void) +{ + settings_add_bool("lookandfeel", "whois_hide_safe_channel_id", TRUE); + + signal_add("event 311", (SIGNAL_FUNC) event_whois); + signal_add("event 312", (SIGNAL_FUNC) event_whois_server); + /* readding this events fixes the printing of /whois -yes * + Bug http://bugs.irssi.org/?do=details&task_id=123 */ + signal_add("event 317", (SIGNAL_FUNC) event_whois_idle); + signal_add("event 319", (SIGNAL_FUNC) event_whois_channels); + signal_add("event 313", (SIGNAL_FUNC) event_whois_oper); + signal_add("event 330", (SIGNAL_FUNC) event_whois_auth); + signal_add("whois account", (SIGNAL_FUNC) event_whois_auth); + signal_add("event 377", (SIGNAL_FUNC) event_whois_usermode); + signal_add("event 378", (SIGNAL_FUNC) event_whois_realhost); + signal_add("event 379", (SIGNAL_FUNC) event_whois_modes); + signal_add("event 327", (SIGNAL_FUNC) event_whois_realhost327); + signal_add("event 326", (SIGNAL_FUNC) event_whois_usermode326); + signal_add("event 338", (SIGNAL_FUNC) event_whois_realhost338); + signal_add("whois away", (SIGNAL_FUNC) event_whois_away); + signal_add("whois oper", (SIGNAL_FUNC) event_whois_oper); + signal_add("whowas away", (SIGNAL_FUNC) event_whois_away); + signal_add("whois default event", (SIGNAL_FUNC) event_whois_default); + signal_add("event 318", (SIGNAL_FUNC) event_end_of_whois); + signal_add("event 314", (SIGNAL_FUNC) event_whowas); + signal_add("event 369", (SIGNAL_FUNC) event_end_of_whowas); +} + +void fe_whois_deinit(void) +{ + signal_remove("event 311", (SIGNAL_FUNC) event_whois); + signal_remove("event 312", (SIGNAL_FUNC) event_whois_server); + signal_remove("event 317", (SIGNAL_FUNC) event_whois_idle); + signal_remove("event 319", (SIGNAL_FUNC) event_whois_channels); + signal_remove("event 313", (SIGNAL_FUNC) event_whois_oper); + signal_remove("event 330", (SIGNAL_FUNC) event_whois_auth); + signal_remove("whois account", (SIGNAL_FUNC) event_whois_auth); + signal_remove("event 377", (SIGNAL_FUNC) event_whois_usermode); + signal_remove("event 378", (SIGNAL_FUNC) event_whois_realhost); + signal_remove("event 379", (SIGNAL_FUNC) event_whois_modes); + signal_remove("event 327", (SIGNAL_FUNC) event_whois_realhost327); + signal_remove("event 326", (SIGNAL_FUNC) event_whois_usermode326); + signal_remove("event 338", (SIGNAL_FUNC) event_whois_realhost338); + signal_remove("whois away", (SIGNAL_FUNC) event_whois_away); + signal_remove("whois oper", (SIGNAL_FUNC) event_whois_oper); + signal_remove("whowas away", (SIGNAL_FUNC) event_whois_away); + signal_remove("whois default event", (SIGNAL_FUNC) event_whois_default); + signal_remove("event 318", (SIGNAL_FUNC) event_end_of_whois); + signal_remove("event 314", (SIGNAL_FUNC) event_whowas); + signal_remove("event 369", (SIGNAL_FUNC) event_end_of_whowas); +} |