diff options
author | Timo Sirainen <cras@irssi.org> | 2004-08-20 00:03:40 +0000 |
---|---|---|
committer | cras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564> | 2004-08-20 00:03:40 +0000 |
commit | 226a567562cf1f9a95ea08383838e11c20fb98c3 (patch) | |
tree | 484a82b46cf0ae9e93002b567c8dd43e70fefaf8 | |
parent | 924ac8f91f87d9034dedb711ec33fe714f91a860 (diff) | |
download | irssi-226a567562cf1f9a95ea08383838e11c20fb98c3.zip |
Recode patch by decadix/senneth
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@3283 dbcabf3a-b0e7-0310-adc4-f8d773084564
-rw-r--r-- | acconfig.h | 1 | ||||
-rw-r--r-- | configure.in | 11 | ||||
-rw-r--r-- | src/core/Makefile.am | 2 | ||||
-rw-r--r-- | src/core/chat-commands.c | 12 | ||||
-rw-r--r-- | src/core/core.c | 3 | ||||
-rw-r--r-- | src/fe-common/core/Makefile.am | 2 | ||||
-rw-r--r-- | src/fe-common/core/chat-completion.c | 54 | ||||
-rw-r--r-- | src/fe-common/core/fe-common-core.c | 3 | ||||
-rw-r--r-- | src/fe-common/core/fe-queries.c | 2 | ||||
-rw-r--r-- | src/fe-common/core/formats.c | 78 | ||||
-rw-r--r-- | src/fe-common/core/module-formats.c | 11 | ||||
-rw-r--r-- | src/fe-common/core/module-formats.h | 10 | ||||
-rw-r--r-- | src/fe-common/core/printtext.c | 12 | ||||
-rw-r--r-- | src/fe-common/irc/fe-irc-commands.c | 29 | ||||
-rw-r--r-- | src/fe-text/statusbar.c | 13 | ||||
-rw-r--r-- | src/fe-text/term.c | 4 | ||||
-rw-r--r-- | src/irc/core/channel-events.c | 10 | ||||
-rw-r--r-- | src/irc/core/irc-commands.c | 76 | ||||
-rw-r--r-- | src/irc/proxy/dump.c | 4 | ||||
-rw-r--r-- | src/irc/proxy/listen.c | 15 |
20 files changed, 289 insertions, 63 deletions
@@ -14,6 +14,7 @@ #undef HAVE_GC_GC_H #undef WANT_BIG5 #undef USE_GC +#undef HAVE_GLIB2 /* macros/curses checks */ #undef HAS_CURSES diff --git a/configure.in b/configure.in index b13c7c42..122ff9d9 100644 --- a/configure.in +++ b/configure.in @@ -517,6 +517,17 @@ if test "x$want_gc" = xyes; then fi dnl ** +dnl ** Recode +dnl ** +AC_MSG_CHECKING([if we can use recode, requires GLIB2]) +if test "$glib_config_major_version" = "2"; then + AC_DEFINE(HAVE_GLIB2) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no, using glib1]) +fi + +dnl ** dnl ** check if we can link dynamic libraries to modules dnl ** also checks if libraries are built to .libs dir dnl ** diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 707f8b86..59ae0a8d 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -36,6 +36,7 @@ libcore_a_SOURCES = \ pidwait.c \ queries.c \ rawlog.c \ + recode.c \ servers.c \ servers-reconnect.c \ servers-setup.c \ @@ -84,6 +85,7 @@ pkginc_core_HEADERS = \ pidwait.h \ queries.h \ rawlog.h \ + recode.h \ servers.h \ servers-reconnect.h \ servers-setup.h \ diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index 85576df8..06fe5ce2 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -24,6 +24,7 @@ #include "commands.h" #include "special-vars.h" #include "settings.h" +#include "recode.h" #include "chat-protocols.h" #include "servers.h" @@ -349,7 +350,7 @@ static void cmd_join(const char *data, SERVER_REC *server) static void cmd_msg(const char *data, SERVER_REC *server, WI_ITEM_REC *item) { GHashTable *optlist; - char *target, *origtarget, *msg; + char *target, *origtarget, *msg, *recoded; void *free_arg; int free_ret, target_type = SEND_TARGET_NICK; @@ -401,15 +402,16 @@ static void cmd_msg(const char *data, SERVER_REC *server, WI_ITEM_REC *item) SEND_TARGET_CHANNEL : SEND_TARGET_NICK; } } - + recoded = recode_out(msg, target); if (target != NULL) { - signal_emit("server sendmsg", 4, server, target, msg, + signal_emit("server sendmsg", 4, server, target, recoded, GINT_TO_POINTER(target_type)); } signal_emit(target != NULL && target_type == SEND_TARGET_CHANNEL ? "message own_public" : "message own_private", 4, - server, msg, target, origtarget); - + server, recoded, target, origtarget); + + g_free(recoded); if (free_ret && target != NULL) g_free(target); cmd_params_free(free_arg); } diff --git a/src/core/core.c b/src/core/core.c index b4e6d6e0..6b1aad56 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -40,6 +40,7 @@ #include "log.h" #include "rawlog.h" #include "ignore.h" +#include "recode.h" #include "channels.h" #include "queries.h" @@ -241,6 +242,7 @@ void core_init(int argc, char *argv[]) log_init(); log_away_init(); rawlog_init(); + recode_init(); channels_init(); queries_init(); @@ -276,6 +278,7 @@ void core_deinit(void) queries_deinit(); channels_deinit(); + recode_deinit(); rawlog_deinit(); log_away_deinit(); log_deinit(); diff --git a/src/fe-common/core/Makefile.am b/src/fe-common/core/Makefile.am index b7c57414..75ff7a9a 100644 --- a/src/fe-common/core/Makefile.am +++ b/src/fe-common/core/Makefile.am @@ -30,6 +30,7 @@ libfe_common_core_a_SOURCES = \ keyboard.c \ module-formats.c \ printtext.c \ + fe-recode.c \ themes.c \ translation.c \ window-activity.c \ @@ -56,6 +57,7 @@ pkginc_fe_common_core_HEADERS = \ module-formats.h \ module.h \ printtext.h \ + fe-recode.h \ themes.h \ translation.h \ window-activity.h \ diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index 9c04162d..fbd3d1d8 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -788,6 +788,36 @@ GList *completion_get_servers(const char *word) return list; } +GList *completion_get_targets(const char *word) +{ + CONFIG_NODE *node; + GList *list; + GSList *tmp; + int len; + + g_return_val_if_fail(word != NULL, NULL); + + len = strlen(word); + list = NULL; + + /* get the list of all conversion targets */ + node = iconfig_node_traverse("conversions", FALSE); + tmp = node == NULL ? NULL : config_node_first(node->value); + for (; tmp != NULL; tmp = config_node_next(tmp)) { + node = tmp->data; + + if (node->type != NODE_TYPE_KEY) + continue; + + if (len != 0 && g_strncasecmp(node->key, word, len) != 0) + continue; + + list = g_list_append(list, g_strdup(node->key)); + } + + return list; +} + static void sig_complete_connect(GList **list, WINDOW_REC *window, const char *word, const char *line, int *want_space) @@ -881,7 +911,6 @@ static void sig_complete_alias(GList **list, WINDOW_REC *window, } } - static void sig_complete_channel(GList **list, WINDOW_REC *window, const char *word, const char *line, int *want_space) @@ -904,6 +933,27 @@ static void sig_complete_server(GList **list, WINDOW_REC *window, if (*list != NULL) signal_stop(); } +static void sig_complete_target(GList **list, WINDOW_REC *window, + const char *word, const char *line, + int *want_space) +{ + const char *definition; + + g_return_if_fail(list != NULL); + g_return_if_fail(word != NULL); + g_return_if_fail(line != NULL); + + if (*line != '\0') { + if ((definition = iconfig_get_str("conversions", line ,NULL)) != NULL) { + *list = g_list_append(NULL, g_strdup(definition)); + signal_stop(); + } + } else { + *list = completion_get_targets(word); + if (*list != NULL) signal_stop(); + } +} + /* expand \n, \t and \\ */ static char *expand_escapes(const char *line, SERVER_REC *server, WI_ITEM_REC *item) @@ -1090,6 +1140,7 @@ void chat_completion_init(void) signal_add("complete command window item move", (SIGNAL_FUNC) sig_complete_channel); signal_add("complete command server add", (SIGNAL_FUNC) sig_complete_server); signal_add("complete command server remove", (SIGNAL_FUNC) sig_complete_server); + signal_add("complete command recode remove", (SIGNAL_FUNC) sig_complete_target); signal_add("message public", (SIGNAL_FUNC) sig_message_public); signal_add("message join", (SIGNAL_FUNC) sig_message_join); signal_add("message private", (SIGNAL_FUNC) sig_message_private); @@ -1126,6 +1177,7 @@ void chat_completion_deinit(void) signal_remove("complete command window item move", (SIGNAL_FUNC) sig_complete_channel); signal_remove("complete command server add", (SIGNAL_FUNC) sig_complete_server); signal_remove("complete command server remove", (SIGNAL_FUNC) sig_complete_server); + signal_remove("complete command recode remove", (SIGNAL_FUNC) sig_complete_target); signal_remove("message public", (SIGNAL_FUNC) sig_message_public); signal_remove("message join", (SIGNAL_FUNC) sig_message_join); signal_remove("message private", (SIGNAL_FUNC) sig_message_private); diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index d123b814..147d5448 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -46,6 +46,7 @@ #include "window-activity.h" #include "window-items.h" #include "windows-layout.h" +#include "fe-recode.h" #include <signal.h> @@ -202,6 +203,7 @@ void fe_common_core_init(void) fe_messages_init(); hilight_text_init(); fe_ignore_messages_init(); + fe_recode_init(); settings_check(); @@ -244,6 +246,7 @@ void fe_common_core_deinit(void) fe_messages_deinit(); fe_ignore_messages_deinit(); + fe_recode_deinit(); theme_unregister(); themes_deinit(); diff --git a/src/fe-common/core/fe-queries.c b/src/fe-common/core/fe-queries.c index f48e37e9..f1763814 100644 --- a/src/fe-common/core/fe-queries.c +++ b/src/fe-common/core/fe-queries.c @@ -322,7 +322,7 @@ static int sig_query_autoclose(void) now-rec->last_unread_msg > query_auto_close) query_destroy(rec); } - return 1; + return 1; } static void sig_message_private(SERVER_REC *server, const char *msg, diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index 22ed82be..2470ba26 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -275,7 +275,6 @@ void format_read_arglist(va_list va, FORMAT_REC *format, } } } - void format_create_dest(TEXT_DEST_REC *dest, void *server, const char *target, int level, WINDOW_REC *window) @@ -296,16 +295,50 @@ void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, dest->window = window != NULL ? window : window_find_closest(server, target, level); } +#ifdef HAVE_GLIB2 +static gboolean term_is_utf8 (void) +{ + const char *charset; + + charset = settings_get_str("term_charset"); + if (*charset) + return ! g_strcasecmp(charset, "utf-8"); + + return g_get_charset(&charset); +} + +static int advance (char const **str, gboolean utf8) +{ + if (utf8) { + gunichar c; + + c = g_utf8_get_char(*str); + *str = g_utf8_next_char(*str); + + return utf8_width(c); + } else { + *str += 1; + return 1; + } +} +#endif /* Return length of text part in string (ie. without % codes) */ int format_get_length(const char *str) { - GString *tmp; + GString *tmp; int len; +#ifdef HAVE_GLIB2 + gboolean utf8; +#endif + + g_return_val_if_fail(str != NULL, 0); - g_return_val_if_fail(str != NULL, 0); +#ifdef HAVE_GLIB2 + utf8 = term_is_utf8() && g_utf8_validate(str, -1, NULL); +#endif - tmp = g_string_new(NULL); + tmp = g_string_new(NULL); len = 0; while (*str != '\0') { if (*str == '%' && str[1] != '\0') { @@ -320,9 +353,12 @@ int format_get_length(const char *str) if (*str != '%') len++; } - - len++; +#ifdef HAVE_GLIB2 + len += advance(&str, utf8); +#else + len++; str++; +#endif } g_string_free(tmp, TRUE); @@ -336,12 +372,18 @@ int format_real_length(const char *str, int len) { GString *tmp; const char *start; - - g_return_val_if_fail(str != NULL, 0); - g_return_val_if_fail(len >= 0, 0); - - start = str; - tmp = g_string_new(NULL); +#ifdef HAVE_GLIB2 + gboolean utf8; +#endif + g_return_val_if_fail(str != NULL, 0); + g_return_val_if_fail(len >= 0, 0); + +#ifdef HAVE_GLIB2 + utf8 = term_is_utf8() && g_utf8_validate(str, -1, NULL); +#endif + + start = str; + tmp = g_string_new(NULL); while (*str != '\0' && len > 0) { if (*str == '%' && str[1] != '\0') { str++; @@ -358,8 +400,12 @@ int format_real_length(const char *str, int len) } } - len--; +#ifdef HAVE_GLIB2 + len -= advance(&str, utf8); +#else + len--; str++; +#endif } g_string_free(tmp, TRUE); @@ -883,7 +929,7 @@ char *strip_codes(const char *input) out = str = g_strdup(input); for (p = input; *p != '\0'; p++) { if (*p == 3) { - p++; + p++; /* mirc color */ get_mirc_color(&p, NULL, NULL); @@ -909,11 +955,11 @@ char *strip_codes(const char *input) p = get_ansi_color(current_theme, p, NULL, NULL, NULL); p--; } else if (!IS_COLOR_CODE(*p)) - *out++ = *p; + *out++ = *p; } *out = '\0'; - return str; + return str; } /* send a fully parsed text string for GUI to print */ diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index 0342f7e8..2bd4c23d 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -247,6 +247,17 @@ FORMAT_REC fecommon_core_formats[] = { { "ignore_footer", "", 0 }, /* ---- */ + { NULL, "Recode", 0 }, + + { "not_channel_or_query", "The current window is not a channel or query window", 0 }, + { "conversion_added", "Added {hilight $0}/{hilight $1} to conversion database", 2, { FORMAT_STRING, FORMAT_STRING } }, + { "conversion_removed", "Removed {hilight $0} from conversion database", 1, { FORMAT_STRING } }, + { "conversion_not_found", "{hilight $0} not found in conversion database", 1, { FORMAT_STRING } }, + { "conversion_not_supported", "Conversion to the character set {hilight $0} is not supported",1, { FORMAT_STRING } }, + { "recode_header", "%#Target Character set", 0 }, + { "recode_line", "%#%|$[!30]0 $1", 2, { FORMAT_STRING, FORMAT_STRING } }, + + /* ---- */ { NULL, "Misc", 0 }, { "unknown_chat_protocol", "Unknown chat protocol: $0", 1, { 0 } }, diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index d0092bd6..95465c33 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -215,6 +215,16 @@ enum { TXT_FILL_13, + TXT_NOT_CHANNEL_OR_QUERY, + TXT_CONVERSION_ADDED, + TXT_CONVERSION_REMOVED, + TXT_CONVERSION_NOT_FOUND, + TXT_CONVERSION_NOT_SUPPORTED, + TXT_RECODE_HEADER, + TXT_RECODE_LINE, + + TXT_FILL_14, + TXT_UNKNOWN_CHAT_PROTOCOL, TXT_UNKNOWN_CHATNET, TXT_NOT_TOGGLE, diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c index 6cc64081..e51da230 100644 --- a/src/fe-common/core/printtext.c +++ b/src/fe-common/core/printtext.c @@ -23,6 +23,7 @@ #include "modules.h" #include "signals.h" #include "commands.h" +#include "recode.h" #include "settings.h" #include "levels.h" @@ -159,23 +160,26 @@ void printformat_module_gui(const char *module, int formatnum, ...) static void print_line(TEXT_DEST_REC *dest, const char *text) { THEME_REC *theme; - char *str, *tmp, *stripped; + char *str, *recoded, *tmp, *stripped; g_return_if_fail(dest != NULL); g_return_if_fail(text != NULL); - + theme = window_get_theme(dest->window); tmp = format_get_level_tag(theme, dest); str = !theme->info_eol ? format_add_linestart(text, tmp) : format_add_lineend(text, tmp); g_free_not_null(tmp); + + recoded = recode_in(str, dest->target); /* send both the formatted + stripped (for logging etc.) */ - stripped = strip_codes(str); - signal_emit_id(signal_print_text, 3, dest, str, stripped); + stripped = strip_codes(recoded); + signal_emit_id(signal_print_text, 3, dest, recoded, stripped); g_free_and_null(dest->hilight_color); g_free(str); + g_free(recoded); g_free(stripped); } diff --git a/src/fe-common/irc/fe-irc-commands.c b/src/fe-common/irc/fe-irc-commands.c index b1752d9d..0c948dee 100644 --- a/src/fe-common/irc/fe-irc-commands.c +++ b/src/fe-common/irc/fe-irc-commands.c @@ -22,6 +22,7 @@ #include "module-formats.h" #include "signals.h" #include "misc.h" +#include "recode.h" #include "special-vars.h" #include "settings.h" @@ -56,6 +57,9 @@ static const char *skip_target(const char *target) /* SYNTAX: ME <message> */ static void cmd_me(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { + const char *target; + char *recoded; + CMD_IRC_SERVER(server); if (!IS_IRC_ITEM(item)) return; @@ -63,11 +67,16 @@ static void cmd_me(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED); - signal_emit("message irc own_action", 3, server, data, + target = window_item_get_target(item); + recoded = recode_out(data, target); + + signal_emit("message irc own_action", 3, server, recoded, item->visible_name); irc_send_cmdv(server, "PRIVMSG %s :\001ACTION %s\001", - window_item_get_target(item), data); + target, recoded); + + g_free(recoded); } /* SYNTAX: ACTION [-<server tag>] <target> <message> */ @@ -75,6 +84,7 @@ static void cmd_action(const char *data, IRC_SERVER_REC *server) { GHashTable *optlist; const char *target, *text; + char *recoded; void *free_arg; CMD_IRC_SERVER(server); @@ -90,10 +100,13 @@ static void cmd_action(const char *data, IRC_SERVER_REC *server) if (server == NULL || !server->connected) cmd_param_error(CMDERR_NOT_CONNECTED); - irc_send_cmdv(server, "PRIVMSG %s :\001ACTION %s\001", target, text); + recoded = recode_out(text, target); + irc_send_cmdv(server, "PRIVMSG %s :\001ACTION %s\001", target, recoded); target = skip_target(target); - signal_emit("message irc own_action", 3, server, text, target); + signal_emit("message irc own_action", 3, server, recoded, target); + + g_free(recoded); cmd_params_free(free_arg); } @@ -101,6 +114,7 @@ static void cmd_notice(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { const char *target, *msg; + char *recoded; void *free_arg; CMD_IRC_SERVER(server); @@ -113,8 +127,11 @@ static void cmd_notice(const char *data, IRC_SERVER_REC *server, if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); - - signal_emit("message irc own_notice", 3, server, msg, target); + + recoded = recode_out(msg, target); + signal_emit("message irc own_notice", 3, server, recoded, target); + + g_free(recoded); cmd_params_free(free_arg); } diff --git a/src/fe-text/statusbar.c b/src/fe-text/statusbar.c index 689e4f9b..0de19e00 100644 --- a/src/fe-text/statusbar.c +++ b/src/fe-text/statusbar.c @@ -21,6 +21,7 @@ #include "module.h" #include "signals.h" #include "expandos.h" +#include "recode.h" #include "special-vars.h" #include "themes.h" @@ -684,8 +685,10 @@ void statusbar_item_default_handler(SBAR_ITEM_REC *item, int get_size_only, int escape_vars) { SERVER_REC *server; - WI_ITEM_REC *wiitem; - char *tmpstr, *tmpstr2; + WI_ITEM_REC *wiitem; + char *tmpstr, *tmpstr2; + const char *target; + char *recoded; int len; if (str == NULL) @@ -724,7 +727,11 @@ void statusbar_item_default_handler(SBAR_ITEM_REC *item, int get_size_only, tmpstr2 = reverse_controls(tmpstr); g_free(tmpstr); - tmpstr = tmpstr2; + target = wiitem ? window_item_get_target(wiitem) : NULL; + recoded = recode_in(tmpstr2, target); + g_free(tmpstr2); + + tmpstr = recoded; if (get_size_only) { item->min_size = item->max_size = format_get_length(tmpstr); } else { diff --git a/src/fe-text/term.c b/src/fe-text/term.c index aa6200a1..5e62ce5d 100644 --- a/src/fe-text/term.c +++ b/src/fe-text/term.c @@ -119,7 +119,7 @@ static void read_settings(void) term_auto_detach(settings_get_bool("term_auto_detach")); /* set terminal type */ - str = settings_get_str("term_type"); + str = settings_get_str("term_charset"); if (g_strcasecmp(str, "utf-8") == 0) term_type = TERM_TYPE_UTF8; else if (g_strcasecmp(str, "big5") == 0) @@ -152,7 +152,7 @@ void term_common_init(void) settings_add_bool("lookandfeel", "term_force_colors", FALSE); settings_add_bool("lookandfeel", "term_auto_detach", FALSE); settings_add_bool("lookandfeel", "mirc_blink_fix", FALSE); - settings_add_str("lookandfeel", "term_type", "8bit"); + settings_add_str("lookandfeel", "term_charset", "ISO8859-1"); force_colors = FALSE; term_use_colors = term_has_colors() && settings_get_bool("colors"); diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index edaa3f9e..ac71e85f 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -23,6 +23,7 @@ #include "misc.h" #include "channels-setup.h" #include "settings.h" +#include "recode.h" #include "irc-servers.h" #include "irc-channels.h" @@ -136,13 +137,16 @@ static void channel_change_topic(IRC_SERVER_REC *server, const char *channel, time_t settime) { CHANNEL_REC *chanrec; - + char *recoded = NULL; + chanrec = channel_find(SERVER(server), channel); if (chanrec == NULL) return; - + /* the topic may be send out encoded, so we need to + recode it back or /topic <tab> will not work properly */ + recoded = recode_in(topic, channel); if (topic != NULL) { g_free_not_null(chanrec->topic); - chanrec->topic = *topic == '\0' ? NULL : g_strdup(topic); + chanrec->topic = recoded == NULL ? NULL : g_strdup(recoded); } g_free_not_null(chanrec->topic_by); diff --git a/src/irc/core/irc-commands.c b/src/irc/core/irc-commands.c index d398a4e7..bdd45d3b 100644 --- a/src/irc/core/irc-commands.c +++ b/src/irc/core/irc-commands.c @@ -20,6 +20,7 @@ #include "module.h" #include "misc.h" +#include "recode.h" #include "special-vars.h" #include "settings.h" #include "window-item-def.h" @@ -63,6 +64,7 @@ static void cmd_notice(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { const char *target, *msg; + char *recoded; void *free_arg; CMD_IRC_SERVER(server); @@ -75,7 +77,10 @@ static void cmd_notice(const char *data, IRC_SERVER_REC *server, if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); - g_string_sprintf(tmpstr, "NOTICE %s :%s", target, msg); + recoded = recode_out(msg, target); + g_string_sprintf(tmpstr, "NOTICE %s :%s", target, recoded); + g_free(recoded); + irc_send_cmd_split(server, tmpstr->str, 2, server->max_msgs_in_cmd); cmd_params_free(free_arg); @@ -102,8 +107,14 @@ static void cmd_ctcp(const char *data, IRC_SERVER_REC *server, g_strup(ctcpcmd); if (*ctcpdata == '\0') g_string_sprintf(tmpstr, "PRIVMSG %s :\001%s\001", target, ctcpcmd); - else - g_string_sprintf(tmpstr, "PRIVMSG %s :\001%s %s\001", target, ctcpcmd, ctcpdata); + else { + char *recoded; + + recoded = recode_out(ctcpdata, target); + g_string_sprintf(tmpstr, "PRIVMSG %s :\001%s %s\001", target, ctcpcmd, recoded); + g_free(recoded); + } + irc_send_cmd_split(server, tmpstr->str, 2, server->max_msgs_in_cmd); cmd_params_free(free_arg); @@ -114,7 +125,7 @@ static void cmd_nctcp(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { const char *target; - char *ctcpcmd, *ctcpdata; + char *ctcpcmd, *ctcpdata, *recoded; void *free_arg; CMD_IRC_SERVER(server); @@ -128,7 +139,10 @@ static void cmd_nctcp(const char *data, IRC_SERVER_REC *server, cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); g_strup(ctcpcmd); - g_string_sprintf(tmpstr, "NOTICE %s :\001%s %s\001", target, ctcpcmd, ctcpdata); + recoded = recode_out(ctcpdata, target); + g_string_sprintf(tmpstr, "NOTICE %s :\001%s %s\001", target, ctcpcmd, recoded); + g_free(recoded); + irc_send_cmd_split(server, tmpstr->str, 2, server->max_msgs_in_cmd); cmd_params_free(free_arg); @@ -139,6 +153,7 @@ static void cmd_part(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { char *channame, *msg; + char *recoded = NULL; void *free_arg; CMD_IRC_SERVER(server); @@ -153,16 +168,19 @@ static void cmd_part(const char *data, IRC_SERVER_REC *server, if (server->cmdcount > MAX_COMMANDS_ON_PART_UNTIL_PURGE) irc_server_purge_output(server, channame); - irc_send_cmdv(server, *msg == '\0' ? "PART %s" : "PART %s :%s", - channame, msg); + if (*msg != '\0') + recoded = recode_out(msg, channame); + irc_send_cmdv(server, ! recoded ? "PART %s" : "PART %s :%s", + channame, recoded); + g_free(recoded); cmd_params_free(free_arg); } /* SYNTAX: KICK [<channel>] <nicks> [<reason>] */ static void cmd_kick(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { - char *channame, *nicks, *reason; + char *channame, *nicks, *reason, *recoded; void *free_arg; CMD_IRC_SERVER(server); @@ -175,7 +193,10 @@ static void cmd_kick(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item if (*channame == '\0' || *nicks == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (!ischannel(*channame)) cmd_param_error(CMDERR_NOT_JOINED); - g_string_sprintf(tmpstr, "KICK %s %s :%s", channame, nicks, reason); + recoded = recode_out(reason, channame); + g_string_sprintf(tmpstr, "KICK %s %s :%s", channame, nicks, recoded); + g_free(recoded); + irc_send_cmd_split(server, tmpstr->str, 3, server->max_kicks_in_cmd); cmd_params_free(free_arg); @@ -186,6 +207,7 @@ static void cmd_topic(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *ite { GHashTable *optlist; char *channame, *topic; + char *recoded = NULL; void *free_arg; CMD_IRC_SERVER(server); @@ -195,9 +217,11 @@ static void cmd_topic(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *ite item, "topic", &optlist, &channame, &topic)) return; - irc_send_cmdv(server, *topic == '\0' && - g_hash_table_lookup(optlist, "delete") == NULL ? - "TOPIC %s" : "TOPIC %s :%s", channame, topic); + if (*topic != '\0' || g_hash_table_lookup(optlist, "delete") != NULL) + recoded = recode_out(topic, channame); + irc_send_cmdv(server, recoded == NULL ? "TOPIC %s" : "TOPIC %s :%s", + channame, recoded); + g_free(recoded); cmd_params_free(free_arg); } @@ -619,7 +643,7 @@ static void cmd_wait(const char *data, IRC_SERVER_REC *server) /* SYNTAX: WALL [<channel>] <message> */ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { - char *channame, *msg, *args; + char *channame, *msg, *args, *recoded; void *free_arg; IRC_CHANNEL_REC *chanrec; GSList *tmp, *nicks; @@ -649,14 +673,18 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item SERVER(server), item, args, NULL, 0); g_free(args); + recoded = recode_out(msg, channame); + for (tmp = nicks; tmp != NULL; tmp = tmp->next) { NICK_REC *rec = tmp->data; if (rec != chanrec->ownnick) { irc_send_cmdv(server, "NOTICE %s :%s", - rec->nick, msg); + rec->nick, recoded); } } + + g_free(recoded); g_free(msg); g_slist_free(nicks); } @@ -669,7 +697,7 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item and it supports NOTICE @#channel anyway */ static void cmd_wallchops(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { - char *channame, *msg; + char *channame, *msg, *recoded; void *free_arg; CMD_IRC_SERVER(server); @@ -679,8 +707,10 @@ static void cmd_wallchops(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC return; if (*msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); - irc_send_cmdv(server, "WALLCHOPS %s :%s", channame, msg); + recoded = recode_out(msg, channame); + irc_send_cmdv(server, "WALLCHOPS %s :%s", channame, recoded); + g_free(recoded); cmd_params_free(free_arg); } @@ -689,7 +719,7 @@ static void cmd_kickban(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { IRC_CHANNEL_REC *chanrec; - char *channel, *nicks, *reason, *kickcmd, *bancmd; + char *channel, *nicks, *reason, *kickcmd, *bancmd, *recoded; char **nicklist, *spacenicks; void *free_arg; @@ -712,7 +742,10 @@ static void cmd_kickban(const char *data, IRC_SERVER_REC *server, spacenicks = g_strjoinv(" ", nicklist); g_strfreev(nicklist); - kickcmd = g_strdup_printf("%s %s %s", chanrec->name, nicks, reason); + recoded = recode_out(reason, channel); + kickcmd = g_strdup_printf("%s %s %s", chanrec->name, nicks, recoded); + g_free(recoded); + bancmd = g_strdup_printf("%s %s", chanrec->name, spacenicks); g_free(spacenicks); @@ -771,7 +804,7 @@ static void cmd_knockout(const char *data, IRC_SERVER_REC *server, IRC_CHANNEL_REC *channel) { KNOCKOUT_REC *rec; - char *nicks, *reason, *timeoutstr, *kickcmd, *bancmd; + char *nicks, *reason, *timeoutstr, *kickcmd, *bancmd, *recoded; char **nicklist, *spacenicks, *banmasks; void *free_arg; int timeleft; @@ -807,7 +840,10 @@ static void cmd_knockout(const char *data, IRC_SERVER_REC *server, banmasks = ban_get_masks(channel, spacenicks, 0); g_free(spacenicks); - kickcmd = g_strdup_printf("%s %s %s", channel->name, nicks, reason); + recoded = recode_out(reason, channel->name); + kickcmd = g_strdup_printf("%s %s %s", channel->name, nicks, recoded); + g_free(recoded); + bancmd = *banmasks == '\0'? NULL : g_strdup_printf("%s %s", channel->name, banmasks); diff --git a/src/irc/proxy/dump.c b/src/irc/proxy/dump.c index f98bee94..1aeea5e5 100644 --- a/src/irc/proxy/dump.c +++ b/src/irc/proxy/dump.c @@ -22,6 +22,7 @@ #include "network.h" #include "settings.h" #include "irssi-version.h" +#include "recode.h" #include "irc-servers.h" #include "irc-channels.h" @@ -195,10 +196,11 @@ static void dump_join(IRC_CHANNEL_REC *channel, CLIENT_REC *client) proxy_outdata(client, ":%s 366 %s %s :End of /NAMES list.\n", client->proxy_address, client->nick, channel->name); + /* this is needed because the topic may be encoded into other charsets internaly */ if (channel->topic != NULL) { proxy_outdata(client, ":%s 332 %s %s :%s\n", client->proxy_address, client->nick, - channel->name, channel->topic); + channel->name, recode_out(channel->topic, channel->name)); } } diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c index 2ab1373c..cf9b2f2d 100644 --- a/src/irc/proxy/listen.c +++ b/src/irc/proxy/listen.c @@ -257,7 +257,8 @@ static void handle_client_cmd(CLIENT_REC *client, char *cmd, char *args, ignore_next = TRUE; if (*msg != '\001' || msg[strlen(msg)-1] != '\001') { - signal_emit("message own_public", 4, + signal_emit(ischannel(*target) ? + "message own_public" : "message own_private", 4, client->server, msg, target, target); } else if (strncmp(msg+1, "ACTION ", 7) == 0) { /* action */ @@ -528,6 +529,16 @@ static void sig_message_own_public(IRC_SERVER_REC *server, const char *msg, proxy_outserver_all(server, "PRIVMSG %s :%s", target, msg); } +static void sig_message_own_private(IRC_SERVER_REC *server, const char *msg, + const char *target, const char *origtarget) +{ + if (!IS_IRC_SERVER(server)) + return; + + if (!ignore_next) + proxy_outserver_all(server, "PRIVMSG %s :%s", target, msg); +} + static void sig_message_own_action(IRC_SERVER_REC *server, const char *msg, const char *target) { @@ -659,6 +670,7 @@ void proxy_listen_init(void) signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); signal_add("event nick", (SIGNAL_FUNC) event_nick); signal_add("message own_public", (SIGNAL_FUNC) sig_message_own_public); + signal_add("message own_private", (SIGNAL_FUNC) sig_message_own_private); signal_add("message irc own_action", (SIGNAL_FUNC) sig_message_own_action); signal_add("setup changed", (SIGNAL_FUNC) read_settings); } @@ -675,6 +687,7 @@ void proxy_listen_deinit(void) signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); signal_remove("event nick", (SIGNAL_FUNC) event_nick); signal_remove("message own_public", (SIGNAL_FUNC) sig_message_own_public); + signal_remove("message own_private", (SIGNAL_FUNC) sig_message_own_private); signal_remove("message irc own_action", (SIGNAL_FUNC) sig_message_own_action); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); } |