diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2010-09-17 14:47:36 +0200 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2010-09-17 14:47:36 +0200 |
commit | d2d60d47110f49c3f4bb34c539da87222b76b9d4 (patch) | |
tree | 8943fca087668f8883ab2d77bddc05cb40f6a88d /src | |
parent | 26a99c2912a30e994117bae5e042e60b2c229a26 (diff) | |
download | weechat-d2d60d47110f49c3f4bb34c539da87222b76b9d4.zip |
Beta version of IRC proxy feature in Relay plugin
Major changes in Relay plugin:
- IRC proxy feature (beta),
- raw buffer.
Changes in IRC plugin:
- add tags for messages sent to servers,
- add signal "irc_input_send" to simulate text/command on an IRC buffer,
- add prefix in infolist "irc_nick".
Diffstat (limited to 'src')
30 files changed, 2112 insertions, 898 deletions
diff --git a/src/plugins/irc/irc-channel.c b/src/plugins/irc/irc-channel.c index 8b03cb291..e1708ef71 100644 --- a/src/plugins/irc/irc-channel.c +++ b/src/plugins/irc/irc-channel.c @@ -373,7 +373,7 @@ irc_channel_check_away (struct t_irc_server *server, || (channel->nicks_count <= weechat_config_integer (irc_config_network_away_check_max_nicks)))) { channel->checking_away++; - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_LOW, + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_LOW, NULL, "WHO %s", channel->name); } else diff --git a/src/plugins/irc/irc-command.c b/src/plugins/irc/irc-command.c index 3d6c786b0..b8db9e36b 100644 --- a/src/plugins/irc/irc-command.c +++ b/src/plugins/irc/irc-command.c @@ -74,7 +74,8 @@ irc_command_mode_nicks (struct t_irc_server *server, const char *channel, strcat (command, " "); strcat (command, argv[i]); } - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_LOW, "%s", command); + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_LOW, NULL, + "%s", command); free (command); } } @@ -96,11 +97,14 @@ irc_command_admin (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "ADMIN %s", argv_eol[1]); } else - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "ADMIN"); + { + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "ADMIN"); + } return WEECHAT_RC_OK; } @@ -339,7 +343,7 @@ irc_command_me_channel (struct t_irc_server *server, { char *string; - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PRIVMSG %s :\01ACTION %s\01", channel->name, (arguments && arguments[0]) ? arguments : ""); @@ -401,7 +405,7 @@ irc_command_away_server (struct t_irc_server *server, const char *arguments, { server->is_away = 1; server->away_time = time (NULL); - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "AWAY :%s", arguments); if (weechat_config_integer (irc_config_look_display_away) != IRC_CONFIG_DISPLAY_AWAY_OFF) { @@ -464,7 +468,8 @@ irc_command_away_server (struct t_irc_server *server, const char *arguments, /* if server is connected, send away command now */ if (server->is_connected) { - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "AWAY"); + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "AWAY"); server->is_away = 0; if (server->away_time != 0) { @@ -630,7 +635,7 @@ irc_command_ban (void *data, struct t_gui_buffer *buffer, int argc, /* loop on users */ while (argv[pos_args]) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "MODE %s +b %s", pos_channel, argv[pos_args]); pos_args++; @@ -646,7 +651,7 @@ irc_command_ban (void *data, struct t_gui_buffer *buffer, int argc, weechat_prefix ("error"), IRC_PLUGIN_NAME, "ban"); return WEECHAT_RC_OK; } - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "MODE %s +b", ptr_channel->name); } @@ -851,7 +856,7 @@ irc_command_ctcp (void *data, struct t_gui_buffer *buffer, int argc, gettimeofday (&tv, NULL); snprintf (str_time, sizeof (str_time), "%ld %ld", tv.tv_sec, tv.tv_usec); - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PRIVMSG %s :\01PING %s\01", argv[1], str_time); weechat_printf (ptr_server->buffer, @@ -868,7 +873,7 @@ irc_command_ctcp (void *data, struct t_gui_buffer *buffer, int argc, } else { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PRIVMSG %s :\01%s%s%s\01", argv[1], irc_cmd, @@ -984,14 +989,14 @@ irc_command_cycle (void *data, struct t_gui_buffer *buffer, int argc, { version = weechat_info_get ("version", ""); buf = weechat_string_replace (ptr_arg, "%v", (version) ? version : ""); - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PART %s :%s", channel_name, (buf) ? buf : ptr_arg); if (buf) free (buf); } else - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PART %s", channel_name); return WEECHAT_RC_OK; @@ -1129,7 +1134,7 @@ irc_command_dehalfop (void *data, struct t_gui_buffer *buffer, int argc, { if (argc < 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "MODE %s -h %s", ptr_channel->name, ptr_server->nick); @@ -1170,7 +1175,7 @@ irc_command_deop (void *data, struct t_gui_buffer *buffer, int argc, { if (argc < 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "MODE %s -o %s", ptr_channel->name, ptr_server->nick); @@ -1211,7 +1216,7 @@ irc_command_devoice (void *data, struct t_gui_buffer *buffer, int argc, { if (argc < 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "MODE %s -v %s", ptr_channel->name, ptr_server->nick); @@ -1250,7 +1255,7 @@ irc_command_die (void *data, struct t_gui_buffer *buffer, int argc, (void) argv; (void) argv_eol; - irc_server_sendf (ptr_server, 0, "DIE"); + irc_server_sendf (ptr_server, 0, NULL, "DIE"); return WEECHAT_RC_OK; } @@ -1280,13 +1285,13 @@ irc_command_quit_server (struct t_irc_server *server, const char *arguments) version = weechat_info_get ("version", ""); buf = weechat_string_replace (ptr_arg, "%v", (version) ? version : ""); - irc_server_sendf (server, 0, "QUIT :%s", + irc_server_sendf (server, 0, NULL, "QUIT :%s", (buf) ? buf : ptr_arg); if (buf) free (buf); } else - irc_server_sendf (server, 0, "QUIT"); + irc_server_sendf (server, 0, NULL, "QUIT"); } } @@ -1406,7 +1411,7 @@ irc_command_halfop (void *data, struct t_gui_buffer *buffer, int argc, { if (argc < 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "MODE %s +h %s", ptr_channel->name, ptr_server->nick); @@ -1633,12 +1638,12 @@ irc_command_info (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "INFO %s", argv_eol[1]); } else { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "INFO"); } @@ -1662,14 +1667,14 @@ irc_command_invite (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "INVITE %s %s", argv[1], argv[2]); } else { if (ptr_channel && (ptr_channel->type == IRC_CHANNEL_TYPE_CHANNEL)) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "INVITE %s %s", argv[1], ptr_channel->name); } @@ -1705,7 +1710,7 @@ irc_command_ison (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "ISON %s", argv_eol[1]); } else @@ -1725,12 +1730,12 @@ irc_command_join_server (struct t_irc_server *server, const char *arguments) { if (irc_channel_is_channel (arguments)) { - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "JOIN %s", arguments); } else { - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "JOIN #%s", arguments); } } @@ -1822,13 +1827,13 @@ irc_command_kick (void *data, struct t_gui_buffer *buffer, int argc, if (pos_comment) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "KICK %s %s :%s", pos_channel, pos_nick, pos_comment); } else { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "KICK %s %s", pos_channel, pos_nick); } @@ -1923,7 +1928,8 @@ irc_command_kickban (void *data, struct t_gui_buffer *buffer, int argc, pos = strchr (pos_nick, '!'); snprintf (mask, length, "*!%s", (pos) ? pos + 1 : pos_nick); - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, + IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "MODE %s +b %s", pos_channel, mask); free (mask); @@ -1931,13 +1937,14 @@ irc_command_kickban (void *data, struct t_gui_buffer *buffer, int argc, } else { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, + IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "MODE %s +b %s", pos_channel, pos_nick); } /* kick nick */ - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "KICK %s %s%s%s", pos_channel, nick_only, @@ -1970,7 +1977,7 @@ irc_command_kill (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "KILL %s :%s", argv[1], argv_eol[2]); } else @@ -1999,11 +2006,14 @@ irc_command_links (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "LINKS %s", argv_eol[1]); } else - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "LINKS"); + { + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "LINKS"); + } return WEECHAT_RC_OK; } @@ -2057,7 +2067,8 @@ irc_command_list (void *data, struct t_gui_buffer *buffer, int argc, } if (!ptr_channel_name && !ptr_server_name && !ptr_regex) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "LIST"); + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "LIST"); } else { @@ -2088,7 +2099,7 @@ irc_command_list (void *data, struct t_gui_buffer *buffer, int argc, return WEECHAT_RC_OK; } } - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "LIST%s%s%s%s", (ptr_channel_name) ? " " : "", (ptr_channel_name) ? ptr_channel_name : "", @@ -2097,7 +2108,10 @@ irc_command_list (void *data, struct t_gui_buffer *buffer, int argc, } } else - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "LIST"); + { + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "LIST"); + } return WEECHAT_RC_OK; } @@ -2119,11 +2133,14 @@ irc_command_lusers (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "LUSERS %s", argv_eol[1]); } else - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "LUSERS"); + { + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "LUSERS"); + } return WEECHAT_RC_OK; } @@ -2145,11 +2162,14 @@ irc_command_map (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "MAP %s", argv_eol[1]); } else - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "MAP"); + { + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "MAP"); + } return WEECHAT_RC_OK; } @@ -2195,13 +2215,13 @@ irc_command_mode_server (struct t_irc_server *server, { if (channel && arguments) { - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_LOW, + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_LOW, NULL, "MODE %s %s", channel->name, arguments); } else { - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_LOW, + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_LOW, NULL, "MODE %s", (channel) ? channel->name : arguments); } @@ -2269,11 +2289,14 @@ irc_command_motd (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "MOTD %s", argv_eol[1]); } else - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "MOTD"); + { + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "MOTD"); + } return WEECHAT_RC_OK; } @@ -2347,7 +2370,8 @@ irc_command_msg (void *data, struct t_gui_buffer *buffer, int argc, if (string) free (string); - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, + IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PRIVMSG %s :%s", ptr_channel->name, argv_eol[arg_text]); } @@ -2371,7 +2395,7 @@ irc_command_msg (void *data, struct t_gui_buffer *buffer, int argc, free (string); } irc_server_sendf (ptr_server, - IRC_SERVER_OUTQUEUE_PRIO_HIGH, + IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PRIVMSG %s :%s", targets[i], argv_eol[arg_text]); } @@ -2430,7 +2454,7 @@ irc_command_msg (void *data, struct t_gui_buffer *buffer, int argc, free (string); } irc_server_sendf (ptr_server, - IRC_SERVER_OUTQUEUE_PRIO_HIGH, + IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PRIVMSG %s :%s", targets[i], argv_eol[arg_text]); } @@ -2459,14 +2483,14 @@ irc_command_names (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "NAMES %s", argv_eol[1]); } else { if (ptr_channel && (ptr_channel->type == IRC_CHANNEL_TYPE_CHANNEL)) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "NAMES %s", ptr_channel->name); } else @@ -2495,7 +2519,7 @@ irc_send_nick_server (struct t_irc_server *server, const char *nickname) if (server->is_connected) { - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "NICK %s", nickname); } else @@ -2579,9 +2603,11 @@ irc_command_notice (void *data, struct t_gui_buffer *buffer, int argc, weechat_config_boolean (irc_config_network_colors_receive)); ptr_channel = irc_channel_search (ptr_server, argv[arg_nick]); weechat_printf ((ptr_channel) ? ptr_channel->buffer : ptr_server->buffer, - "%s%sNotice%s -> %s%s%s: %s", + "%s%s%s%s -> %s%s%s: %s", weechat_prefix ("network"), IRC_COLOR_NOTICE, + /* TRANSLATORS: "Notice" is command name in IRC protocol (translation is frequently the same word) */ + _("Notice"), IRC_COLOR_CHAT, (irc_channel_is_channel (argv[arg_nick])) ? IRC_COLOR_CHAT_CHANNEL : IRC_COLOR_CHAT_NICK, @@ -2590,7 +2616,7 @@ irc_command_notice (void *data, struct t_gui_buffer *buffer, int argc, (string) ? string : argv_eol[arg_text]); if (string) free (string); - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "NOTICE %s :%s", argv[arg_nick], argv_eol[arg_text]); } @@ -2622,7 +2648,7 @@ irc_command_op (void *data, struct t_gui_buffer *buffer, int argc, char **argv, { if (argc < 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "MODE %s +o %s", ptr_channel->name, ptr_server->nick); @@ -2661,7 +2687,7 @@ irc_command_oper (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "OPER %s", argv_eol[1]); } else @@ -2693,7 +2719,8 @@ irc_command_part_channel (struct t_irc_server *server, const char *channel_name, { version = weechat_info_get ("version", ""); buf = weechat_string_replace (ptr_arg, "%v", (version) ? version : ""); - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "PART %s :%s", + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "PART %s :%s", channel_name, (buf) ? buf : ptr_arg); if (buf) @@ -2701,7 +2728,7 @@ irc_command_part_channel (struct t_irc_server *server, const char *channel_name, } else { - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PART %s", channel_name); } } @@ -2787,7 +2814,7 @@ irc_command_ping (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PING %s", argv_eol[1]); } else @@ -2815,7 +2842,7 @@ irc_command_pong (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PONG %s", argv_eol[1]); } else @@ -2883,7 +2910,7 @@ irc_command_query (void *data, struct t_gui_buffer *buffer, int argc, (string) ? string : argv_eol[arg_text]); if (string) free (string); - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PRIVMSG %s :%s", argv[arg_nick], argv_eol[arg_text]); } @@ -2909,7 +2936,7 @@ irc_command_quote (void *data, struct t_gui_buffer *buffer, int argc, /* make C compiler happy */ (void) data; - + if (argc > 1) { if ((argc >= 4) && (weechat_strcasecmp (argv[1], "-server") == 0)) @@ -2917,14 +2944,14 @@ irc_command_quote (void *data, struct t_gui_buffer *buffer, int argc, ptr_server = irc_server_search (argv[2]); if (!ptr_server || (ptr_server->sock < 0)) return WEECHAT_RC_ERROR; - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "%s", argv_eol[3]); } else { if (!ptr_server || (ptr_server->sock < 0)) return WEECHAT_RC_ERROR; - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "%s", argv_eol[1]); } } @@ -3065,11 +3092,14 @@ irc_command_rehash (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "REHASH %s", argv_eol[1]); } else - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "REHASH"); + { + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "REHASH"); + } return WEECHAT_RC_OK; } @@ -3091,7 +3121,8 @@ irc_command_restart (void *data, struct t_gui_buffer *buffer, int argc, (void) argv; (void) argv_eol; - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "RESTART"); + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "RESTART"); return WEECHAT_RC_OK; } @@ -3112,7 +3143,7 @@ irc_command_sajoin (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "SAJOIN %s %s", argv[1], argv_eol[2]); } else @@ -3139,7 +3170,7 @@ irc_command_samode (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "SAMODE %s %s", argv[1], argv_eol[2]); } else @@ -3166,7 +3197,7 @@ irc_command_sanick (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "SANICK %s %s", argv[1], argv_eol[2]); } else @@ -3193,7 +3224,7 @@ irc_command_sapart (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "SAPART %s %s", argv[1], argv_eol[2]); } else @@ -3220,7 +3251,7 @@ irc_command_saquit (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "SAQUIT %s :%s", argv[1], argv_eol[2]); } else @@ -3596,7 +3627,7 @@ irc_command_service (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "SERVICE %s", argv_eol[1]); } else @@ -3624,12 +3655,12 @@ irc_command_servlist (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "SERVLIST %s", argv_eol[1]); } else { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "SERVLIST"); } @@ -3654,12 +3685,12 @@ irc_command_squery (void *data, struct t_gui_buffer *buffer, int argc, { if (argc > 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "SQUERY %s :%s", argv[1], argv_eol[2]); } else { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "SQUERY %s", argv_eol[1]); } } @@ -3687,7 +3718,7 @@ irc_command_squit (void *data, struct t_gui_buffer *buffer, int argc, (void) argv; if (argc > 1) - irc_server_sendf (ptr_server, 0, "SQUIT %s", argv_eol[1]); + irc_server_sendf (ptr_server, 0, NULL, "SQUIT %s", argv_eol[1]); else { IRC_COMMAND_TOO_FEW_ARGUMENTS(ptr_server->buffer, "squit"); @@ -3713,11 +3744,14 @@ irc_command_stats (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "STATS %s", argv_eol[1]); } else - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "STATS"); + { + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "STATS"); + } return WEECHAT_RC_OK; } @@ -3740,7 +3774,7 @@ irc_command_summon (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "SUMMON %s", argv_eol[1]); } else @@ -3768,11 +3802,14 @@ irc_command_time (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "TIME %s", argv_eol[1]); } else - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "TIME"); + { + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "TIME"); + } return WEECHAT_RC_OK; } @@ -3827,13 +3864,13 @@ irc_command_topic (void *data, struct t_gui_buffer *buffer, int argc, if (new_topic) { if (weechat_strcasecmp (new_topic, "-delete") == 0) - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "TOPIC %s :", channel_name); else { new_topic_color = irc_color_encode (new_topic, weechat_config_boolean (irc_config_network_colors_send)); - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "TOPIC %s :%s", channel_name, (new_topic_color) ? new_topic_color : new_topic); @@ -3842,7 +3879,7 @@ irc_command_topic (void *data, struct t_gui_buffer *buffer, int argc, } } else - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "TOPIC %s", channel_name); return WEECHAT_RC_OK; @@ -3865,11 +3902,14 @@ irc_command_trace (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "TRACE %s", argv_eol[1]); } else - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "TRACE"); + { + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "TRACE"); + } return WEECHAT_RC_OK; } @@ -3924,7 +3964,7 @@ irc_command_unban (void *data, struct t_gui_buffer *buffer, int argc, /* loop on users */ while (argv[pos_args]) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "MODE %s -b %s", pos_channel, argv[pos_args]); pos_args++; @@ -3958,7 +3998,7 @@ irc_command_userhost (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "USERHOST %s", argv_eol[1]); } else @@ -3986,11 +4026,14 @@ irc_command_users (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "USERS %s", argv_eol[1]); } else - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "USERS"); + { + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "USERS"); + } return WEECHAT_RC_OK; } @@ -4016,18 +4059,18 @@ irc_command_version (void *data, struct t_gui_buffer *buffer, int argc, if (ptr_channel && (ptr_channel->type == IRC_CHANNEL_TYPE_CHANNEL) && irc_nick_search (ptr_channel, argv[1])) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PRIVMSG %s :\01VERSION\01", argv[1]); } else { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "VERSION %s", argv[1]); } } else { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "VERSION"); } @@ -4053,7 +4096,7 @@ irc_command_voice (void *data, struct t_gui_buffer *buffer, int argc, { if (argc < 2) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "MODE %s +v %s", ptr_channel->name, ptr_server->nick); @@ -4133,9 +4176,11 @@ irc_command_wallchops (void *data, struct t_gui_buffer *buffer, int argc, } weechat_printf (ptr_channel->buffer, - "%s%sNoticeOp%s -> %s%s%s: %s", + "%s%s%sOp%s -> %s%s%s: %s", weechat_prefix ("network"), IRC_COLOR_NOTICE, + /* TRANSLATORS: "Notice" is command name in IRC protocol (translation is frequently the same word) */ + _("Notice"), IRC_COLOR_CHAT, IRC_COLOR_CHAT_CHANNEL, ptr_channel->name, @@ -4153,7 +4198,7 @@ irc_command_wallchops (void *data, struct t_gui_buffer *buffer, int argc, * if WALLCHOPS is supported, or if STATUSMSG includes '@', * then send a notice to @#channel */ - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "NOTICE @%s :%s", ptr_channel->name, argv_eol[pos_args]); } @@ -4169,7 +4214,8 @@ irc_command_wallchops (void *data, struct t_gui_buffer *buffer, int argc, if (IRC_NICK_IS_OP(ptr_nick) && (strcmp (ptr_nick->name, ptr_server->nick) != 0)) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_LOW, + irc_server_sendf (ptr_server, + IRC_SERVER_SEND_OUTQ_PRIO_LOW, NULL, "NOTICE %s :%s", ptr_nick->name, argv_eol[pos_args]); } @@ -4202,7 +4248,7 @@ irc_command_wallops (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "WALLOPS :%s", argv_eol[1]); } else @@ -4230,11 +4276,14 @@ irc_command_who (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "WHO %s", argv_eol[1]); } else - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, "WHO"); + { + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, + "WHO"); + } return WEECHAT_RC_OK; } @@ -4256,7 +4305,7 @@ irc_command_whois (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "WHOIS %s", argv_eol[1]); } else @@ -4264,7 +4313,7 @@ irc_command_whois (void *data, struct t_gui_buffer *buffer, int argc, if (ptr_channel && (ptr_channel->type == IRC_CHANNEL_TYPE_PRIVATE)) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "WHOIS %s", ptr_channel->name); } else @@ -4293,7 +4342,7 @@ irc_command_whowas (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "WHOWAS %s", argv_eol[1]); } else @@ -4687,7 +4736,7 @@ irc_command_init () N_("send raw data to server without parsing"), N_("[-server server] data"), N_("server: send to this server (internal name)\n" - "data: raw data to send"), + " data: raw data to send"), NULL, &irc_command_quote, NULL); weechat_hook_command ("reconnect", N_("reconnect to server(s)"), diff --git a/src/plugins/irc/irc-config.c b/src/plugins/irc/irc-config.c index 3f2695567..61bf79b43 100644 --- a/src/plugins/irc/irc-config.c +++ b/src/plugins/irc/irc-config.c @@ -1705,8 +1705,8 @@ irc_config_init () irc_config_look_raw_messages = weechat_config_new_option ( irc_config_file, ptr_section, "raw_messages", "integer", - N_("number of IRC raw messages to save in memory when raw data buffer " - "is closed (messages will be displayed when opening raw data buffer)"), + N_("number of raw messages to save in memory when raw data buffer is " + "closed (messages will be displayed when opening raw data buffer)"), NULL, 0, 65535, "256", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL); irc_config_look_smart_filter = weechat_config_new_option ( irc_config_file, ptr_section, diff --git a/src/plugins/irc/irc-ctcp.c b/src/plugins/irc/irc-ctcp.c index 26f264bb4..9aa12359f 100644 --- a/src/plugins/irc/irc-ctcp.c +++ b/src/plugins/irc/irc-ctcp.c @@ -249,7 +249,7 @@ irc_ctcp_reply_to_nick (struct t_irc_server *server, const char *nick, const char *ctcp, const char *arguments) { - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_LOW, + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_LOW, NULL, "NOTICE %s :\01%s%s%s\01", nick, ctcp, (arguments) ? " " : "", diff --git a/src/plugins/irc/irc-info.c b/src/plugins/irc/irc-info.c index 3a6c8849a..0026954c0 100644 --- a/src/plugins/irc/irc-info.c +++ b/src/plugins/irc/irc-info.c @@ -407,7 +407,9 @@ irc_info_get_infolist_cb (void *data, const char *infolist_name, if (pointer) { /* build list with only one nick */ - if (!irc_nick_add_to_infolist (ptr_infolist, pointer)) + if (!irc_nick_add_to_infolist (ptr_infolist, + ptr_server, + pointer)) { weechat_infolist_free (ptr_infolist); return NULL; @@ -421,6 +423,7 @@ irc_info_get_infolist_cb (void *data, const char *infolist_name, ptr_nick = ptr_nick->next_nick) { if (!irc_nick_add_to_infolist (ptr_infolist, + ptr_server, ptr_nick)) { weechat_infolist_free (ptr_infolist); diff --git a/src/plugins/irc/irc-input.c b/src/plugins/irc/irc-input.c index 71a190aeb..7f2e445d9 100644 --- a/src/plugins/irc/irc-input.c +++ b/src/plugins/irc/irc-input.c @@ -73,21 +73,22 @@ irc_input_user_message_display (struct t_gui_buffer *buffer, const char *text) } /* - * irc_input_send_user_message: send a PRIVMSG message, and split it - * if > 512 bytes - * warning: this function makes temporarirly - * changes in "text" + * irc_input_send_user_message: send a PRIVMSG message, and split it it message + * size is > 512 bytes + * Warning: this function makes temporarirly + * changes in "message" */ void -irc_input_send_user_message (struct t_gui_buffer *buffer, char *text) +irc_input_send_user_message (struct t_gui_buffer *buffer, int flags, + const char *tags, char *message) { int max_length; char *pos, *pos_max, *last_space, *pos_next, *next, saved_char; IRC_BUFFER_GET_SERVER_CHANNEL(buffer); - if (!ptr_server || !ptr_channel || !text || !text[0]) + if (!ptr_server || !ptr_channel || !message || !message[0]) return; if (!ptr_server->is_connected) @@ -107,10 +108,10 @@ irc_input_send_user_message (struct t_gui_buffer *buffer, char *text) if (max_length > 0) { - if ((int)strlen (text) > max_length) + if ((int)strlen (message) > max_length) { - pos = text; - pos_max = text + max_length; + pos = message; + pos_max = message + max_length; while (pos && pos[0]) { if (pos[0] == ' ') @@ -128,14 +129,14 @@ irc_input_send_user_message (struct t_gui_buffer *buffer, char *text) } } - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, - "PRIVMSG %s :%s", ptr_channel->name, text); - irc_input_user_message_display (buffer, text); + irc_server_sendf (ptr_server, flags, tags, + "PRIVMSG %s :%s", ptr_channel->name, message); + irc_input_user_message_display (buffer, message); if (next) { next[0] = saved_char; - irc_input_send_user_message (buffer, next); + irc_input_send_user_message (buffer, flags, tags, next); } } @@ -170,7 +171,8 @@ irc_input_data_cb (void *data, struct t_gui_buffer *buffer, && !weechat_string_input_for_buffer (input_data)) { if (ptr_server) - irc_server_sendf (ptr_server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (ptr_server, + IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, weechat_utf8_next_char (input_data)); return WEECHAT_RC_OK; } @@ -186,7 +188,10 @@ irc_input_data_cb (void *data, struct t_gui_buffer *buffer, msg = strdup ((data_with_colors) ? data_with_colors : ptr_data); if (msg) { - irc_input_send_user_message (buffer, msg); + irc_input_send_user_message (buffer, + IRC_SERVER_SEND_OUTQ_PRIO_HIGH, + NULL, + msg); free (msg); } @@ -203,3 +208,141 @@ irc_input_data_cb (void *data, struct t_gui_buffer *buffer, return WEECHAT_RC_OK; } + +/* + * irc_input_send_cb: callback for "irc_input_send" signal + * This signal can be used by other plugins/scripts, it + * simulates input or command from user on an IRC buffer + * (it is used for example by Relay plugin) + * Format of signal_data (string) is: + * "server;channel;flags;tags;text" + * - server: server name (required) + * - channel: channel name (optional) + * - flags: flags for irc_server_sendf() (optional) + * - tags: tags for irc_server_sendf() (optional) + * - text: text or command (required) + */ + +int +irc_input_send_cb (void *data, const char *signal, + const char *type_data, void *signal_data) +{ + const char *ptr_string, *ptr_message; + char *pos_semicol1, *pos_semicol2, *pos_semicol3, *pos_semicol4, *error; + char *server, *channel, *flags, *tags; + long flags_value; + char *data_with_colors; + struct t_irc_server *ptr_server; + struct t_irc_channel *ptr_channel; + struct t_gui_buffer *ptr_buffer; + + /* make C compiler happy */ + (void) data; + (void) signal; + (void) type_data; + + ptr_string = (const char *)signal_data; + + server = NULL; + channel = NULL; + flags = NULL; + tags = NULL; + ptr_message = NULL; + ptr_server = NULL; + ptr_channel = NULL; + + pos_semicol1 = strchr (ptr_string, ';'); + if (pos_semicol1) + { + if (pos_semicol1 > ptr_string + 1) + { + server = weechat_strndup (ptr_string, pos_semicol1 - ptr_string); + } + pos_semicol2 = strchr (pos_semicol1 + 1, ';'); + if (pos_semicol2) + { + if (pos_semicol2 > pos_semicol1 + 1) + { + channel = weechat_strndup (pos_semicol1 + 1, + pos_semicol2 - pos_semicol1 - 1); + } + pos_semicol3 = strchr (pos_semicol2 + 1, ';'); + if (pos_semicol3) + { + if (pos_semicol3 > pos_semicol2 + 1) + { + flags = weechat_strndup (pos_semicol2 + 1, + pos_semicol3 - pos_semicol2 - 1); + } + pos_semicol4 = strchr (pos_semicol3 + 1, ';'); + if (pos_semicol4) + { + if (pos_semicol4 > pos_semicol3 + 1) + { + tags = weechat_strndup (pos_semicol3 + 1, + pos_semicol4 - pos_semicol3 - 1); + } + ptr_message = pos_semicol4 + 1; + } + } + } + } + + flags_value = 0; + if (flags) + { + error = NULL; + flags_value = strtol (flags, &error, 10); + if (flags_value < 0) + flags_value = 0; + } + + if (server && ptr_message) + { + ptr_server = irc_server_search (server); + if (ptr_server) + { + ptr_buffer = ptr_server->buffer; + if (channel) + { + ptr_channel = irc_channel_search (ptr_server, channel); + if (ptr_channel) + ptr_buffer = ptr_channel->buffer; + } + + /* set tags to use by default */ + irc_server_set_send_default_tags (tags); + + /* send text to buffer, or execute command */ + if (weechat_string_input_for_buffer (ptr_message)) + { + /* text as input */ + irc_input_data_cb (NULL, ptr_buffer, ptr_message); + } + else + { + /* command */ + data_with_colors = irc_color_encode (ptr_message, + weechat_config_boolean (irc_config_network_colors_send)); + weechat_command (ptr_buffer, + (data_with_colors) ? data_with_colors : ptr_message); + if (data_with_colors) + free (data_with_colors); + } + + /* reset tags to use by default */ + irc_server_set_send_default_tags (NULL); + } + } + + if (server) + free (server); + if (channel) + free (channel); + if (flags) + free (flags); + if (tags) + free (tags); + + return WEECHAT_RC_OK; +} diff --git a/src/plugins/irc/irc-input.h b/src/plugins/irc/irc-input.h index 8a8dd61e4..b508a8149 100644 --- a/src/plugins/irc/irc-input.h +++ b/src/plugins/irc/irc-input.h @@ -26,5 +26,7 @@ extern void irc_input_user_message_display (struct t_gui_buffer *buffer, const char *text); extern int irc_input_data_cb (void *data, struct t_gui_buffer *buffer, const char *input_data); +extern int irc_input_send_cb (void *data, const char *signal, + const char *type_data, void *signal_data); #endif /* __WEECHAT_IRC_INPUT_H */ diff --git a/src/plugins/irc/irc-nick.c b/src/plugins/irc/irc-nick.c index a9e5110af..c2540623c 100644 --- a/src/plugins/irc/irc-nick.c +++ b/src/plugins/irc/irc-nick.c @@ -741,9 +741,11 @@ irc_nick_color_for_pv (struct t_irc_channel *channel, const char *nickname) int irc_nick_add_to_infolist (struct t_infolist *infolist, + struct t_irc_server *server, struct t_irc_nick *nick) { struct t_infolist_item *ptr_item; + char prefix[2]; if (!infolist || !nick) return 0; @@ -760,6 +762,11 @@ irc_nick_add_to_infolist (struct t_infolist *infolist, return 0; if (!weechat_infolist_new_var_string (ptr_item, "color", nick->color)) return 0; + prefix[0] = ' '; + prefix[1] = '\0'; + irc_nick_get_gui_infos (server, nick, prefix, NULL, NULL, NULL); + if (!weechat_infolist_new_var_string (ptr_item, "prefix", prefix)) + return 0; return 1; } diff --git a/src/plugins/irc/irc-nick.h b/src/plugins/irc/irc-nick.h index 1b05d85eb..9dffce6ea 100644 --- a/src/plugins/irc/irc-nick.h +++ b/src/plugins/irc/irc-nick.h @@ -114,6 +114,7 @@ extern char *irc_nick_as_prefix (struct t_irc_server *server, extern const char * irc_nick_color_for_pv (struct t_irc_channel *channel, const char *nickname); extern int irc_nick_add_to_infolist (struct t_infolist *infolist, + struct t_irc_server *server, struct t_irc_nick *nick); extern void irc_nick_print_log (struct t_irc_nick *nick); diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index c13152912..884d1d6d5 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -310,7 +310,7 @@ IRC_PROTOCOL_CALLBACK(authenticate) } if (answer) { - irc_server_sendf (server, 0, "AUTHENTICATE %s", answer); + irc_server_sendf (server, 0, NULL, "AUTHENTICATE %s", answer); free (answer); } else @@ -320,7 +320,7 @@ IRC_PROTOCOL_CALLBACK(authenticate) "SASL authentication, using mechanism \"%s\""), weechat_prefix ("error"), IRC_PLUGIN_NAME, irc_sasl_mechanism_string[IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_SASL_MECHANISM)]); - irc_server_sendf (server, 0, "CAP END"); + irc_server_sendf (server, 0, NULL, "CAP END"); } } @@ -375,7 +375,7 @@ IRC_PROTOCOL_CALLBACK(cap) _("%s%s: client capability, requesting: sasl"), weechat_prefix ("network"), IRC_PLUGIN_NAME); - irc_server_sendf (server, 0, "CAP REQ :sasl"); + irc_server_sendf (server, 0, NULL, "CAP REQ :sasl"); } else { @@ -383,7 +383,7 @@ IRC_PROTOCOL_CALLBACK(cap) _("%s%s: client capability: sasl not supported"), weechat_prefix ("network"), IRC_PLUGIN_NAME); - irc_server_sendf (server, 0, "CAP END"); + irc_server_sendf (server, 0, NULL, "CAP END"); } } } @@ -403,7 +403,8 @@ IRC_PROTOCOL_CALLBACK(cap) { case IRC_SASL_MECHANISM_DH_BLOWFISH: #ifdef HAVE_GCRYPT - irc_server_sendf (server, 0, "AUTHENTICATE DH-BLOWFISH"); + irc_server_sendf (server, 0, NULL, + "AUTHENTICATE DH-BLOWFISH"); #else weechat_printf (server->buffer, _("%s%s: cannot authenticate with SASL " @@ -412,12 +413,13 @@ IRC_PROTOCOL_CALLBACK(cap) "libgcrypt support"), weechat_prefix ("error"), IRC_PLUGIN_NAME); - irc_server_sendf (server, 0, "CAP END"); + irc_server_sendf (server, 0, NULL, "CAP END"); #endif break; case IRC_SASL_MECHANISM_PLAIN: default: - irc_server_sendf (server, 0, "AUTHENTICATE PLAIN"); + irc_server_sendf (server, 0, NULL, + "AUTHENTICATE PLAIN"); break; } if (server->hook_timer_sasl) @@ -441,7 +443,7 @@ IRC_PROTOCOL_CALLBACK(cap) weechat_prefix ("error"), IRC_PLUGIN_NAME, ptr_caps); if (!server->is_connected) - irc_server_sendf (server, 0, "CAP END"); + irc_server_sendf (server, 0, NULL, "CAP END"); } } @@ -831,7 +833,7 @@ IRC_PROTOCOL_CALLBACK(mode) { if (irc_mode_channel_set (server, ptr_channel, pos_modes)) { - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_LOW, + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_LOW, NULL, "MODE %s", ptr_channel->name); } } @@ -1049,9 +1051,11 @@ IRC_PROTOCOL_CALLBACK(notice) ptr_nick = irc_nick_search (ptr_channel, nick); weechat_printf_tags ((ptr_channel) ? ptr_channel->buffer : server->buffer, irc_protocol_tags (command, "notify_message"), - "%s%sNotice%s%s(%s%s%s)%s: %s", + "%s%s%s%s%s(%s%s%s)%s: %s", weechat_prefix ("network"), IRC_COLOR_NOTICE, + /* TRANSLATORS: "Notice" is command name in IRC protocol (translation is frequently the same word) */ + _("Notice"), (notice_op) ? "Op" : "", IRC_COLOR_CHAT_DELIMITERS, IRC_COLOR_NICK_IN_SERVER_MESSAGE(ptr_nick), @@ -1116,44 +1120,67 @@ IRC_PROTOCOL_CALLBACK(notice) ptr_buffer = irc_msgbuffer_get_target_buffer (server, nick, command, NULL, NULL); - if (address && address[0]) + /* + * if notice is sent from myself (for example another WeeChat + * via relay), then display message of outgoing notice + */ + if (nick && strcmp (server->nick, nick) == 0) { weechat_printf_tags (ptr_buffer, irc_protocol_tags (command, (notify_private) ? "notify_private" : NULL), - "%s%s%s %s(%s%s%s)%s: %s", + "%s%s%s%s -> %s%s%s: %s", weechat_prefix ("network"), + IRC_COLOR_NOTICE, + /* TRANSLATORS: "Notice" is command name in IRC protocol (translation is frequently the same word) */ + _("Notice"), + IRC_COLOR_CHAT, IRC_COLOR_CHAT_NICK, - nick, - IRC_COLOR_CHAT_DELIMITERS, - IRC_COLOR_CHAT_HOST, - address, - IRC_COLOR_CHAT_DELIMITERS, + pos_target, IRC_COLOR_CHAT, pos_args); } else { - if (nick && nick[0]) + if (address && address[0]) { weechat_printf_tags (ptr_buffer, irc_protocol_tags (command, (notify_private) ? "notify_private" : NULL), - "%s%s%s%s: %s", + "%s%s%s %s(%s%s%s)%s: %s", weechat_prefix ("network"), IRC_COLOR_CHAT_NICK, nick, + IRC_COLOR_CHAT_DELIMITERS, + IRC_COLOR_CHAT_HOST, + address, + IRC_COLOR_CHAT_DELIMITERS, IRC_COLOR_CHAT, pos_args); } else { - weechat_printf_tags (ptr_buffer, - irc_protocol_tags (command, - (notify_private) ? "notify_private" : NULL), - "%s%s", - weechat_prefix ("network"), - pos_args); + if (nick && nick[0]) + { + weechat_printf_tags (ptr_buffer, + irc_protocol_tags (command, + (notify_private) ? "notify_private" : NULL), + "%s%s%s%s: %s", + weechat_prefix ("network"), + IRC_COLOR_CHAT_NICK, + nick, + IRC_COLOR_CHAT, + pos_args); + } + else + { + weechat_printf_tags (ptr_buffer, + irc_protocol_tags (command, + (notify_private) ? "notify_private" : NULL), + "%s%s", + weechat_prefix ("network"), + pos_args); + } } } } @@ -1322,7 +1349,7 @@ IRC_PROTOCOL_CALLBACK(ping) IRC_PROTOCOL_MIN_ARGS(2); - irc_server_sendf (server, 0, "PONG :%s", + irc_server_sendf (server, 0, NULL, "PONG :%s", (argv[1][0] == ':') ? argv[1] + 1 : argv[1]); return WEECHAT_RC_OK; @@ -1438,10 +1465,9 @@ IRC_PROTOCOL_CALLBACK(privmsg) } else { - if (strcmp (server->nick, nick) == 0) - remote_nick = argv[2]; - else - remote_nick = nick; + nick_is_me = (strcmp (server->nick, nick) == 0); + + remote_nick = (nick_is_me) ? argv[2] : nick; /* CTCP to user */ if ((pos_args[0] == '\01') @@ -1454,8 +1480,6 @@ IRC_PROTOCOL_CALLBACK(privmsg) } /* private message received => display it */ - nick_is_me = (strcmp (server->nick, nick) == 0); - ptr_channel = irc_channel_search (server, remote_nick); if (!ptr_channel) @@ -3844,7 +3868,7 @@ IRC_PROTOCOL_CALLBACK(432) irc_server_set_nick (server, server->nicks_array[nick_index]); - irc_server_sendf (server, 0, "NICK %s", server->nick); + irc_server_sendf (server, 0, NULL, "NICK %s", server->nick); } return WEECHAT_RC_OK; @@ -3895,7 +3919,7 @@ IRC_PROTOCOL_CALLBACK(433) irc_server_set_nick (server, server->nicks_array[nick_index]); - irc_server_sendf (server, 0, "NICK %s", server->nick); + irc_server_sendf (server, 0, NULL, "NICK %s", server->nick); } else { @@ -3960,7 +3984,7 @@ IRC_PROTOCOL_CALLBACK(437) irc_server_set_nick (server, server->nicks_array[nick_index]); - irc_server_sendf (server, 0, "NICK %s", server->nick); + irc_server_sendf (server, 0, NULL, "NICK %s", server->nick); } } @@ -4088,7 +4112,7 @@ IRC_PROTOCOL_CALLBACK(sasl_end) ignored, argc, argv, argv_eol); if (!server->is_connected) - irc_server_sendf (server, 0, "CAP END"); + irc_server_sendf (server, 0, NULL, "CAP END"); return WEECHAT_RC_OK; } @@ -4289,11 +4313,15 @@ irc_protocol_recv_command (struct t_irc_server *server, nick, host); /* send signal with received command, even if command is ignored */ - irc_server_send_signal (server, "irc_raw_in", msg_command, irc_message); + irc_server_send_signal (server, "irc_raw_in", msg_command, + irc_message, NULL); /* send signal with received command, only if message is not ignored */ if (!message_ignored) - irc_server_send_signal (server, "irc_in", msg_command, irc_message); + { + irc_server_send_signal (server, "irc_in", msg_command, + irc_message, NULL); + } /* look for IRC command */ cmd_found = -1; @@ -4369,11 +4397,15 @@ irc_protocol_recv_command (struct t_irc_server *server, /* send signal with received command (if message is not ignored) */ if (!message_ignored) - irc_server_send_signal (server, "irc_in2", msg_command, irc_message); + { + irc_server_send_signal (server, "irc_in2", msg_command, + irc_message, NULL); + } } /* send signal with received command, even if command is ignored */ - irc_server_send_signal (server, "irc_raw_in2", msg_command, irc_message); + irc_server_send_signal (server, "irc_raw_in2", msg_command, + irc_message, NULL); end: if (nick) diff --git a/src/plugins/irc/irc-raw.c b/src/plugins/irc/irc-raw.c index 2a8d91fff..d2e5764e4 100644 --- a/src/plugins/irc/irc-raw.c +++ b/src/plugins/irc/irc-raw.c @@ -67,9 +67,6 @@ void irc_raw_open (int switch_to_buffer) { struct t_irc_raw_message *ptr_raw_message; - int buffer_created; - - buffer_created = 0; if (!irc_raw_buffer) { @@ -80,30 +77,23 @@ irc_raw_open (int switch_to_buffer) irc_raw_buffer = weechat_buffer_new (IRC_RAW_BUFFER_NAME, &irc_input_data_cb, NULL, &irc_buffer_close_cb, NULL); - buffer_created = 1; /* failed to create buffer ? then return */ if (!irc_raw_buffer) return; - - if (buffer_created) - { - weechat_buffer_set (irc_raw_buffer, - "title", _("IRC raw messages")); - - weechat_buffer_set (irc_raw_buffer, "short_name", IRC_RAW_BUFFER_NAME); - weechat_buffer_set (irc_raw_buffer, "localvar_set_type", "debug"); - weechat_buffer_set (irc_raw_buffer, "localvar_set_server", IRC_RAW_BUFFER_NAME); - weechat_buffer_set (irc_raw_buffer, "localvar_set_channel", IRC_RAW_BUFFER_NAME); - weechat_buffer_set (irc_raw_buffer, "localvar_set_no_log", "1"); - - /* disable all highlights on this debug buffer */ - weechat_buffer_set (irc_raw_buffer, "highlight_words", "-"); - } - if (switch_to_buffer) - weechat_buffer_set (irc_raw_buffer, "display", "1"); + weechat_buffer_set (irc_raw_buffer, + "title", _("IRC raw messages")); + + weechat_buffer_set (irc_raw_buffer, "short_name", IRC_RAW_BUFFER_NAME); + weechat_buffer_set (irc_raw_buffer, "localvar_set_type", "debug"); + weechat_buffer_set (irc_raw_buffer, "localvar_set_server", IRC_RAW_BUFFER_NAME); + weechat_buffer_set (irc_raw_buffer, "localvar_set_channel", IRC_RAW_BUFFER_NAME); + weechat_buffer_set (irc_raw_buffer, "localvar_set_no_log", "1"); + /* disable all highlights on this buffer */ + weechat_buffer_set (irc_raw_buffer, "highlight_words", "-"); + /* print messages in list */ for (ptr_raw_message = irc_raw_messages; ptr_raw_message; ptr_raw_message = ptr_raw_message->next_message) @@ -112,11 +102,9 @@ irc_raw_open (int switch_to_buffer) } } } - else - { - if (switch_to_buffer) - weechat_buffer_set (irc_raw_buffer, "display", "1"); - } + + if (irc_raw_buffer && switch_to_buffer) + weechat_buffer_set (irc_raw_buffer, "display", "1"); } /* @@ -283,7 +271,7 @@ irc_raw_message_add (struct t_irc_server *server, int send, int modified, } /* - * irc_raw_print: print a message on IRC debug buffer + * irc_raw_print: print a message on IRC raw buffer */ void @@ -294,7 +282,8 @@ irc_raw_print (struct t_irc_server *server, int send, int modified, if (!message) return; - + + /* auto-open IRC raw buffer if debug for irc plugin is >= 1 */ if (!irc_raw_buffer && (weechat_irc_plugin->debug >= 1)) irc_raw_open (0); @@ -309,7 +298,7 @@ irc_raw_print (struct t_irc_server *server, int send, int modified, } /* - * irc_raw_add_to_infolist: add a raw messagt in an infolist + * irc_raw_add_to_infolist: add a raw message in an infolist * return 1 if ok, 0 if error */ diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c index e449cb807..e929d321a 100644 --- a/src/plugins/irc/irc-server.c +++ b/src/plugins/irc/irc-server.c @@ -79,6 +79,9 @@ char *irc_server_option_default[IRC_SERVER_NUM_OPTIONS] = "", "0", "", "off", "30", }; +const char *irc_server_send_default_tags = NULL; /* default tags when */ + /* sending a message */ + void irc_server_reconnect (struct t_irc_server *server); void irc_server_free_data (struct t_irc_server *server); @@ -730,7 +733,7 @@ irc_server_apply_command_line_options (struct t_irc_server *server, void irc_server_outqueue_add (struct t_irc_server *server, int priority, const char *command, const char *msg1, - const char *msg2, int modified) + const char *msg2, int modified, const char *tags) { struct t_irc_outqueue *new_outqueue; @@ -741,6 +744,7 @@ irc_server_outqueue_add (struct t_irc_server *server, int priority, new_outqueue->message_before_mod = (msg1) ? strdup (msg1) : NULL; new_outqueue->message_after_mod = (msg2) ? strdup (msg2) : NULL; new_outqueue->modified = modified; + new_outqueue->tags = (tags) ? strdup (tags) : NULL; new_outqueue->prev_outqueue = server->last_outqueue[priority]; new_outqueue->next_outqueue = NULL; @@ -776,7 +780,7 @@ irc_server_outqueue_free (struct t_irc_server *server, if (outqueue->next_outqueue) (outqueue->next_outqueue)->prev_outqueue = outqueue->prev_outqueue; - + /* free data */ if (outqueue->command) free (outqueue->command); @@ -784,6 +788,8 @@ irc_server_outqueue_free (struct t_irc_server *server, free (outqueue->message_before_mod); if (outqueue->message_after_mod) free (outqueue->message_after_mod); + if (outqueue->tags) + free (outqueue->tags); free (outqueue); server->outqueue[priority] = new_outqueue; } @@ -1052,10 +1058,11 @@ irc_server_rename (struct t_irc_server *server, const char *new_server_name) void irc_server_send_signal (struct t_irc_server *server, const char *signal, - const char *command, const char *full_message) + const char *command, const char *full_message, + const char *tags) { int length; - char *str_signal; + char *str_signal, *full_message_tags; length = strlen (server->name) + 1 + strlen (signal) + 1 + strlen (command) + 1; str_signal = malloc (length); @@ -1063,8 +1070,25 @@ irc_server_send_signal (struct t_irc_server *server, const char *signal, { snprintf (str_signal, length, "%s,%s_%s", server->name, signal, command); - weechat_hook_signal_send (str_signal, WEECHAT_HOOK_SIGNAL_STRING, - (void *)full_message); + if (tags) + { + length = strlen (tags) + 1 + strlen (full_message) + 1; + full_message_tags = malloc (length); + if (full_message_tags) + { + snprintf (full_message_tags, length, + "%s;%s", tags, full_message); + weechat_hook_signal_send (str_signal, + WEECHAT_HOOK_SIGNAL_STRING, + (void *)full_message_tags); + free (full_message_tags); + } + } + else + { + weechat_hook_signal_send (str_signal, WEECHAT_HOOK_SIGNAL_STRING, + (void *)full_message); + } free (str_signal); } } @@ -1130,6 +1154,46 @@ irc_server_send (struct t_irc_server *server, const char *buffer, int size_buf) } /* + * irc_server_set_send_default_tags: set default tags used when sending message + */ + +void +irc_server_set_send_default_tags (const char *tags) +{ + irc_server_send_default_tags = tags; +} + +/* + * irc_server_get_tags_to_send: get tags to send by concatenation of tags + * and irc_server_send_default_tags (if set) + * If returned value is not NULL, then it must be + * free() after use. + */ + +char * +irc_server_get_tags_to_send (const char *tags) +{ + int length; + char *buf; + + if (!tags && !irc_server_send_default_tags) + return NULL; + + if (!tags) + return strdup (irc_server_send_default_tags); + + if (!irc_server_send_default_tags) + return strdup (tags); + + /* concatenate tags and irc_server_send_default_tags */ + length = strlen (tags) + 1 + strlen (irc_server_send_default_tags) + 1; + buf = malloc (length); + if (buf) + snprintf (buf, length, "%s,%s", tags, irc_server_send_default_tags); + return buf; +} + +/* * irc_server_outqueue_send: send a message from outqueue */ @@ -1137,7 +1201,7 @@ void irc_server_outqueue_send (struct t_irc_server *server) { time_t time_now; - char *pos; + char *pos, *tags_to_send; int priority; time_now = time (NULL); @@ -1177,7 +1241,15 @@ irc_server_outqueue_send (struct t_irc_server *server) /* send signal with command that will be sent to server */ irc_server_send_signal (server, "irc_out", server->outqueue[priority]->command, - server->outqueue[priority]->message_after_mod); + server->outqueue[priority]->message_after_mod, + NULL); + tags_to_send = irc_server_get_tags_to_send (server->outqueue[priority]->tags); + irc_server_send_signal (server, "irc_outtags", + server->outqueue[priority]->command, + server->outqueue[priority]->message_after_mod, + (tags_to_send) ? tags_to_send : ""); + if (tags_to_send) + free (tags_to_send); /* send command */ irc_server_send (server, server->outqueue[priority]->message_after_mod, @@ -1367,9 +1439,10 @@ irc_server_parse_message_to_hashtable (const char *message) /* * irc_server_send_one_msg: send one message to IRC server - * if queue_msg > 0, then messages are in a queue and - * sent slowly (to be sure there will not be any - * "excess flood"), value of queue_msg is priority: + * if flag contains outqueue priority value, then + * messages are in a queue and sent slowly (to be sure + * there will not be any "excess flood"), value of + * queue_msg is priority: * 1 = higher priority, for user messages * 2 = lower priority, for other messages (like * auto reply to CTCP queries) @@ -1377,15 +1450,15 @@ irc_server_parse_message_to_hashtable (const char *message) */ int -irc_server_send_one_msg (struct t_irc_server *server, int queue_msg, - const char *message) +irc_server_send_one_msg (struct t_irc_server *server, int flags, + const char *message, const char *tags) { static char buffer[4096]; const char *ptr_msg; - char *new_msg, *pos, *nick, *command, *channel; + char *new_msg, *pos, *nick, *command, *channel, *tags_to_send; char *ptr_chan_nick, *msg_encoded; char str_modifier[64], modifier_data[256]; - int rc, add_to_queue, first_message; + int rc, queue_msg, add_to_queue, first_message; time_t time_now; rc = 1; @@ -1450,13 +1523,24 @@ irc_server_send_one_msg (struct t_irc_server *server, int queue_msg, if (server->last_user_message > time_now) server->last_user_message = time_now; + /* get queue from flags */ + queue_msg = 0; + if (flags && IRC_SERVER_SEND_OUTQ_PRIO_HIGH) + queue_msg = 1; + else if (flags && IRC_SERVER_SEND_OUTQ_PRIO_LOW) + queue_msg = 2; + add_to_queue = 0; if ((queue_msg > 0) && (server->outqueue[queue_msg - 1] || ((weechat_config_integer (irc_config_network_anti_flood[queue_msg - 1]) > 0) && (time_now - server->last_user_message < weechat_config_integer (irc_config_network_anti_flood[queue_msg - 1]))))) + { add_to_queue = queue_msg; + } + + tags_to_send = irc_server_get_tags_to_send (tags); if (add_to_queue > 0) { @@ -1464,7 +1548,8 @@ irc_server_send_one_msg (struct t_irc_server *server, int queue_msg, irc_server_outqueue_add (server, add_to_queue - 1, command, (new_msg && first_message) ? message : NULL, buffer, - (new_msg) ? 1 : 0); + (new_msg) ? 1 : 0, + tags_to_send); } else { @@ -1476,7 +1561,12 @@ irc_server_send_one_msg (struct t_irc_server *server, int queue_msg, /* send signal with command that will be sent to server */ irc_server_send_signal (server, "irc_out", (command) ? command : "unknown", - ptr_msg); + ptr_msg, + NULL); + irc_server_send_signal (server, "irc_outtags", + (command) ? command : "unknown", + ptr_msg, + (tags_to_send) ? tags_to_send : ""); if (irc_server_send (server, buffer, strlen (buffer)) <= 0) rc = 0; @@ -1486,6 +1576,10 @@ irc_server_send_one_msg (struct t_irc_server *server, int queue_msg, server->last_user_message = time_now; } } + + if (tags_to_send) + free (tags_to_send); + if (pos) { pos[0] = '\n'; @@ -1517,16 +1611,10 @@ irc_server_send_one_msg (struct t_irc_server *server, int queue_msg, /* * irc_server_sendf: send formatted data to IRC server * many messages may be sent, separated by '\n' - * if queue_msg > 0, then messages are in a queue and sent - * slowly (to be sure there will not be any "excess flood"), - * value of queue_msg is priority: - * 1 = higher priority, for user messages - * 2 = lower priority, for other messages (like auto reply - * to CTCP queries) */ void -irc_server_sendf (struct t_irc_server *server, int queue_msg, +irc_server_sendf (struct t_irc_server *server, int flags, const char *tags, const char *format, ...) { va_list args; @@ -1544,7 +1632,7 @@ irc_server_sendf (struct t_irc_server *server, int queue_msg, items = weechat_string_split (buffer, "\n", 0, 0, &items_count); for (i = 0; i < items_count; i++) { - if (!irc_server_send_one_msg (server, queue_msg, items[i])) + if (!irc_server_send_one_msg (server, flags, items[i], tags)) break; } if (items) @@ -1968,7 +2056,7 @@ irc_server_timer_sasl_cb (void *data, int remaining_calls) weechat_printf (server->buffer, _("%s%s: sasl authentication timeout"), weechat_prefix ("error"), IRC_PLUGIN_NAME); - irc_server_sendf (server, 0, "CAP END"); + irc_server_sendf (server, 0, NULL, "CAP END"); } return WEECHAT_RC_OK; @@ -2014,7 +2102,7 @@ irc_server_timer_cb (void *data, int remaining_calls) && (ptr_server->lag_check_time.tv_sec == 0) && (new_time >= ptr_server->lag_next_check)) { - irc_server_sendf (ptr_server, 0, "PING %s", + irc_server_sendf (ptr_server, 0, NULL, "PING %s", ptr_server->addresses_array[ptr_server->index_current_address]); gettimeofday (&(ptr_server->lag_check_time), NULL); ptr_server->lag = 0; @@ -2230,7 +2318,7 @@ irc_server_login (struct t_irc_server *server) realname = IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_REALNAME); if (password && password[0]) - irc_server_sendf (server, 0, "PASS %s", password); + irc_server_sendf (server, 0, NULL, "PASS %s", password); if (!server->nick) { @@ -2244,10 +2332,10 @@ irc_server_login (struct t_irc_server *server) if (irc_server_sasl_enabled (server)) { - irc_server_sendf (server, 0, "CAP LS"); + irc_server_sendf (server, 0, NULL, "CAP LS"); } - irc_server_sendf (server, 0, + irc_server_sendf (server, 0, NULL, "NICK %s\n" "USER %s %s %s :%s", server->nick, @@ -3210,13 +3298,15 @@ irc_server_autojoin_channels (struct t_irc_server *server) { if (ptr_channel->key) { - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_LOW, + irc_server_sendf (server, + IRC_SERVER_SEND_OUTQ_PRIO_LOW, NULL, "JOIN %s %s", ptr_channel->name, ptr_channel->key); } else { - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_LOW, + irc_server_sendf (server, + IRC_SERVER_SEND_OUTQ_PRIO_LOW, NULL, "JOIN %s", ptr_channel->name); } @@ -3468,7 +3558,8 @@ irc_server_xfer_send_ready_cb (void *data, const char *signal, { filename = weechat_infolist_string (infolist, "filename"); spaces_in_name = (strchr (filename, ' ') != NULL); - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (server, + IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PRIVMSG %s :\01DCC SEND %s%s%s " "%s %d %s\01", weechat_infolist_string (infolist, "remote_nick"), @@ -3481,7 +3572,8 @@ irc_server_xfer_send_ready_cb (void *data, const char *signal, } else if (strcmp (type, "chat_send") == 0) { - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (server, + IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PRIVMSG %s :\01DCC CHAT chat %s %d\01", weechat_infolist_string (infolist, "remote_nick"), weechat_infolist_string (infolist, "address"), @@ -3538,7 +3630,7 @@ irc_server_xfer_resume_ready_cb (void *data, const char *signal, { filename = weechat_infolist_string (infolist, "filename"); spaces_in_name = (strchr (filename, ' ') != NULL); - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PRIVMSG %s :\01DCC RESUME %s%s%s %d %s\01", weechat_infolist_string (infolist, "remote_nick"), (spaces_in_name) ? "\"" : "", @@ -3597,7 +3689,7 @@ irc_server_xfer_send_accept_resume_cb (void *data, const char *signal, { filename = weechat_infolist_string (infolist, "filename"); spaces_in_name = (strchr (filename, ' ') != NULL); - irc_server_sendf (server, IRC_SERVER_OUTQUEUE_PRIO_HIGH, + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PRIVMSG %s :\01DCC ACCEPT %s%s%s %d %s\01", weechat_infolist_string (infolist, "remote_nick"), (spaces_in_name) ? "\"" : "", diff --git a/src/plugins/irc/irc-server.h b/src/plugins/irc/irc-server.h index 4b2d9108d..71555a76c 100644 --- a/src/plugins/irc/irc-server.h +++ b/src/plugins/irc/irc-server.h @@ -85,10 +85,13 @@ enum t_irc_server_option #define IRC_SERVER_DEFAULT_PORT 6667 #define IRC_SERVER_DEFAULT_NICKS "weechat1,weechat2,weechat3,weechat4,weechat5" -#define IRC_SERVER_OUTQUEUE_PRIO_HIGH 1 -#define IRC_SERVER_OUTQUEUE_PRIO_LOW 2 +/* number of queues for sending messages */ #define IRC_SERVER_NUM_OUTQUEUES_PRIO 2 +/* flags for irc_server_sendf() */ +#define IRC_SERVER_SEND_OUTQ_PRIO_HIGH 1 +#define IRC_SERVER_SEND_OUTQ_PRIO_LOW 2 + /* output queue of messages to server (for sending slowly to server) */ struct t_irc_outqueue @@ -97,6 +100,7 @@ struct t_irc_outqueue char *message_before_mod; /* msg before any modifier */ char *message_after_mod; /* msg after modifier(s) */ int modified; /* msg was modified by modifier(s) */ + char *tags; /* tags (used by Relay plugin) */ struct t_irc_outqueue *next_outqueue; /* link to next msg in queue */ struct t_irc_outqueue *prev_outqueue; /* link to prev msg in queue */ }; @@ -202,10 +206,12 @@ extern struct t_irc_server *irc_server_copy (struct t_irc_server *server, extern int irc_server_rename (struct t_irc_server *server, const char *new_name); extern void irc_server_send_signal (struct t_irc_server *server, const char *signal, const char *command, - const char *full_message); + const char *full_message, + const char *tags); extern struct t_hashtable *irc_server_parse_message_to_hashtable (const char *message); -extern void irc_server_sendf (struct t_irc_server *server, int queue_msg, - const char *format, ...); +extern void irc_server_set_send_default_tags (const char *tags); +extern void irc_server_sendf (struct t_irc_server *server, int flags, + const char *tags, const char *format, ...); extern struct t_irc_server *irc_server_search (const char *server_name); extern void irc_server_set_buffer_title (struct t_irc_server *server); extern struct t_gui_buffer *irc_server_create_buffer (struct t_irc_server *server); diff --git a/src/plugins/irc/irc-upgrade.c b/src/plugins/irc/irc-upgrade.c index ad7ab38b7..ee154c9b8 100644 --- a/src/plugins/irc/irc-upgrade.c +++ b/src/plugins/irc/irc-upgrade.c @@ -99,7 +99,7 @@ irc_upgrade_save_all_data (struct t_upgrade_file *upgrade_file) infolist = weechat_infolist_new (); if (!infolist) return 0; - if (!irc_nick_add_to_infolist (infolist, ptr_nick)) + if (!irc_nick_add_to_infolist (infolist, ptr_server, ptr_nick)) { weechat_infolist_free (infolist); return 0; diff --git a/src/plugins/irc/irc.c b/src/plugins/irc/irc.c index 56e7ae00b..6e7ba0dab 100644 --- a/src/plugins/irc/irc.c +++ b/src/plugins/irc/irc.c @@ -35,6 +35,7 @@ #include "irc-config.h" #include "irc-debug.h" #include "irc-info.h" +#include "irc-input.h" #include "irc-server.h" #include "irc-channel.h" #include "irc-nick.h" @@ -171,6 +172,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) weechat_hook_signal ("xfer_send_ready", &irc_server_xfer_send_ready_cb, NULL); weechat_hook_signal ("xfer_resume_ready", &irc_server_xfer_resume_ready_cb, NULL); weechat_hook_signal ("xfer_send_accept_resume", &irc_server_xfer_send_accept_resume_cb, NULL); + weechat_hook_signal ("irc_input_send", &irc_input_send_cb, NULL); /* modifiers */ weechat_hook_modifier ("irc_color_decode", &irc_color_modifier_cb, NULL); diff --git a/src/plugins/relay/CMakeLists.txt b/src/plugins/relay/CMakeLists.txt index 9a36b5eba..dc9d09cfc 100644 --- a/src/plugins/relay/CMakeLists.txt +++ b/src/plugins/relay/CMakeLists.txt @@ -21,12 +21,13 @@ ADD_LIBRARY(relay MODULE relay.c relay.h relay-buffer.c relay-buffer.h relay-client.c relay-client.h +relay-client-irc.c relay-client-irc.h +relay-client-weechat.c relay-client-weechat.h relay-command.c relay-command.h relay-completion.c relay-completion.h relay-config.c relay-config.h relay-info.c relay-info.h -relay-protocol-irc.c relay-protocol-irc.h -relay-protocol-weechat.c relay-protocol-weechat.h +relay-raw.c relay-raw.h relay-server.c relay-server.h relay-upgrade.c relay-upgrade.h) SET_TARGET_PROPERTIES(relay PROPERTIES PREFIX "") diff --git a/src/plugins/relay/Makefile.am b/src/plugins/relay/Makefile.am index 53f6583f1..958614a44 100644 --- a/src/plugins/relay/Makefile.am +++ b/src/plugins/relay/Makefile.am @@ -29,6 +29,10 @@ relay_la_SOURCES = relay.c \ relay-buffer.h \ relay-client.c \ relay-client.h \ + relay-client-irc.c \ + relay-client-irc.h \ + relay-client-weechat.c \ + relay-client-weechat.h \ relay-command.c \ relay-command.h \ relay-completion.c \ @@ -37,10 +41,8 @@ relay_la_SOURCES = relay.c \ relay-config.h \ relay-info.c \ relay-info.h \ - relay-protocol-irc.c \ - relay-protocol-irc.h \ - relay-protocol-weechat.c \ - relay-protocol-weechat.h \ + relay-raw.c \ + relay-raw.h \ relay-server.c \ relay-server.h \ relay-upgrade.c \ diff --git a/src/plugins/relay/relay-buffer.c b/src/plugins/relay/relay-buffer.c index df39df81e..da68513f2 100644 --- a/src/plugins/relay/relay-buffer.c +++ b/src/plugins/relay/relay-buffer.c @@ -125,9 +125,10 @@ relay_buffer_refresh (const char *hotlist) str_recv = weechat_string_format_size (ptr_client->bytes_recv); str_sent = weechat_string_format_size (ptr_client->bytes_sent); weechat_printf_y (relay_buffer, (line * 2) + 3, - _("%s%-26s protocol: %s, received: %s, sent: %s"), + _("%s%-26s id: %d, protocol: %s, received: %s, sent: %s"), weechat_color(str_color), " ", + ptr_client->id, relay_protocol_string[ptr_client->protocol], (str_recv) ? str_recv : "?", (str_sent) ? str_sent : "?"); diff --git a/src/plugins/relay/relay-client-irc.c b/src/plugins/relay/relay-client-irc.c new file mode 100644 index 000000000..766c9e06d --- /dev/null +++ b/src/plugins/relay/relay-client-irc.c @@ -0,0 +1,983 @@ +/* + * Copyright (C) 2003-2010 Sebastien Helleu <flashcode@flashtux.org> + * + * This file is part of WeeChat, the extensible chat client. + * + * WeeChat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WeeChat. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * relay-client-irc.c: IRC protocol for relay to client + * (relay acting as an IRC proxy/bouncer) + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <time.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <errno.h> + +#include "../weechat-plugin.h" +#include "relay.h" +#include "relay-client-irc.h" +#include "relay-client.h" +#include "relay-raw.h" + + +char *relay_client_irc_relay_commands[] = { "privmsg", "notice", NULL }; +char *relay_client_irc_ignore_commands[] = { "pong", "quit", NULL }; + + +/* + * relay_client_irc_command_relayed: return 1 if IRC command has to be + * relayed to client, or 0 if command + * must NOT be relayed + */ + +int +relay_client_irc_command_relayed (const char *irc_command) +{ + int i; + + if (irc_command) + { + for (i = 0; relay_client_irc_relay_commands[i]; i++) + { + if (weechat_strcasecmp (relay_client_irc_relay_commands[i], irc_command) == 0) + return 1; + } + } + + /* command must NOT be relayed to client */ + return 0; +} + +/* + * relay_client_irc_command_ignored: return 1 if IRC command from client + * has to be ignored + */ + +int +relay_client_irc_command_ignored (const char *irc_command) +{ + int i; + + if (irc_command) + { + for (i = 0; relay_client_irc_ignore_commands[i]; i++) + { + if (weechat_strcasecmp (relay_client_irc_ignore_commands[i], irc_command) == 0) + return 1; + } + } + + /* command must NOT be relayed to client */ + return 0; +} + +/* + * relay_client_irc_parse_message: parse IRC message + */ + +struct t_hashtable * +relay_client_irc_parse_message (const char *message) +{ + struct t_hashtable *hash_msg, *hash_parsed; + + hash_msg = NULL; + hash_parsed = NULL; + + hash_msg = weechat_hashtable_new (8, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, + NULL); + if (!hash_msg) + { + weechat_printf (NULL, + _("%s%s: not enough memory for parsing message"), + weechat_prefix ("error"), RELAY_PLUGIN_NAME); + goto end; + } + weechat_hashtable_set (hash_msg, "message", (char *)message); + hash_parsed = weechat_info_get_hashtable ("irc_parse_message", + hash_msg); + if (!hash_parsed) + { + weechat_printf (NULL, + _("%s%s: not enough memory for parsing message"), + weechat_prefix ("error"), RELAY_PLUGIN_NAME); + goto end; + } + +end: + if (hash_msg) + weechat_hashtable_free (hash_msg); + + return hash_parsed; +} + +/* + * relay_client_irc_sendf: send formatted data to client + */ + +int +relay_client_irc_sendf (struct t_relay_client *client, const char *format, ...) +{ + va_list args; + static char buffer[4096]; + int length, num_sent; + char *pos; + + if (!client) + return 0; + + va_start (args, format); + vsnprintf (buffer, sizeof (buffer) - 3, format, args); + va_end (args); + + if (weechat_relay_plugin->debug >= 2) + { + weechat_printf (NULL, "%s: send: %s", + RELAY_PLUGIN_NAME, buffer); + } + + length = strlen (buffer); + + pos = strchr (buffer, '\r'); + if (pos) + pos[0] = '\0'; + + relay_raw_print (client, 1, buffer); + + if (pos) + pos[0] = '\r'; + else + { + buffer[length] = '\r'; + buffer[length + 1] = '\n'; + buffer[length + 2] = '\0'; + length += 2; + } + + num_sent = send (client->sock, buffer, length, 0); + + if (num_sent >= 0) + client->bytes_sent += num_sent; + else + { + weechat_printf (NULL, + _("%s%s: error sending data to client: %s"), + weechat_prefix ("error"), RELAY_PLUGIN_NAME, + strerror (errno)); + } + + return num_sent; +} + +/* + * relay_client_irc_signal_irc_in2_cb: callback for "irc_in2" signal + * It is called when something is + * received on IRC server, and message + * can be relayed (or not) to client. + */ + +int +relay_client_irc_signal_irc_in2_cb (void *data, const char *signal, + const char *type_data, void *signal_data) +{ + struct t_relay_client *client; + const char *ptr_msg, *irc_host, *irc_command, *irc_args; + struct t_hashtable *hash_parsed; + + /* make C compiler happy */ + (void) signal; + (void) type_data; + + client = (struct t_relay_client *)data; + ptr_msg = (const char *)signal_data; + + if (weechat_relay_plugin->debug >= 2) + { + weechat_printf (NULL, "%s: irc_in2: client: %s, data: %s", + RELAY_PLUGIN_NAME, + client->protocol_string, + ptr_msg); + } + + hash_parsed = relay_client_irc_parse_message (ptr_msg); + if (hash_parsed) + { + irc_host = weechat_hashtable_get (hash_parsed, "host"); + irc_command = weechat_hashtable_get (hash_parsed, "command"); + irc_args = weechat_hashtable_get (hash_parsed, "arguments"); + + /* if self nick has changed, update it in client data */ + if (irc_command && (weechat_strcasecmp (irc_command, "nick") == 0)) + { + if (irc_args && irc_args[0]) + { + if (RELAY_IRC_DATA(client, nick)) + free (RELAY_IRC_DATA(client, nick)); + RELAY_IRC_DATA(client, nick) = strdup (irc_args); + } + } + + /* relay all commands to client, but not ping/pong */ + if (irc_command + && (weechat_strcasecmp (irc_command, "ping") != 0) + && (weechat_strcasecmp (irc_command, "pong") != 0)) + { + relay_client_irc_sendf (client, ":%s %s %s", + (irc_host && irc_host[0]) ? irc_host : RELAY_IRC_DATA(client, address), + irc_command, + irc_args); + } + } + + return WEECHAT_RC_OK; +} + +/* + * relay_client_irc_tag_relay_client_id: get id of client by looking for tag + * "relay_client_NNN" in list of tags + * (comma separated list) + * Return number found, or -1 if tag + * is not found. + */ + +int +relay_client_irc_tag_relay_client_id (const char *tags) +{ + char **argv, *error; + int result, argc, i; + long number; + + result = -1; + + if (tags && tags[0]) + { + argv = weechat_string_split (tags, ",", 0, 0, &argc); + if (argv) + { + for (i = 0; i < argc; i++) + { + if (strncmp (argv[i], "relay_client_", 13) == 0) + { + error = NULL; + number = strtol (argv[i] + 13, &error, 10); + if (error && !error[0]) + { + result = number; + break; + } + } + } + weechat_string_free_split (argv); + } + } + + return result; +} + +/* + * relay_client_irc_signal_irc_outtags_cb: callback for "irc_out" signal + * It is called when a message is sent + * to IRC server (by irc plugin or any + * other plugin/script). + */ + +int +relay_client_irc_signal_irc_outtags_cb (void *data, const char *signal, + const char *type_data, + void *signal_data) +{ + struct t_relay_client *client; + struct t_hashtable *hash_parsed; + const char *irc_command, *irc_args, *host, *ptr_message; + char *pos, *tags, *irc_channel, *message; + struct t_infolist *infolist_nick; + char str_infolist_args[256]; + + /* make C compiler happy */ + (void) signal; + (void) type_data; + + client = (struct t_relay_client *)data; + + message = strdup ((char *)signal_data); + if (!message) + goto end; + pos = strchr (message, '\r'); + if (pos) + pos[0] = '\0'; + + if (weechat_relay_plugin->debug >= 2) + { + weechat_printf (NULL, "%s: irc_out: client: %s, message: %s", + RELAY_PLUGIN_NAME, + client->protocol_string, + message); + } + + tags = NULL; + ptr_message = message; + + pos = strchr (ptr_message, ';'); + if (pos) + { + if (pos > ptr_message + 1) + tags = weechat_strndup (ptr_message, pos - ptr_message); + ptr_message = pos + 1; + } + + /* + * We check if there is a tag "relay_client_NNN" and if NNN (numeric) + * is equal to current client, then we ignore message, because message + * was sent from this same client! + * This is to prevent message from being displayed twice on client. + */ + if (relay_client_irc_tag_relay_client_id (tags) == client->id) + goto end; + + hash_parsed = relay_client_irc_parse_message (ptr_message); + if (hash_parsed) + { + irc_command = weechat_hashtable_get (hash_parsed, "command"); + irc_args = weechat_hashtable_get (hash_parsed, "arguments"); + + pos = strchr (irc_args, ' '); + irc_channel = (pos) ? + weechat_strndup (irc_args, pos - irc_args) : strdup (irc_args); + + /* if command has to be relayed, relay it to client */ + if (irc_command && irc_command[0] + && irc_channel && irc_channel[0] + && relay_client_irc_command_relayed (irc_command)) + { + /* get host for nick (it is self nick) */ + snprintf (str_infolist_args, sizeof (str_infolist_args) - 1, + "%s,%s,%s", + client->protocol_string, + irc_channel, + RELAY_IRC_DATA(client, nick)); + + host = NULL; + infolist_nick = weechat_infolist_get ("irc_nick", NULL, str_infolist_args); + if (infolist_nick && weechat_infolist_next (infolist_nick)) + host = weechat_infolist_string (infolist_nick, "host"); + + /* send message to client */ + relay_client_irc_sendf (client, + ":%s%s%s %s", + RELAY_IRC_DATA(client, nick), + (host && host[0]) ? "!" : "", + (host && host[0]) ? host : "", + ptr_message); + + if (infolist_nick) + weechat_infolist_free (infolist_nick); + } + if (irc_channel) + free (irc_channel); + weechat_hashtable_free (hash_parsed); + } + +end: + if (message) + free (message); + if (tags) + free (tags); + + return WEECHAT_RC_OK; +} + +/* + * relay_client_irc_signal_irc_disc_cb: callback for "irc_disconnected" signal + * It is called when connection to a + * server is lost. + */ + +int +relay_client_irc_signal_irc_disc_cb (void *data, const char *signal, + const char *type_data, void *signal_data) +{ + struct t_relay_client *client; + + /* make C compiler happy */ + (void) signal; + (void) type_data; + (void) signal_data; + + client = (struct t_relay_client *)data; + + if (strcmp ((char *)signal_data, client->protocol_string) == 0) + { + relay_client_set_status (client, RELAY_STATUS_DISCONNECTED); + } + + return WEECHAT_RC_OK; +} + +/* + * relay_client_irc_send_join: send join for a channel to client + */ + +void +relay_client_irc_send_join (struct t_relay_client *client, + const char *channel) +{ + char *infolist_name, *nicks; + const char *nick, *prefix; + char *host; + int length, length_nicks; + struct t_infolist *infolist_nick, *infolist_nicks; + + length = strlen (client->protocol_string) + 1 + strlen (channel) + 1 + + strlen (RELAY_IRC_DATA(client, nick)) + 1; + infolist_name = malloc (length); + if (infolist_name) + { + /* get nick host */ + host = NULL; + snprintf (infolist_name, length, "%s,%s,%s", + client->protocol_string, + channel, + RELAY_IRC_DATA(client, nick)); + infolist_nick = weechat_infolist_get ("irc_nick", NULL, infolist_name); + if (infolist_nick) + { + if (weechat_infolist_next (infolist_nick)) + { + host = (char *)weechat_infolist_string (infolist_nick, "host"); + if (host) + host = strdup (host); + } + weechat_infolist_free (infolist_nick); + } + relay_client_irc_sendf (client, + ":%s!%s JOIN %s", + RELAY_IRC_DATA(client, nick), + (host && host[0]) ? host : "weechat@proxy", + channel); + if (host) + free (host); + snprintf (infolist_name, length, "%s,%s", + client->protocol_string, + channel); + infolist_nicks = weechat_infolist_get ("irc_nick", NULL, infolist_name); + if (infolist_nicks) + { + length_nicks = 0; + nicks = NULL; + while (weechat_infolist_next (infolist_nicks)) + { + nick = weechat_infolist_string (infolist_nicks, "name"); + prefix = weechat_infolist_string (infolist_nicks, "prefix"); + if (nick && nick[0]) + { + length_nicks += strlen (nick) + 1 + 1; + if (nicks) + { + nicks = realloc (nicks, length_nicks); + strcat (nicks, " "); + } + else + { + nicks = malloc (length_nicks); + nicks[0] = '\0'; + } + if (prefix && (prefix[0] != ' ')) + strcat (nicks, prefix); + strcat (nicks, nick); + } + } + if (nicks) + { + relay_client_irc_sendf (client, + ":%s 353 %s = %s :%s", + RELAY_IRC_DATA(client, address), + RELAY_IRC_DATA(client, nick), + channel, nicks); + free (nicks); + } + weechat_infolist_free (infolist_nicks); + } + relay_client_irc_sendf (client, + ":%s 366 %s %s :End of /NAMES list.", + RELAY_IRC_DATA(client, address), + RELAY_IRC_DATA(client, nick), + channel); + free (infolist_name); + } +} + +/* + * relay_client_irc_send_join_channels: send join for all channels of server to + * client + */ + +void +relay_client_irc_send_join_channels (struct t_relay_client *client) +{ + struct t_infolist *infolist_channels; + const char *channel; + + infolist_channels = weechat_infolist_get ("irc_channel", NULL, + client->protocol_string); + if (infolist_channels) + { + while (weechat_infolist_next (infolist_channels)) + { + channel = weechat_infolist_string (infolist_channels, "name"); + relay_client_irc_send_join (client, channel); + } + weechat_infolist_free (infolist_channels); + } +} + +/* + * relay_client_irc_input_send: send text or command on an IRC buffer + */ + +void +relay_client_irc_input_send (struct t_relay_client *client, + const char *irc_channel, + int flags, + const char *format, ...) +{ + va_list args; + static char buffer[4096]; + int length; + + snprintf (buffer, sizeof (buffer), + "%s;%s;%d;relay_client_%d;", + client->protocol_string, + (irc_channel) ? irc_channel : "", + flags, + client->id); + + length = strlen (buffer); + + va_start (args, format); + vsnprintf (buffer + length, sizeof (buffer) - 1 - length, format, args); + va_end (args); + + if (weechat_relay_plugin->debug >= 2) + { + weechat_printf (NULL, + "%s: irc_input_send: \"%s\"", + RELAY_PLUGIN_NAME, buffer); + } + + weechat_hook_signal_send ("irc_input_send", + WEECHAT_HOOK_SIGNAL_STRING, + buffer); +} + +/* + * relay_client_irc_recv_one_msg: read one message from client + */ + +void +relay_client_irc_recv_one_msg (struct t_relay_client *client, char *data) +{ + char *pos, str_time[128], str_signal_name[128], *target; + const char *irc_command, *irc_channel, *irc_args, *irc_args2; + const char *nick, *irc_is_channel, *isupport; + struct t_hashtable *hash_parsed; + struct t_infolist *infolist_server; + + hash_parsed = NULL; + + /* remove \r at the end of message */ + pos = strchr (data, '\r'); + if (pos) + pos[0] = '\0'; + + /* display debug message */ + if (weechat_relay_plugin->debug >= 2) + { + weechat_printf (NULL, "%s: recv from client: \"%s\"", + RELAY_PLUGIN_NAME, data); + } + + relay_raw_print (client, 0, data); + + /* parse IRC message */ + hash_parsed = relay_client_irc_parse_message (data); + if (!hash_parsed) + goto end; + irc_command = weechat_hashtable_get (hash_parsed, "command"); + irc_channel = weechat_hashtable_get (hash_parsed, "channel"); + irc_args = weechat_hashtable_get (hash_parsed, "arguments"); + + /* process the message */ + if (irc_command && (weechat_strcasecmp (irc_command, "nick") == 0)) + { + if (irc_args && irc_args[0]) + { + if (RELAY_IRC_DATA(client, nick)) + free (RELAY_IRC_DATA(client, nick)); + RELAY_IRC_DATA(client, nick) = strdup (irc_args); + } + } + if (!RELAY_IRC_DATA(client, connected)) + { + if (irc_command && (weechat_strcasecmp (irc_command, "user") == 0)) + { + /* check if connection to server is ok */ + infolist_server = weechat_infolist_get ("irc_server", NULL, + client->protocol_string); + if (infolist_server) + { + if (weechat_infolist_next (infolist_server)) + { + if (!weechat_infolist_integer (infolist_server, + "is_connected")) + { + relay_client_irc_sendf (client, + ":%s ERROR :WeeChat: no " + "connection to server \"%s\"", + RELAY_IRC_DATA(client, address), + client->protocol_string); + relay_client_irc_sendf (client, + ":%s ERROR :Closing Link", + RELAY_IRC_DATA(client, address)); + relay_client_set_status (client, + RELAY_STATUS_DISCONNECTED); + return; + } + if (irc_args && irc_args[0]) + { + RELAY_IRC_DATA(client, user_received) = 1; + } + } + weechat_infolist_free (infolist_server); + } + } + if (RELAY_IRC_DATA(client, nick) && RELAY_IRC_DATA(client, user_received)) + { + RELAY_IRC_DATA(client, connected) = 1; + + /* + * send nick to client if server nick is different of nick asked + * by client with command NICK + */ + nick = weechat_info_get ("irc_nick", client->protocol_string); + if (nick && (strcmp (nick, RELAY_IRC_DATA(client, nick)) != 0)) + { + relay_client_irc_sendf (client, + ":%s!proxy NICK :%s", + RELAY_IRC_DATA(client, nick), + nick); + free (RELAY_IRC_DATA(client, nick)); + RELAY_IRC_DATA(client, nick) = strdup (nick); + } + + relay_client_irc_sendf (client, + ":%s 001 %s :Welcome to the Internet " + "Relay Chat Network %s!%s@proxy", + RELAY_IRC_DATA(client, address), + RELAY_IRC_DATA(client, nick), + RELAY_IRC_DATA(client, nick), + "weechat"); + relay_client_irc_sendf (client, + ":%s 002 %s :Your host is " + "weechat-relay-irc, running version %s", + RELAY_IRC_DATA(client, address), + RELAY_IRC_DATA(client, nick), + weechat_info_get("version", NULL)); + snprintf (str_time, sizeof (str_time), "%s", + ctime (&client->listen_start_time)); + if (str_time[0]) + str_time[strlen (str_time) - 1] = '\0'; + relay_client_irc_sendf (client, + ":%s 003 %s :This server was created on %s", + RELAY_IRC_DATA(client, address), + RELAY_IRC_DATA(client, nick), + str_time); + relay_client_irc_sendf (client, + ":%s 004 %s %s %s oirw abiklmnopqstv", + RELAY_IRC_DATA(client, address), + RELAY_IRC_DATA(client, nick), + RELAY_IRC_DATA(client, address), + weechat_info_get("version", NULL)); + infolist_server = weechat_infolist_get ("irc_server", NULL, + client->protocol_string); + if (infolist_server) + { + if (weechat_infolist_next (infolist_server)) + { + isupport = weechat_infolist_string (infolist_server, + "isupport"); + if (isupport && isupport[0]) + { + while (isupport[0] == ' ') + { + isupport++; + } + /* TODO: split this message into many messages */ + relay_client_irc_sendf (client, + ":%s 005 %s %s :are supported " + "by this server", + RELAY_IRC_DATA(client, address), + RELAY_IRC_DATA(client, nick), + isupport); + } + } + weechat_infolist_free (infolist_server); + } + relay_client_irc_sendf (client, + ":%s 251 %s :There are %d users and 0 " + "invisible on 1 servers", + RELAY_IRC_DATA(client, address), + RELAY_IRC_DATA(client, nick), + relay_client_count); + relay_client_irc_sendf (client, + ":%s 255 %s :I have %d clients, 0 " + "services and 0 servers", + RELAY_IRC_DATA(client, address), + RELAY_IRC_DATA(client, nick), + relay_client_count); + relay_client_irc_sendf (client, + ":%s 422 %s :MOTD File is missing", + RELAY_IRC_DATA(client, address), + RELAY_IRC_DATA(client, nick)); + + /* + * hook signal "xxx,irc_in2_*" to catch IRC data received from + * this server + */ + snprintf (str_signal_name, sizeof (str_signal_name), + "%s,irc_in2_*", + client->protocol_string); + RELAY_IRC_DATA(client, hook_signal_irc_in2) = + weechat_hook_signal (str_signal_name, + &relay_client_irc_signal_irc_in2_cb, + client); + + /* + * hook signal "xxx,irc_outtags_*" to catch IRC data sent to + * this server + */ + snprintf (str_signal_name, sizeof (str_signal_name), + "%s,irc_outtags_*", + client->protocol_string); + RELAY_IRC_DATA(client, hook_signal_irc_outtags) = + weechat_hook_signal (str_signal_name, + &relay_client_irc_signal_irc_outtags_cb, + client); + + /* + * hook signal "irc_server_disconnected" to disconnect client if + * connection to server is lost + */ + RELAY_IRC_DATA(client, hook_signal_irc_disc) = + weechat_hook_signal ("irc_server_disconnected", + &relay_client_irc_signal_irc_disc_cb, + client); + + /* send JOIN for all channels on server to client */ + relay_client_irc_send_join_channels (client); + } + } + else + { + if (irc_command && weechat_strcasecmp (irc_command, "ping") == 0) + { + relay_client_irc_sendf (client, + ":%s PONG %s :%s", + RELAY_IRC_DATA(client, address), + RELAY_IRC_DATA(client, address), + irc_args); + } + else if (irc_command && irc_channel && irc_channel[0] + && irc_args && irc_args[0] + && (weechat_strcasecmp (irc_command, "notice") == 0)) + { + irc_args2 = strchr (irc_args, ' '); + if (irc_args2) + { + target = weechat_strndup (irc_args, irc_args2 - irc_args); + if (target) + { + while (irc_args2[0] == ' ') + { + irc_args2++; + } + if (irc_args2[0] == ':') + irc_args2++; + relay_client_irc_input_send (client, NULL, 1, + "/notice %s %s", + target, + irc_args2); + free (target); + } + } + } + else if (irc_command && irc_channel && irc_channel[0] + && irc_args && irc_args[0] + && (weechat_strcasecmp (irc_command, "privmsg") == 0)) + { + irc_args2 = strchr (irc_args, ' '); + if (!irc_args2) + irc_args2 = irc_args; + while (irc_args2[0] == ' ') + { + irc_args2++; + } + if (irc_args2[0] == ':') + irc_args2++; + irc_is_channel = weechat_info_get ("irc_is_channel", irc_channel); + if (irc_is_channel && (strcmp (irc_is_channel, "1") == 0)) + { + relay_client_irc_input_send (client, irc_channel, 1, + "%s", irc_args2); + } + else + { + relay_client_irc_input_send (client, NULL, 1, + "/query %s %s", + irc_channel, irc_args2); + } + } + else if (!relay_client_irc_command_ignored (irc_command)) + { + relay_client_irc_input_send (client, NULL, 1, + "/quote %s", + data); + } + } + +end: + if (hash_parsed) + weechat_hashtable_free (hash_parsed); +} + +/* + * relay_client_irc_recv: read data from client + */ + +void +relay_client_irc_recv (struct t_relay_client *client, const char *data) +{ + char **items; + int items_count, i; + + items = weechat_string_split (data, "\n", 0, 0, &items_count); + for (i = 0; i < items_count; i++) + { + relay_client_irc_recv_one_msg (client, items[i]); + } + if (items) + weechat_string_free_split (items); +} + +/* + * relay_client_irc_close_connection: called when connection with client is + * closed + */ + +void +relay_client_irc_close_connection (struct t_relay_client *client) +{ + RELAY_IRC_DATA(client, connected) = 0; + if (RELAY_IRC_DATA(client, hook_signal_irc_in2)) + { + weechat_unhook (RELAY_IRC_DATA(client, hook_signal_irc_in2)); + RELAY_IRC_DATA(client, hook_signal_irc_in2) = NULL; + } + if (RELAY_IRC_DATA(client, hook_signal_irc_outtags)) + { + weechat_unhook (RELAY_IRC_DATA(client, hook_signal_irc_outtags)); + RELAY_IRC_DATA(client, hook_signal_irc_outtags) = NULL; + } + if (RELAY_IRC_DATA(client, hook_signal_irc_disc)) + { + weechat_unhook (RELAY_IRC_DATA(client, hook_signal_irc_disc)); + RELAY_IRC_DATA(client, hook_signal_irc_disc) = NULL; + } +} + +/* + * relay_client_irc_alloc: init relay data specific to IRC protocol + */ + +void +relay_client_irc_alloc (struct t_relay_client *client) +{ + struct t_relay_client_irc_data *irc_data; + + client->protocol_data = malloc (sizeof (*irc_data)); + if (client->protocol_data) + { + RELAY_IRC_DATA(client, address) = strdup ("weechat.relay.irc"); + RELAY_IRC_DATA(client, nick) = NULL; + RELAY_IRC_DATA(client, user_received) = 0; + RELAY_IRC_DATA(client, connected) = 0; + RELAY_IRC_DATA(client, hook_signal_irc_in2) = NULL; + RELAY_IRC_DATA(client, hook_signal_irc_outtags) = NULL; + RELAY_IRC_DATA(client, hook_signal_irc_disc) = NULL; + } +} + +/* + * relay_client_irc_free: free relay data specific to IRC protocol + */ + +void +relay_client_irc_free (struct t_relay_client *client) +{ + if (client->protocol_data) + { + if (RELAY_IRC_DATA(client, address)) + free (RELAY_IRC_DATA(client, address)); + if (RELAY_IRC_DATA(client, nick)) + free (RELAY_IRC_DATA(client, nick)); + if (RELAY_IRC_DATA(client, hook_signal_irc_in2)) + weechat_unhook (RELAY_IRC_DATA(client, hook_signal_irc_in2)); + if (RELAY_IRC_DATA(client, hook_signal_irc_outtags)) + weechat_unhook (RELAY_IRC_DATA(client, hook_signal_irc_outtags)); + if (RELAY_IRC_DATA(client, hook_signal_irc_disc)) + weechat_unhook (RELAY_IRC_DATA(client, hook_signal_irc_disc)); + + free (client->protocol_data); + + client->protocol_data = NULL; + } +} + +/* + * relay_client_irc_print_log: print IRC client infos in log (usually for + * crash dump) + */ + +void +relay_client_irc_print_log (struct t_relay_client *client) +{ + if (client->protocol_data) + { + weechat_log_printf (" address. . . . . . . . : '%s'", RELAY_IRC_DATA(client, address)); + weechat_log_printf (" nick . . . . . . . . . : '%s'", RELAY_IRC_DATA(client, nick)); + weechat_log_printf (" user_received. . . . . : %d", RELAY_IRC_DATA(client, user_received)); + weechat_log_printf (" connected. . . . . . . : %d", RELAY_IRC_DATA(client, connected)); + weechat_log_printf (" hook_signal_irc_in2. . : 0x%lx", RELAY_IRC_DATA(client, hook_signal_irc_in2)); + weechat_log_printf (" hook_signal_irc_outtags: 0x%lx", RELAY_IRC_DATA(client, hook_signal_irc_outtags)); + weechat_log_printf (" hook_signal_irc_disc . : 0x%lx", RELAY_IRC_DATA(client, hook_signal_irc_disc)); + } +} diff --git a/src/plugins/relay/relay-protocol-irc.h b/src/plugins/relay/relay-client-irc.h index f92a2b503..b74c57670 100644 --- a/src/plugins/relay/relay-protocol-irc.h +++ b/src/plugins/relay/relay-client-irc.h @@ -17,15 +17,15 @@ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef __WEECHAT_RELAY_PROTOCOL_IRC_H -#define __WEECHAT_RELAY_PROTOCOL_IRC_H 1 +#ifndef __WEECHAT_RELAY_CLIENT_IRC_H +#define __WEECHAT_RELAY_CLIENT_IRC_H 1 struct t_relay_client; #define RELAY_IRC_DATA(client, var) \ - (((struct t_relay_protocol_irc_data *)client->protocol_data)->var) + (((struct t_relay_client_irc_data *)client->protocol_data)->var) -struct t_relay_protocol_irc_data +struct t_relay_client_irc_data { char *address; /* client address (used when sending */ /* data to client) */ @@ -33,14 +33,16 @@ struct t_relay_protocol_irc_data int user_received; /* command "USER" received */ int connected; /* 1 if client is connected as IRC */ /* client */ - struct t_hook *hook_signal_irc_in2;/* hook signal "irc_in2" */ - struct t_hook *hook_signal_irc_out;/* hook signal "irc_out" */ + struct t_hook *hook_signal_irc_in2; /* signal "irc_in2" */ + struct t_hook *hook_signal_irc_outtags; /* signal "irc_outtags" */ + struct t_hook *hook_signal_irc_disc; /* signal "irc_disconnected" */ }; -extern void relay_protocol_irc_recv (struct t_relay_client *client, - const char *data); -extern void relay_protocol_irc_alloc (struct t_relay_client *client); -extern void relay_protocol_irc_free (struct t_relay_client *client); -extern void relay_protocol_irc_print_log (struct t_relay_client *client); +extern void relay_client_irc_recv (struct t_relay_client *client, + const char *data); +extern void relay_client_irc_close_connection (struct t_relay_client *client); +extern void relay_client_irc_alloc (struct t_relay_client *client); +extern void relay_client_irc_free (struct t_relay_client *client); +extern void relay_client_irc_print_log (struct t_relay_client *client); -#endif /* __WEECHAT_RELAY_PROTOCOL_IRC_H */ +#endif /* __WEECHAT_RELAY_CLIENT_IRC_H */ diff --git a/src/plugins/relay/relay-protocol-weechat.c b/src/plugins/relay/relay-client-weechat.c index d731fa919..7b9e31351 100644 --- a/src/plugins/relay/relay-protocol-weechat.c +++ b/src/plugins/relay/relay-client-weechat.c @@ -18,7 +18,7 @@ */ /* - * relay-protocol-weechat.c: WeeChat protocol for relay to client + * relay-client-weechat.c: WeeChat protocol for relay to client */ #include <stdlib.h> @@ -31,17 +31,17 @@ #include "../weechat-plugin.h" #include "relay.h" -#include "relay-protocol-weechat.h" +#include "relay-client-weechat.h" #include "relay-client.h" /* - * relay_protocol_weechat_sendf: send formatted data to client + * relay_client_weechat_sendf: send formatted data to client */ int -relay_protocol_weechat_sendf (struct t_relay_client *client, - const char *format, ...) +relay_client_weechat_sendf (struct t_relay_client *client, + const char *format, ...) { va_list args; static char buffer[4096]; @@ -75,19 +75,19 @@ relay_protocol_weechat_sendf (struct t_relay_client *client, } /* - * relay_protocol_weechat_send_infolist: send infolist to client + * relay_client_weechat_send_infolist: send infolist to client */ void -relay_protocol_weechat_send_infolist (struct t_relay_client *client, - const char *name, - struct t_infolist *infolist) +relay_client_weechat_send_infolist (struct t_relay_client *client, + const char *name, + struct t_infolist *infolist) { const char *fields; char **argv; int i, argc, size; - relay_protocol_weechat_sendf (client, "name %s", name); + relay_client_weechat_sendf (client, "name %s", name); while (weechat_infolist_next (infolist)) { @@ -102,34 +102,34 @@ relay_protocol_weechat_send_infolist (struct t_relay_client *client, switch (argv[i][0]) { case 'i': - relay_protocol_weechat_sendf (client, "%s %c %d", - argv[i] + 2, argv[i][0], - weechat_infolist_integer (infolist, - argv[i] + 2)); + relay_client_weechat_sendf (client, "%s %c %d", + argv[i] + 2, argv[i][0], + weechat_infolist_integer (infolist, + argv[i] + 2)); break; case 's': - relay_protocol_weechat_sendf (client, "%s %c %s", - argv[i] + 2, argv[i][0], - weechat_infolist_string (infolist, - argv[i] + 2)); + relay_client_weechat_sendf (client, "%s %c %s", + argv[i] + 2, argv[i][0], + weechat_infolist_string (infolist, + argv[i] + 2)); break; case 'p': - relay_protocol_weechat_sendf (client, "%s %c %lx", - argv[i] + 2, argv[i][0], - (long unsigned int)weechat_infolist_pointer (infolist, - argv[i] + 2)); + relay_client_weechat_sendf (client, "%s %c %lx", + argv[i] + 2, argv[i][0], + (long unsigned int)weechat_infolist_pointer (infolist, + argv[i] + 2)); break; case 'b': - relay_protocol_weechat_sendf (client, "%s %c %lx", - argv[i] + 2, argv[i][0], - (long unsigned int)weechat_infolist_buffer (infolist, - argv[i] + 2, + relay_client_weechat_sendf (client, "%s %c %lx", + argv[i] + 2, argv[i][0], + (long unsigned int)weechat_infolist_buffer (infolist, + argv[i] + 2, &size)); break; case 't': - relay_protocol_weechat_sendf (client, "%s %c %ld", - argv[i] + 2, argv[i][0], - weechat_infolist_time (infolist, argv[i] + 2)); + relay_client_weechat_sendf (client, "%s %c %ld", + argv[i] + 2, argv[i][0], + weechat_infolist_time (infolist, argv[i] + 2)); break; } } @@ -141,11 +141,11 @@ relay_protocol_weechat_send_infolist (struct t_relay_client *client, } /* - * relay_protocol_weechat_recv_one_msg: read one message from client + * relay_client_weechat_recv_one_msg: read one message from client */ void -relay_protocol_weechat_recv_one_msg (struct t_relay_client *client, char *data) +relay_client_weechat_recv_one_msg (struct t_relay_client *client, char *data) { char *pos; struct t_infolist *infolist; @@ -166,18 +166,18 @@ relay_protocol_weechat_recv_one_msg (struct t_relay_client *client, char *data) infolist = weechat_infolist_get (data, NULL, NULL); if (infolist) { - relay_protocol_weechat_send_infolist (client, data, infolist); + relay_client_weechat_send_infolist (client, data, infolist); weechat_infolist_free (infolist); } } } /* - * relay_protocol_weechat_recv: read data from client + * relay_client_weechat_recv: read data from client */ void -relay_protocol_weechat_recv (struct t_relay_client *client, const char *data) +relay_client_weechat_recv (struct t_relay_client *client, const char *data) { char **items; int items_count, i; @@ -185,20 +185,20 @@ relay_protocol_weechat_recv (struct t_relay_client *client, const char *data) items = weechat_string_split (data, "\n", 0, 0, &items_count); for (i = 0; i < items_count; i++) { - relay_protocol_weechat_recv_one_msg (client, items[i]); + relay_client_weechat_recv_one_msg (client, items[i]); } if (items) weechat_string_free_split (items); } /* - * relay_protocol_weechat_alloc: init relay data specific to weechat protocol + * relay_client_weechat_alloc: init relay data specific to weechat protocol */ void -relay_protocol_weechat_alloc (struct t_relay_client *client) +relay_client_weechat_alloc (struct t_relay_client *client) { - struct t_relay_protocol_weechat_data *weechat_data; + struct t_relay_client_weechat_data *weechat_data; client->protocol_data = malloc (sizeof (*weechat_data)); if (client->protocol_data) @@ -208,23 +208,23 @@ relay_protocol_weechat_alloc (struct t_relay_client *client) } /* - * relay_protocol_weechat_free: free relay data specific to weechat protocol + * relay_client_weechat_free: free relay data specific to weechat protocol */ void -relay_protocol_weechat_free (struct t_relay_client *client) +relay_client_weechat_free (struct t_relay_client *client) { if (client->protocol_data) free (client->protocol_data); } /* - * relay_protocol_weechat_print_log: print weechat client infos in log (usually - * for crash dump) + * relay_client_weechat_print_log: print weechat client infos in log (usually + * for crash dump) */ void -relay_protocol_weechat_print_log (struct t_relay_client *client) +relay_client_weechat_print_log (struct t_relay_client *client) { if (client->protocol_data) { diff --git a/src/plugins/relay/relay-protocol-weechat.h b/src/plugins/relay/relay-client-weechat.h index 8466868d9..32172235f 100644 --- a/src/plugins/relay/relay-protocol-weechat.h +++ b/src/plugins/relay/relay-client-weechat.h @@ -17,15 +17,15 @@ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef __WEECHAT_RELAY_PROTOCOL_WEECHAT_H -#define __WEECHAT_RELAY_PROTOCOL_WEECHAT_H 1 +#ifndef __WEECHAT_RELAY_CLIENT_WEECHAT_H +#define __WEECHAT_RELAY_CLIENT_WEECHAT_H 1 struct t_relay_client; #define RELAY_WEECHAT_DATA(client, var) \ - (((struct t_relay_protocol_weechat_data *)client->protocol_data)->var) + (((struct t_relay_client_weechat_data *)client->protocol_data)->var) -struct t_relay_protocol_weechat_data +struct t_relay_client_weechat_data { char *address; /* client address (used when sending */ /* data to client) */ @@ -35,10 +35,10 @@ struct t_relay_protocol_weechat_data /* client */ }; -extern void relay_protocol_weechat_recv (struct t_relay_client *client, - const char *data); -extern void relay_protocol_weechat_alloc (struct t_relay_client *client); -extern void relay_protocol_weechat_free (struct t_relay_client *client); -extern void relay_protocol_weechat_print_log (struct t_relay_client *client); +extern void relay_client_weechat_recv (struct t_relay_client *client, + const char *data); +extern void relay_client_weechat_alloc (struct t_relay_client *client); +extern void relay_client_weechat_free (struct t_relay_client *client); +extern void relay_client_weechat_print_log (struct t_relay_client *client); -#endif /* __WEECHAT_RELAY_PROTOCOL_WEECHAT_H */ +#endif /* __WEECHAT_RELAY_CLIENT_WEECHAT_H */ diff --git a/src/plugins/relay/relay-client.c b/src/plugins/relay/relay-client.c index 5d018206c..1dec067af 100644 --- a/src/plugins/relay/relay-client.c +++ b/src/plugins/relay/relay-client.c @@ -34,10 +34,10 @@ #include "../weechat-plugin.h" #include "relay.h" #include "relay-client.h" +#include "relay-client-irc.h" +#include "relay-client-weechat.h" #include "relay-config.h" #include "relay-buffer.h" -#include "relay-protocol-irc.h" -#include "relay-protocol-weechat.h" #include "relay-server.h" @@ -123,10 +123,10 @@ relay_client_recv_cb (void *arg_client, int fd) switch (client->protocol) { case RELAY_PROTOCOL_WEECHAT: - relay_protocol_weechat_recv (client, buffer); + relay_client_weechat_recv (client, buffer); break; case RELAY_PROTOCOL_IRC: - relay_protocol_irc_recv (client, buffer); + relay_client_irc_recv (client, buffer); break; case RELAY_NUM_PROTOCOLS: break; @@ -153,6 +153,7 @@ relay_client_new (int sock, char *address, struct t_relay_server *server) new_client = malloc (sizeof (*new_client)); if (new_client) { + new_client->id = (relay_clients) ? relay_clients->id + 1 : 1; new_client->sock = sock; new_client->address = strdup ((address) ? address : "?"); new_client->status = RELAY_STATUS_CONNECTED; @@ -171,10 +172,10 @@ relay_client_new (int sock, char *address, struct t_relay_server *server) switch (new_client->protocol) { case RELAY_PROTOCOL_WEECHAT: - relay_protocol_weechat_alloc (new_client); + relay_client_weechat_alloc (new_client); break; case RELAY_PROTOCOL_IRC: - relay_protocol_irc_alloc (new_client); + relay_client_irc_alloc (new_client); break; case RELAY_NUM_PROTOCOLS: break; @@ -189,12 +190,13 @@ relay_client_new (int sock, char *address, struct t_relay_server *server) relay_clients = new_client; weechat_printf (NULL, - _("%s: new client from %s%s%s on port %d (relaying: %s.%s)"), + _("%s: new client from %s%s%s on port %d (id: %d, relaying: %s.%s)"), RELAY_PLUGIN_NAME, RELAY_COLOR_CHAT_HOST, new_client->address, RELAY_COLOR_CHAT, server->port, + new_client->id, relay_protocol_string[new_client->protocol], new_client->protocol_string); @@ -247,6 +249,16 @@ relay_client_set_status (struct t_relay_client *client, weechat_unhook (client->hook_timer); client->hook_timer = NULL; } + switch (client->protocol) + { + case RELAY_PROTOCOL_WEECHAT: + break; + case RELAY_PROTOCOL_IRC: + relay_client_irc_close_connection (client); + break; + case RELAY_NUM_PROTOCOLS: + break; + } switch (client->status) { case RELAY_STATUS_AUTH_FAILED: @@ -323,10 +335,10 @@ relay_client_free (struct t_relay_client *client) switch (client->protocol) { case RELAY_PROTOCOL_WEECHAT: - relay_protocol_weechat_free (client); + relay_client_weechat_free (client); break; case RELAY_PROTOCOL_IRC: - relay_protocol_irc_free (client); + relay_client_irc_free (client); break; case RELAY_NUM_PROTOCOLS: break; @@ -446,36 +458,37 @@ relay_client_print_log () { weechat_log_printf (""); weechat_log_printf ("[relay client (addr:0x%lx)]", ptr_client); - weechat_log_printf (" sock. . . . . . . . : %d", ptr_client->sock); - weechat_log_printf (" address . . . . . . : '%s'", ptr_client->address); - weechat_log_printf (" status. . . . . . . : %d (%s)", + weechat_log_printf (" id. . . . . . . . . . : %d", ptr_client->id); + weechat_log_printf (" sock. . . . . . . . . : %d", ptr_client->sock); + weechat_log_printf (" address . . . . . . . : '%s'", ptr_client->address); + weechat_log_printf (" status. . . . . . . . : %d (%s)", ptr_client->status, relay_client_status_string[ptr_client->status]); - weechat_log_printf (" protocol. . . . . . : %d (%s)", + weechat_log_printf (" protocol. . . . . . . : %d (%s)", ptr_client->protocol, relay_protocol_string[ptr_client->protocol]); - weechat_log_printf (" protocol_string . . : '%s'", ptr_client->protocol_string); - weechat_log_printf (" listen_start_time . : %ld", ptr_client->listen_start_time); - weechat_log_printf (" start_time. . . . . : %ld", ptr_client->start_time); - weechat_log_printf (" end_time. . . . . . : %ld", ptr_client->end_time); - weechat_log_printf (" hook_fd . . . . . . : 0x%lx", ptr_client->hook_fd); - weechat_log_printf (" hook_timer. . . . . : 0x%lx", ptr_client->hook_timer); - weechat_log_printf (" last_activity . . . : %ld", ptr_client->last_activity); - weechat_log_printf (" bytes_recv. . . . . : %lu", ptr_client->bytes_recv); - weechat_log_printf (" bytes_sent. . . . . : %lu", ptr_client->bytes_sent); - weechat_log_printf (" protocol_data . . . : 0x%lx", ptr_client->protocol_data); + weechat_log_printf (" protocol_string . . . : '%s'", ptr_client->protocol_string); + weechat_log_printf (" listen_start_time . . : %ld", ptr_client->listen_start_time); + weechat_log_printf (" start_time. . . . . . : %ld", ptr_client->start_time); + weechat_log_printf (" end_time. . . . . . . : %ld", ptr_client->end_time); + weechat_log_printf (" hook_fd . . . . . . . : 0x%lx", ptr_client->hook_fd); + weechat_log_printf (" hook_timer. . . . . . : 0x%lx", ptr_client->hook_timer); + weechat_log_printf (" last_activity . . . . : %ld", ptr_client->last_activity); + weechat_log_printf (" bytes_recv. . . . . . : %lu", ptr_client->bytes_recv); + weechat_log_printf (" bytes_sent. . . . . . : %lu", ptr_client->bytes_sent); + weechat_log_printf (" protocol_data . . . . : 0x%lx", ptr_client->protocol_data); switch (ptr_client->protocol) { case RELAY_PROTOCOL_WEECHAT: - relay_protocol_weechat_print_log (ptr_client); + relay_client_weechat_print_log (ptr_client); break; case RELAY_PROTOCOL_IRC: - relay_protocol_irc_print_log (ptr_client); + relay_client_irc_print_log (ptr_client); break; case RELAY_NUM_PROTOCOLS: break; } - weechat_log_printf (" prev_client . . . . : 0x%lx", ptr_client->prev_client); - weechat_log_printf (" next_client . . . . : 0x%lx", ptr_client->next_client); + weechat_log_printf (" prev_client . . . . . : 0x%lx", ptr_client->prev_client); + weechat_log_printf (" next_client . . . . . : 0x%lx", ptr_client->next_client); } } diff --git a/src/plugins/relay/relay-client.h b/src/plugins/relay/relay-client.h index fa0b5818a..9e1eec957 100644 --- a/src/plugins/relay/relay-client.h +++ b/src/plugins/relay/relay-client.h @@ -44,6 +44,7 @@ enum t_relay_status struct t_relay_client { + int id; /* unique id (diff. for each client) */ int sock; /* socket for connection */ char *address; /* string with IP address */ enum t_relay_status status; /* status (connecting, active,..) */ diff --git a/src/plugins/relay/relay-command.c b/src/plugins/relay/relay-command.c index 008274edc..33b315bf3 100644 --- a/src/plugins/relay/relay-command.c +++ b/src/plugins/relay/relay-command.c @@ -30,6 +30,7 @@ #include "relay-buffer.h" #include "relay-client.h" #include "relay-config.h" +#include "relay-raw.h" #include "relay-server.h" @@ -64,9 +65,10 @@ relay_command_client_list (int full) if (full) { weechat_printf (NULL, - _("%3d. %s%s%s (%s%s%s), started on: %s, last " - "activity: %s, bytes: %lu recv, %lu sent"), - i, + _(" id: %d, %s%s%s (%s%s%s), " + "started on: %s, last activity: %s, " + "bytes: %lu recv, %lu sent"), + ptr_client->id, RELAY_COLOR_CHAT_HOST, ptr_client->address, RELAY_COLOR_CHAT, @@ -83,8 +85,8 @@ relay_command_client_list (int full) if (!RELAY_CLIENT_HAS_ENDED(ptr_client->status)) { weechat_printf (NULL, - _("%3d. %s%s%s, started on: %s"), - i, + _(" id: %d, %s%s%s, started on: %s"), + ptr_client->id, RELAY_COLOR_CHAT_HOST, ptr_client->address, RELAY_COLOR_CHAT, @@ -124,8 +126,7 @@ relay_command_server_list () "%a, %d %b %Y %H:%M:%S", date_tmp); weechat_printf (NULL, - _("%3d. port %s%d%s, relay: %s%s.%s%s, started on: %s"), - i, + _(" port %s%d%s, relay: %s%s.%s%s, started on: %s"), RELAY_COLOR_CHAT_BUFFER, ptr_server->port, RELAY_COLOR_CHAT, @@ -223,6 +224,11 @@ relay_command_relay (void *data, struct t_gui_buffer *buffer, int argc, } return WEECHAT_RC_OK; } + if (weechat_strcasecmp (argv[1], "raw") == 0) + { + relay_raw_open (1); + return WEECHAT_RC_OK; + } } if (!relay_buffer) @@ -262,7 +268,7 @@ relay_command_init () weechat_hook_command ("relay", N_("relay control"), N_("[list | listfull | add protocol.name port | " - "del protocol.name]"), + "del protocol.name | raw]"), N_(" list: list relay clients (only active " "relays)\n" " listfull: list relay clients (verbose, all " @@ -272,13 +278,15 @@ relay_command_init () " del: remove relay for a protocol + name\n" "protocol.name: protocol and name to relay\n" " for example: irc.freenode\n" - " port: port used for relay\n\n" + " port: port used for relay\n" + " raw: open buffer with raw Relay data\n\n" "Without argument, this command opens buffer " "with list of relay clients."), "list %(relay_relays)" " || listfull %(relay_relays)" " || listrelay" " || add %(relay_protocol_name) %(relay_free_port)" - " || del %(relay_relays)", + " || del %(relay_relays)" + " || raw", &relay_command_relay, NULL); } diff --git a/src/plugins/relay/relay-config.c b/src/plugins/relay/relay-config.c index d5b3f940d..1e99113ee 100644 --- a/src/plugins/relay/relay-config.c +++ b/src/plugins/relay/relay-config.c @@ -38,6 +38,7 @@ struct t_config_section *relay_config_section_port = NULL; /* relay config, look section */ struct t_config_option *relay_config_look_auto_open_buffer; +struct t_config_option *relay_config_look_raw_messages; /* relay config, color section */ @@ -257,6 +258,12 @@ relay_config_init () "auto_open_buffer", "boolean", N_("auto open relay buffer when a new client is connecting"), NULL, 0, 0, "on", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL); + relay_config_look_raw_messages = weechat_config_new_option ( + relay_config_file, ptr_section, + "raw_messages", "integer", + N_("number of raw messages to save in memory when raw data buffer is " + "closed (messages will be displayed when opening raw data buffer)"), + NULL, 0, 65535, "256", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL); ptr_section = weechat_config_new_section (relay_config_file, "color", 0, 0, diff --git a/src/plugins/relay/relay-config.h b/src/plugins/relay/relay-config.h index 5790b3261..a6f14b54a 100644 --- a/src/plugins/relay/relay-config.h +++ b/src/plugins/relay/relay-config.h @@ -26,6 +26,7 @@ extern struct t_config_file *relay_config_file; extern struct t_config_section *relay_config_section_port; extern struct t_config_option *relay_config_look_auto_open_buffer; +extern struct t_config_option *relay_config_look_raw_messages; extern struct t_config_option *relay_config_color_text; extern struct t_config_option *relay_config_color_text_bg; diff --git a/src/plugins/relay/relay-protocol-irc.c b/src/plugins/relay/relay-protocol-irc.c deleted file mode 100644 index ca2723221..000000000 --- a/src/plugins/relay/relay-protocol-irc.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * Copyright (C) 2003-2010 Sebastien Helleu <flashcode@flashtux.org> - * - * This file is part of WeeChat, the extensible chat client. - * - * WeeChat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * WeeChat is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with WeeChat. If not, see <http://www.gnu.org/licenses/>. - */ - -/* - * relay-protocol-irc.c: IRC protocol for relay to client - * (relay acting as an IRC proxy/bouncer) - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <time.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <errno.h> - -#include "../weechat-plugin.h" -#include "relay.h" -#include "relay-protocol-irc.h" -#include "relay-client.h" - - -/* - * relay_protocol_irc_search_buffer: search IRC buffer with server and channel - * name - */ - -struct t_gui_buffer * -relay_protocol_irc_search_buffer (const char *server, const char *channel) -{ - char string[256]; - long unsigned int value; - const char *str_ptr_buffer; - - snprintf (string, sizeof (string), "%s,%s", server, channel); - str_ptr_buffer = weechat_info_get ("irc_buffer", string); - if (str_ptr_buffer && str_ptr_buffer[0]) - { - sscanf (str_ptr_buffer, "%lx", &value); - return (struct t_gui_buffer *)value; - } - - return NULL; -} - -/* - * relay_protocol_irc_sendf: send formatted data to client - */ - -int -relay_protocol_irc_sendf (struct t_relay_client *client, const char *format, ...) -{ - va_list args; - static char buffer[4096]; - int length, num_sent; - - if (!client) - return 0; - - va_start (args, format); - vsnprintf (buffer, sizeof (buffer) - 3, format, args); - va_end (args); - - if (weechat_relay_plugin->debug) - { - weechat_printf (NULL, "relay: send: %s", buffer); - } - - length = strlen (buffer); - - buffer[length] = '\r'; - buffer[length + 1] = '\n'; - buffer[length + 2] = '\0'; - length += 2; - - num_sent = send (client->sock, buffer, length, 0); - - if (num_sent >= 0) - client->bytes_sent += num_sent; - else - { - weechat_printf (NULL, - _("%s%s: error sending data to client %s"), - weechat_prefix ("error"), RELAY_PLUGIN_NAME, - strerror (errno)); - } - - return num_sent; -} - -/* - * relay_protocol_irc_signal_irc_in2_cb: callback for "irc_in2" IRC signal - */ - -int -relay_protocol_irc_signal_irc_in2_cb (void *data, const char *signal, - const char *type_data, void *signal_data) -{ - struct t_relay_client *client; - const char *ptr_msg; - char *host, *pos, *pos_end_nick; - - (void) signal; - (void) type_data; - - client = (struct t_relay_client *)data; - ptr_msg = (const char *)signal_data; - - if (weechat_relay_plugin->debug) - { - weechat_printf (NULL, "relay: irc_in2: client: %s, data: %s", - client->protocol_string, - ptr_msg); - } - - if (ptr_msg[0] == ':') - { - pos = strchr (ptr_msg, ' '); - if (pos) - { - host = weechat_strndup (ptr_msg + 1, pos - ptr_msg); - if (host) - { - pos_end_nick = strchr (host, '!'); - if (pos_end_nick) - pos_end_nick[0] = '\0'; - else - host[0] = '\0'; - - pos++; - while (pos[0] == ' ') - { - pos++; - } - - relay_protocol_irc_sendf (client, ":%s%s%s %s", - (host[0]) ? host : "", - (host[0]) ? "!" : "", - RELAY_IRC_DATA(client, address), - pos); - free (host); - } - return WEECHAT_RC_OK; - } - } - - relay_protocol_irc_sendf (client, "%s", ptr_msg); - - return WEECHAT_RC_OK; -} - -/* - * relay_protocol_irc_signal_irc_out_cb: callback for "irc_out" IRC signal - */ - -int -relay_protocol_irc_signal_irc_out_cb (void *data, const char *signal, - const char *type_data, void *signal_data) -{ - struct t_relay_client *client; - - (void) signal; - (void) type_data; - - client = (struct t_relay_client *)data; - - if (weechat_relay_plugin->debug) - { - weechat_printf (NULL, "relay: irc_out: client: %s, data: %s", - client->protocol_string, - (char *)signal_data); - } - - return WEECHAT_RC_OK; -} - -/* - * relay_protocol_irc_send_join: send join for a channel to client - */ - -void -relay_protocol_irc_send_join (struct t_relay_client *client, - const char *channel) -{ - char *infolist_name, *nicks; - const char *nick; - int length, length_nicks; - struct t_infolist *infolist_nicks; - - length = strlen (client->protocol_string) + 1 + strlen (channel) + 1; - infolist_name = malloc (length); - if (infolist_name) - { - relay_protocol_irc_sendf (client, - ":%s!%s@proxy JOIN %s", - RELAY_IRC_DATA(client, nick), - "weechat", - channel); - snprintf (infolist_name, length, "%s,%s", - client->protocol_string, - channel); - infolist_nicks = weechat_infolist_get ("irc_nick", NULL, infolist_name); - if (infolist_nicks) - { - length_nicks = 0; - nicks = NULL; - while (weechat_infolist_next (infolist_nicks)) - { - nick = weechat_infolist_string (infolist_nicks, "name"); - if (nick && nick[0]) - { - if (length_nicks == 0) - { - length_nicks = strlen (nick) + 1; - nicks = malloc (length_nicks); - strcpy (nicks, nick); - } - else - { - length_nicks += strlen (nick) + 1; - nicks = realloc (nicks, length_nicks); - strcat (nicks, " "); - strcat (nicks, nick); - } - } - } - if (nicks) - { - relay_protocol_irc_sendf (client, - ":%s 353 %s = %s :%s", - RELAY_IRC_DATA(client, address), - RELAY_IRC_DATA(client, nick), - channel, nicks); - free (nicks); - } - weechat_infolist_free (infolist_nicks); - } - relay_protocol_irc_sendf (client, - ":%s 366 %s %s :End of /NAMES list.", - RELAY_IRC_DATA(client, address), - RELAY_IRC_DATA(client, nick), - channel); - free (infolist_name); - } -} - -/* - * relay_protocol_irc_send_join_channels: send join for all channels of server - * to client - */ - -void -relay_protocol_irc_send_join_channels (struct t_relay_client *client) -{ - struct t_infolist *infolist_channels; - const char *channel; - - infolist_channels = weechat_infolist_get ("irc_channel", NULL, - client->protocol_string); - if (infolist_channels) - { - while (weechat_infolist_next (infolist_channels)) - { - channel = weechat_infolist_string (infolist_channels, "name"); - relay_protocol_irc_send_join (client, channel); - } - weechat_infolist_free (infolist_channels); - } -} - -/* - * relay_protocol_irc_recv_one_msg: read one message from client - */ - -void -relay_protocol_irc_recv_one_msg (struct t_relay_client *client, char *data) -{ - char *pos, str_time[128], **argv, **argv_eol, str_signal_name[128]; - char *command; - int argc, length; - const char *nick; - struct t_gui_buffer *ptr_buffer; - - pos = strchr (data, '\r'); - if (pos) - pos[0] = '\0'; - - if (weechat_relay_plugin->debug) - { - weechat_printf (NULL, "relay: recv from client: \"%s\"", data); - } - - argv = weechat_string_split (data, " ", 0, 0, &argc); - argv_eol = weechat_string_split (data, " ", 1, 0, &argc); - - if (!RELAY_IRC_DATA(client, connected)) - { - if (weechat_strncasecmp (data, "nick ", 5) == 0) - { - if (data[5]) - { - if (RELAY_IRC_DATA(client, nick)) - free (RELAY_IRC_DATA(client, nick)); - RELAY_IRC_DATA(client, nick) = strdup (data + 5); - } - } - if (weechat_strncasecmp (data, "user ", 5) == 0) - { - if (data[5]) - { - RELAY_IRC_DATA(client, user_received) = 1; - } - } - if (RELAY_IRC_DATA(client, nick) && RELAY_IRC_DATA(client, user_received)) - { - RELAY_IRC_DATA(client, connected) = 1; - - /* - * send nick to client if server nick is different of nick asked - * by client with command NICK - */ - nick = weechat_info_get ("irc_nick", client->protocol_string); - if (nick && (strcmp (nick, RELAY_IRC_DATA(client, nick)) != 0)) - { - relay_protocol_irc_sendf (client, - ":%s!proxy NICK :%s", - RELAY_IRC_DATA(client, nick), - nick); - free (RELAY_IRC_DATA(client, nick)); - RELAY_IRC_DATA(client, nick) = strdup (nick); - } - - relay_protocol_irc_sendf (client, - ":%s 001 %s :Welcome to the Internet " - "Relay Network %s!%s@proxy", - RELAY_IRC_DATA(client, address), - RELAY_IRC_DATA(client, nick), - RELAY_IRC_DATA(client, nick), - "weechat"); - relay_protocol_irc_sendf (client, - ":%s 002 %s :Your host is " - "weechat-relay-irc, running version %s", - RELAY_IRC_DATA(client, address), - RELAY_IRC_DATA(client, nick), - weechat_info_get("version", NULL)); - snprintf (str_time, sizeof (str_time), "%s", - ctime (&client->listen_start_time)); - if (str_time[0]) - str_time[strlen (str_time) - 1] = '\0'; - relay_protocol_irc_sendf (client, - ":%s 003 %s :This server was created " - "on %s", - RELAY_IRC_DATA(client, address), - RELAY_IRC_DATA(client, nick), - str_time); - relay_protocol_irc_sendf (client, - ":%s 004 %s %s %s oirw abiklmnopqstv", - RELAY_IRC_DATA(client, address), - RELAY_IRC_DATA(client, nick), - RELAY_IRC_DATA(client, address), - weechat_info_get("version", NULL)); - relay_protocol_irc_sendf (client, - ":%s 251 %s :There are %d users and 0 " - "invisible on 1 servers", - RELAY_IRC_DATA(client, address), - RELAY_IRC_DATA(client, nick), - relay_client_count); - relay_protocol_irc_sendf (client, - ":%s 255 %s :I have %d clients, 0 " - "services and 0 servers", - RELAY_IRC_DATA(client, address), - RELAY_IRC_DATA(client, nick), - relay_client_count); - relay_protocol_irc_sendf (client, - ":%s 422 %s :MOTD File is missing", - RELAY_IRC_DATA(client, address), - RELAY_IRC_DATA(client, nick)); - - /* - * hook signal "xxx,irc_in2_*" to catch IRC data received from - * this server - */ - snprintf (str_signal_name, sizeof (str_signal_name), - "%s,irc_in2_*", - client->protocol_string); - RELAY_IRC_DATA(client, hook_signal_irc_in2) = - weechat_hook_signal (str_signal_name, - &relay_protocol_irc_signal_irc_in2_cb, - client); - - /* - * hook signal "xxx,irc_out_*" to catch IRC data sent to - * this server - */ - snprintf (str_signal_name, sizeof (str_signal_name), - "%s,irc_out_*", - client->protocol_string); - RELAY_IRC_DATA(client, hook_signal_irc_out) = - weechat_hook_signal (str_signal_name, - &relay_protocol_irc_signal_irc_out_cb, - client); - - /* send JOIN for all channels on server to client */ - relay_protocol_irc_send_join_channels (client); - } - } - else - { - if (argc > 0) - { - if (weechat_strcasecmp (argv[0], "privmsg") == 0) - { - ptr_buffer = relay_protocol_irc_search_buffer (client->protocol_string, - argv[1]); - if (ptr_buffer) - { - weechat_printf (NULL, - "relay: send string \"%s\" on channel %s", - (argv_eol[2][0] == ':') ? argv_eol[2] + 1 : argv_eol[2], - argv[1]); - weechat_command (ptr_buffer, - (argv_eol[2][0] == ':') ? argv_eol[2] + 1 : argv_eol[2]); - } - else - { - weechat_printf (NULL, - _("%s%s: buffer not found for IRC server " - "\"%s\", channel \"%s\""), - weechat_prefix ("error"), - RELAY_PLUGIN_NAME, - client->protocol_string, - argv[1]); - } - } - else - { - length = 32 + strlen (client->protocol_string) + strlen (data); - command = malloc (length + 1); - if (command) - { - snprintf (command, length, "/quote -server %s %s", - client->protocol_string, - data); - weechat_command (NULL, command); - free (command); - } - } - } - } - - if (argv) - weechat_string_free_split (argv); - if (argv_eol) - weechat_string_free_split (argv_eol); -} - -/* - * relay_protocol_irc_recv: read data from client - */ - -void -relay_protocol_irc_recv (struct t_relay_client *client, const char *data) -{ - char **items; - int items_count, i; - - items = weechat_string_split (data, "\n", 0, 0, &items_count); - for (i = 0; i < items_count; i++) - { - relay_protocol_irc_recv_one_msg (client, items[i]); - } - if (items) - weechat_string_free_split (items); -} - -/* - * relay_protocol_irc_alloc: init relay data specific to IRC protocol - */ - -void -relay_protocol_irc_alloc (struct t_relay_client *client) -{ - struct t_relay_protocol_irc_data *irc_data; - - client->protocol_data = malloc (sizeof (*irc_data)); - if (client->protocol_data) - { - RELAY_IRC_DATA(client, address) = strdup ("weechat.relay.irc"); - RELAY_IRC_DATA(client, nick) = NULL; - RELAY_IRC_DATA(client, user_received) = 0; - RELAY_IRC_DATA(client, connected) = 0; - RELAY_IRC_DATA(client, hook_signal_irc_in2) = NULL; - RELAY_IRC_DATA(client, hook_signal_irc_out) = NULL; - } -} - -/* - * relay_protocol_irc_free: free relay data specific to IRC protocol - */ - -void -relay_protocol_irc_free (struct t_relay_client *client) -{ - if (client->protocol_data) - { - if (RELAY_IRC_DATA(client, address)) - free (RELAY_IRC_DATA(client, address)); - if (RELAY_IRC_DATA(client, nick)) - free (RELAY_IRC_DATA(client, nick)); - if (RELAY_IRC_DATA(client, hook_signal_irc_in2)) - weechat_unhook (RELAY_IRC_DATA(client, hook_signal_irc_in2)); - if (RELAY_IRC_DATA(client, hook_signal_irc_out)) - weechat_unhook (RELAY_IRC_DATA(client, hook_signal_irc_out)); - - free (client->protocol_data); - } -} - -/* - * relay_protocol_irc_print_log: print IRC client infos in log (usually for - * crash dump) - */ - -void -relay_protocol_irc_print_log (struct t_relay_client *client) -{ - if (client->protocol_data) - { - weechat_log_printf (" address. . . . . . : '%s'", RELAY_IRC_DATA(client, address)); - weechat_log_printf (" nick . . . . . . . : '%s'", RELAY_IRC_DATA(client, nick)); - weechat_log_printf (" user_received. . . : %d", RELAY_IRC_DATA(client, user_received)); - weechat_log_printf (" connected. . . . . : %d", RELAY_IRC_DATA(client, connected)); - weechat_log_printf (" hook_signal_irc_in2: 0x%lx", RELAY_IRC_DATA(client, hook_signal_irc_in2)); - weechat_log_printf (" hook_signal_irc_out: 0x%lx", RELAY_IRC_DATA(client, hook_signal_irc_out)); - } -} diff --git a/src/plugins/relay/relay-raw.c b/src/plugins/relay/relay-raw.c new file mode 100644 index 000000000..1be5b0754 --- /dev/null +++ b/src/plugins/relay/relay-raw.c @@ -0,0 +1,370 @@ +/* + * Copyright (C) 2003-2010 Sebastien Helleu <flashcode@flashtux.org> + * + * This file is part of WeeChat, the extensible chat client. + * + * WeeChat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WeeChat. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * relay-raw.c: functions for Relay raw data messages + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> + +#include "../weechat-plugin.h" +#include "relay.h" +#include "relay-raw.h" +#include "relay-client.h" +#include "relay-config.h" + + +struct t_gui_buffer *relay_raw_buffer = NULL; + +int relay_raw_messages_count = 0; +struct t_relay_raw_message *relay_raw_messages = NULL; +struct t_relay_raw_message *last_relay_raw_message = NULL; + + +/* + * relay_raw_message_print: print a relay raw message + */ + +void +relay_raw_message_print (struct t_relay_raw_message *raw_message) +{ + if (relay_raw_buffer && raw_message) + { + weechat_printf_date_tags (relay_raw_buffer, + raw_message->date, NULL, + "%s\t%s", + raw_message->prefix, + raw_message->message); + } +} + +/* + * relay_raw_input_data_cb: callback for input data in Relay raw buffer + */ + +int +relay_raw_input_data_cb (void *data, struct t_gui_buffer *buffer, + const char *input_data) +{ + /* make C compiler happy */ + (void) data; + + if (weechat_strcasecmp (input_data, "q") == 0) + weechat_buffer_close (buffer); + + return WEECHAT_RC_OK; +} + +/* + * relay_raw_buffer_close_cb: callback called when Relay raw buffer is closed + */ + +int +relay_raw_buffer_close_cb (void *data, struct t_gui_buffer *buffer) +{ + /* make C compiler happy */ + (void) data; + (void) buffer; + + relay_raw_buffer = NULL; + + return WEECHAT_RC_OK; +} + +/* + * relay_raw_open: open Relay raw buffer + */ + +void +relay_raw_open (int switch_to_buffer) +{ + struct t_relay_raw_message *ptr_raw_message; + + if (!relay_raw_buffer) + { + relay_raw_buffer = weechat_buffer_search (RELAY_PLUGIN_NAME, + RELAY_RAW_BUFFER_NAME); + if (!relay_raw_buffer) + { + relay_raw_buffer = weechat_buffer_new (RELAY_RAW_BUFFER_NAME, + &relay_raw_input_data_cb, NULL, + &relay_raw_buffer_close_cb, NULL); + + /* failed to create buffer ? then return */ + if (!relay_raw_buffer) + return; + + weechat_buffer_set (relay_raw_buffer, + "title", _("Relay raw messages")); + + weechat_buffer_set (relay_raw_buffer, "short_name", RELAY_RAW_BUFFER_NAME); + weechat_buffer_set (relay_raw_buffer, "localvar_set_type", "debug"); + weechat_buffer_set (relay_raw_buffer, "localvar_set_server", RELAY_RAW_BUFFER_NAME); + weechat_buffer_set (relay_raw_buffer, "localvar_set_channel", RELAY_RAW_BUFFER_NAME); + weechat_buffer_set (relay_raw_buffer, "localvar_set_no_log", "1"); + + /* disable all highlights on this buffer */ + weechat_buffer_set (relay_raw_buffer, "highlight_words", "-"); + + /* print messages in list */ + for (ptr_raw_message = relay_raw_messages; ptr_raw_message; + ptr_raw_message = ptr_raw_message->next_message) + { + relay_raw_message_print (ptr_raw_message); + } + } + } + + if (relay_raw_buffer && switch_to_buffer) + weechat_buffer_set (relay_raw_buffer, "display", "1"); +} + +/* + * relay_raw_message_free: free a raw message and remove it from list + */ + +void +relay_raw_message_free (struct t_relay_raw_message *raw_message) +{ + struct t_relay_raw_message *new_raw_messages; + + /* remove message from raw messages list */ + if (last_relay_raw_message == raw_message) + last_relay_raw_message = raw_message->prev_message; + if (raw_message->prev_message) + { + (raw_message->prev_message)->next_message = raw_message->next_message; + new_raw_messages = relay_raw_messages; + } + else + new_raw_messages = raw_message->next_message; + + if (raw_message->next_message) + (raw_message->next_message)->prev_message = raw_message->prev_message; + + /* free data */ + if (raw_message->prefix) + free (raw_message->prefix); + if (raw_message->message) + free (raw_message->message); + + free (raw_message); + + relay_raw_messages = new_raw_messages; + + relay_raw_messages_count--; +} + +/* + * relay_raw_message_free_all: free all raw messages + */ + +void +relay_raw_message_free_all () +{ + while (relay_raw_messages) + { + relay_raw_message_free (relay_raw_messages); + } +} + +/* + * relay_raw_message_remove_old: remove old raw messages if limit has been + * reached + */ + +void +relay_raw_message_remove_old () +{ + int max_messages; + + max_messages = weechat_config_integer (relay_config_look_raw_messages); + while (relay_raw_messages && (relay_raw_messages_count >= max_messages)) + { + relay_raw_message_free (relay_raw_messages); + } +} + +/* + * relay_raw_message_add_to_list: add new message to list + */ + +struct t_relay_raw_message * +relay_raw_message_add_to_list (time_t date, const char *prefix, + const char *message) +{ + struct t_relay_raw_message *new_raw_message; + + relay_raw_message_remove_old (); + + new_raw_message = malloc (sizeof (*new_raw_message)); + if (new_raw_message) + { + new_raw_message->date = date; + new_raw_message->prefix = strdup (prefix); + new_raw_message->message = strdup (message); + + /* add message to list */ + new_raw_message->prev_message = last_relay_raw_message; + new_raw_message->next_message = NULL; + if (relay_raw_messages) + last_relay_raw_message->next_message = new_raw_message; + else + relay_raw_messages = new_raw_message; + last_relay_raw_message = new_raw_message; + + relay_raw_messages_count++; + } + + return new_raw_message; +} + +/* + * relay_raw_message_add: add new message to list + */ + +struct t_relay_raw_message * +relay_raw_message_add (struct t_relay_client *client, int send, + const char *message) +{ + char *buf, *buf2, prefix[256]; + const unsigned char *ptr_buf; + const char *hexa = "0123456789ABCDEF"; + int pos_buf, pos_buf2, char_size, i; + struct t_relay_raw_message *new_raw_message; + + buf = weechat_iconv_to_internal (NULL, message); + buf2 = malloc ((strlen (buf) * 3) + 1); + if (buf2) + { + ptr_buf = (buf) ? (unsigned char *)buf : (unsigned char *)message; + pos_buf = 0; + pos_buf2 = 0; + while (ptr_buf[pos_buf]) + { + if (ptr_buf[pos_buf] < 32) + { + buf2[pos_buf2++] = '\\'; + buf2[pos_buf2++] = hexa[ptr_buf[pos_buf] / 16]; + buf2[pos_buf2++] = hexa[ptr_buf[pos_buf] % 16]; + pos_buf++; + } + else + { + char_size = weechat_utf8_char_size ((const char *)(ptr_buf + pos_buf)); + for (i = 0; i < char_size; i++) + { + buf2[pos_buf2++] = ptr_buf[pos_buf++]; + } + } + } + buf2[pos_buf2] = '\0'; + } + + if (client) + { + snprintf (prefix, sizeof (prefix), "%s[%s%d%s] %s%s %s%s", + weechat_color ("chat_delimiters"), + weechat_color ("chat"), + client->id, + weechat_color ("chat_delimiters"), + weechat_color ("chat_server"), + client->protocol_string, + (send) ? + weechat_color ("chat_prefix_quit") : + weechat_color ("chat_prefix_join"), + (send) ? RELAY_RAW_PREFIX_SEND : RELAY_RAW_PREFIX_RECV); + } + else + { + snprintf (prefix, sizeof (prefix), "%s%s", + (send) ? + weechat_color ("chat_prefix_quit") : + weechat_color ("chat_prefix_join"), + (send) ? RELAY_RAW_PREFIX_SEND : RELAY_RAW_PREFIX_RECV); + } + + new_raw_message = relay_raw_message_add_to_list (time (NULL), + prefix, + (buf2) ? buf2 : ((buf) ? buf : message)); + + if (buf) + free (buf); + if (buf2) + free (buf2); + + return new_raw_message; +} + +/* + * relay_raw_print: print a message on Relay raw buffer + */ + +void +relay_raw_print (struct t_relay_client *client, int send, const char *message) +{ + struct t_relay_raw_message *new_raw_message; + + if (!message) + return; + + /* auto-open Relay raw buffer if debug for irc plugin is >= 1 */ + if (!relay_raw_buffer && (weechat_relay_plugin->debug >= 1)) + relay_raw_open (0); + + new_raw_message = relay_raw_message_add (client, send, message); + if (new_raw_message) + { + if (relay_raw_buffer) + relay_raw_message_print (new_raw_message); + if (weechat_config_integer (relay_config_look_raw_messages) == 0) + relay_raw_message_free (new_raw_message); + } +} + +/* + * relay_raw_add_to_infolist: add a raw message in an infolist + * return 1 if ok, 0 if error + */ + +int +relay_raw_add_to_infolist (struct t_infolist *infolist, + struct t_relay_raw_message *raw_message) +{ + struct t_infolist_item *ptr_item; + + if (!infolist || !raw_message) + return 0; + + ptr_item = weechat_infolist_new_item (infolist); + if (!ptr_item) + return 0; + + if (!weechat_infolist_new_var_time (ptr_item, "date", raw_message->date)) + return 0; + if (!weechat_infolist_new_var_string (ptr_item, "prefix", raw_message->prefix)) + return 0; + if (!weechat_infolist_new_var_string (ptr_item, "message", raw_message->message)) + return 0; + + return 1; +} diff --git a/src/plugins/relay/relay-raw.h b/src/plugins/relay/relay-raw.h new file mode 100644 index 000000000..ed0d2a577 --- /dev/null +++ b/src/plugins/relay/relay-raw.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2003-2010 Sebastien Helleu <flashcode@flashtux.org> + * + * This file is part of WeeChat, the extensible chat client. + * + * WeeChat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WeeChat. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __WEECHAT_RELAY_RAW_H +#define __WEECHAT_RELAY_RAW_H 1 + +#define RELAY_RAW_BUFFER_NAME "relay_raw" +#define RELAY_RAW_PREFIX_RECV "-->" +#define RELAY_RAW_PREFIX_SEND "<--" + +struct t_relay_raw_message +{ + time_t date; /* date/time of message */ + char *prefix; /* prefix */ + char *message; /* message */ + struct t_relay_raw_message *prev_message; /* pointer to prev. message */ + struct t_relay_raw_message *next_message; /* pointer to next message */ +}; + +struct t_relay_client; + +extern struct t_gui_buffer *relay_raw_buffer; +extern int irc_relay_messages_count; +extern struct t_relay_raw_message *relay_raw_messages, *last_relay_raw_message; + +extern void relay_raw_open (int switch_to_buffer); +extern struct t_relay_raw_message *relay_raw_message_add_to_list (time_t date, + const char *prefix, + const char *message); +extern void relay_raw_print (struct t_relay_client *client, int send, + const char *message); +extern void relay_raw_message_free_all (); +extern int relay_raw_add_to_infolist (struct t_infolist *infolist, + struct t_relay_raw_message *raw_message); + +#endif /* __WEECHAT_RELAY_RAW_H */ |