diff options
Diffstat (limited to 'src/plugins/relay/irc/relay-irc.c')
-rw-r--r-- | src/plugins/relay/irc/relay-irc.c | 84 |
1 files changed, 56 insertions, 28 deletions
diff --git a/src/plugins/relay/irc/relay-irc.c b/src/plugins/relay/irc/relay-irc.c index 99fb0f32b..475f15ee0 100644 --- a/src/plugins/relay/irc/relay-irc.c +++ b/src/plugins/relay/irc/relay-irc.c @@ -1,7 +1,7 @@ /* * relay-irc.c - IRC protocol for relay to client: IRC proxy/bouncer * - * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org> + * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org> * * This file is part of WeeChat, the extensible chat client. * @@ -726,7 +726,8 @@ relay_irc_get_line_info (struct t_relay_client *client, && time_format && time_format[0]) { tm = localtime (&msg_date); - strftime (str_time, sizeof (str_time), time_format, tm); + if (strftime (str_time, sizeof (str_time), time_format, tm) == 0) + str_time[0] = '\0'; length = strlen (str_time) + strlen (pos) + 1; *message = malloc (length); if (*message) @@ -741,7 +742,8 @@ relay_irc_get_line_info (struct t_relay_client *client, && (RELAY_IRC_DATA(client, server_capabilities) & (1 << RELAY_IRC_CAPAB_SERVER_TIME))) { tm = gmtime (&msg_date); - strftime (str_time, sizeof (str_time), "%Y-%m-%dT%H:%M:%S", tm); + if (strftime (str_time, sizeof (str_time), "%Y-%m-%dT%H:%M:%S", tm) == 0) + str_time[0] = '\0'; snprintf (str_tag, sizeof (str_tag), "@time=%s.000Z ", str_time); *tags = strdup (str_tag); } @@ -906,6 +908,7 @@ relay_irc_send_channel_backlog (struct t_relay_client *client, (ptr_host) ? "!" : "", (ptr_host) ? ptr_host : "", channel); + break; case RELAY_IRC_CMD_QUIT: relay_irc_sendf (client, "%s:%s%s%s QUIT", @@ -1225,10 +1228,10 @@ relay_irc_hook_signals (struct t_relay_client *client) void relay_irc_recv_command_capab (struct t_relay_client *client, - int argc, char **argv) + int argc, char **argv, char **argv_eol) { - char str_capab[1024]; - int i, capability; + char str_capab[1024], *ptr_cap; + int i, capability, server_caps, num_caps_received, caps_ok; if (weechat_strcasecmp (argv[0], "ls") == 0) { @@ -1251,31 +1254,47 @@ relay_irc_recv_command_capab (struct t_relay_client *client, else if (weechat_strcasecmp (argv[0], "req") == 0) { /* client is asking for one or more server capabilities */ - str_capab[0] = '\0'; + num_caps_received = 0; + caps_ok = 0; + server_caps = RELAY_IRC_DATA(client, server_capabilities); for (i = 1; i < argc; i++) { - capability = relay_irc_search_server_capability ( - (argv[i][0] == ':') ? argv[i] + 1 : argv[i]); - if (capability >= 0) + ptr_cap = (argv[i][0] == ':') ? argv[i] + 1 : argv[i]; + if (ptr_cap[0]) { - if (str_capab[0]) - strcat (str_capab, " "); - strcat (str_capab, - relay_irc_server_capabilities[capability]); - RELAY_IRC_DATA(client, server_capabilities) |= 1 << capability; + num_caps_received++; + capability = relay_irc_search_server_capability (ptr_cap); + if (capability >= 0) + { + caps_ok = 1; + server_caps |= 1 << capability; + } + else + { + caps_ok = 0; + break; + } } } + if (caps_ok) + RELAY_IRC_DATA(client, server_capabilities) = server_caps; + relay_irc_sendf ( + client, + ":%s CAP %s %s :%s", + RELAY_IRC_DATA(client, address), + (RELAY_IRC_DATA(client, nick)) ? RELAY_IRC_DATA(client, nick) : "nick", + (caps_ok) ? "ACK" : "NAK", + (argc >= 2) ? ((argv_eol[1][0] == ':') ? argv_eol[1] + 1 : argv_eol[1]) : ""); + /* - * if at least one supported capability was enabled, send ACK to - * client + * if the CAP REQ command is received without arguments, we consider + * the CAP END is received; this is a workaround for clients like + * Atomic which are sending "CAP REQ :" (see issue #1040) */ - if (str_capab[0]) + if (num_caps_received == 0) { - relay_irc_sendf (client, - ":%s CAP %s ACK :%s", - RELAY_IRC_DATA(client, address), - (RELAY_IRC_DATA(client, nick)) ? RELAY_IRC_DATA(client, nick) : "nick", - str_capab); + if (!RELAY_IRC_DATA(client, connected)) + RELAY_IRC_DATA(client, cap_end_received) = 1; } } else if (weechat_strcasecmp (argv[0], "end") == 0) @@ -1293,7 +1312,7 @@ void relay_irc_recv (struct t_relay_client *client, const char *data) { char str_time[128], str_signal[128], str_server_channel[256]; - char str_command[128], *target, **irc_argv, *pos, *password; + char str_command[128], *target, **irc_argv, **irc_argv_eol, *pos, *password; const char *irc_command, *irc_channel, *irc_args, *irc_args2; int irc_argc, redirect_msg; const char *nick, *irc_is_channel, *isupport, *info, *pos_password; @@ -1302,6 +1321,7 @@ relay_irc_recv (struct t_relay_client *client, const char *data) hash_parsed = NULL; irc_argv = NULL; + irc_argv_eol = NULL; irc_argc = 0; /* display debug message */ @@ -1323,7 +1343,10 @@ relay_irc_recv (struct t_relay_client *client, const char *data) irc_channel = weechat_hashtable_get (hash_parsed, "channel"); irc_args = weechat_hashtable_get (hash_parsed, "arguments"); if (irc_args) + { irc_argv = weechat_string_split (irc_args, " ", 0, 0, &irc_argc); + irc_argv_eol = weechat_string_split (irc_args, " ", 1, 0, NULL); + } /* * first process the "nick" command (it will be processed again in this @@ -1341,8 +1364,11 @@ relay_irc_recv (struct t_relay_client *client, const char *data) /* server capabilities */ if (irc_command && (weechat_strcasecmp (irc_command, "cap") == 0)) { - if ((irc_argc > 0) && irc_argv) - relay_irc_recv_command_capab (client, irc_argc, irc_argv); + if (irc_argc > 0) + { + relay_irc_recv_command_capab (client, + irc_argc, irc_argv, irc_argv_eol); + } } /* if client is not yet "connected" */ if (!RELAY_IRC_DATA(client, connected)) @@ -1473,7 +1499,7 @@ relay_irc_recv (struct t_relay_client *client, const char *data) "weechat-relay-irc, running version %s", RELAY_IRC_DATA(client, address), RELAY_IRC_DATA(client, nick), - weechat_info_get("version", NULL)); + weechat_info_get ("version", NULL)); snprintf (str_time, sizeof (str_time), "%s", ctime (&client->listen_start_time)); if (str_time[0]) @@ -1488,7 +1514,7 @@ relay_irc_recv (struct t_relay_client *client, const char *data) RELAY_IRC_DATA(client, address), RELAY_IRC_DATA(client, nick), RELAY_IRC_DATA(client, address), - weechat_info_get("version", NULL)); + weechat_info_get ("version", NULL)); infolist_server = weechat_infolist_get ("irc_server", NULL, client->protocol_args); if (infolist_server) @@ -1733,6 +1759,8 @@ end: weechat_hashtable_free (hash_parsed); if (irc_argv) weechat_string_free_split (irc_argv); + if (irc_argv_eol) + weechat_string_free_split (irc_argv_eol); } /* |