# HG changeset patch # User Mikael Berthe # Date 1143306636 -3600 # Node ID 464be13343a9cfdc84a9c003fa819c477797d400 # Parent ce4f8a2129a439445549db6bb32f3027e9552f82 Store most data in UTF-8 internally Only chat buffer data is still using 1 byte for char size. User input still doesn't handle UTF-8 locales. diff -r ce4f8a2129a4 -r 464be13343a9 mcabber/src/commands.c --- a/mcabber/src/commands.c Sat Mar 25 18:00:40 2006 +0100 +++ b/mcabber/src/commands.c Sat Mar 25 18:10:36 2006 +0100 @@ -65,7 +65,7 @@ // cmd_add() // Adds a command to the commands list and to the CMD completion list -void cmd_add(const char *name, const char *help, +static void cmd_add(const char *name, const char *help, guint flags_row1, guint flags_row2, void (*f)()) { cmd *n_cmd = g_new0(cmd, 1); @@ -80,7 +80,7 @@ } // cmd_init() -// ... +// Commands table initialization void cmd_init(void) { cmd_add("add", "Add a jabber user", COMPL_JID, 0, &do_add); @@ -511,13 +511,16 @@ (sm ? sm : "")); return; } + arg = to_utf8(arg); setstatus(NULL, arg); + g_free(arg); } static void do_status_to(char *arg) { char **paramlst; char *jid, *st, *msg; + char *jid_utf8 = NULL; paramlst = split_arg(arg, 3, 1); // jid, status, [message] jid = *paramlst; @@ -545,6 +548,7 @@ char *p = jid; for ( ; *p && *p != '/'; p++) *p = tolower(*p); + jid = jid_utf8 = to_utf8(jid); } } else { // Add the current buddy @@ -558,10 +562,13 @@ char *cmd; if (!msg) msg = ""; + msg = to_utf8(msg); cmd = g_strdup_printf("%s %s", st, msg); scr_LogPrint(LPRINT_LOGNORM, "Sending to <%s> /status %s", jid, cmd); setstatus(jid, cmd); + g_free(msg); g_free(cmd); + g_free(jid_utf8); } free_arg_lst(paramlst); } @@ -570,6 +577,7 @@ { char **paramlst; char *id, *nick; + char *jid_utf8 = NULL; if (!jb_getonline()) { scr_LogPrint(LPRINT_NORMAL, "You are not connected."); @@ -592,6 +600,9 @@ id = NULL; } else { mc_strtolower(id); + // Actually an UTF-8 id isn't needed because only the bare jid will + // be used. + id = jid_utf8 = to_utf8(id); } } else { // Add the current buddy @@ -601,12 +612,18 @@ scr_LogPrint(LPRINT_NORMAL, "Please specify a Jabber ID."); } + if (nick) + nick = to_utf8(nick); + if (id) { // 2nd parameter = optional nickname jb_addbuddy(id, nick, NULL); scr_LogPrint(LPRINT_LOGNORM, "Sent presence notification request to <%s>.", id); } + + g_free(jid_utf8); + g_free(nick); free_arg_lst(paramlst); } @@ -740,7 +757,9 @@ } buddy_setflags(bud, ROSTER_FLAG_LOCK, TRUE); + arg = to_utf8(arg); send_message(arg); + g_free(arg); } static void do_msay(char *arg) @@ -795,12 +814,20 @@ scr_set_chatmode(TRUE); if (!strcasecmp(subcmd, "send_to")) { + int err; + gchar *msg_utf8; // Let's send to the specified JID. We leave now if there // has been an error (so we don't leave multi-line mode). - if (send_message_to(arg, scr_get_multiline())) + arg = to_utf8(arg); + msg_utf8 = to_utf8(scr_get_multiline()); + err = send_message_to(arg, msg_utf8); + g_free(msg_utf8); + g_free(arg); + if (err) return; } else { // Send to currently selected buddy gpointer bud; + gchar *msg_utf8; if (!current_buddy) { scr_LogPrint(LPRINT_NORMAL, "Whom are you talking to?"); @@ -814,7 +841,9 @@ } buddy_setflags(bud, ROSTER_FLAG_LOCK, TRUE); - send_message(scr_get_multiline()); + msg_utf8 = to_utf8(scr_get_multiline()); + send_message(msg_utf8); + g_free(msg_utf8); } scr_set_multimode(FALSE); } @@ -839,7 +868,13 @@ return; } + jid = to_utf8(jid); + msg = to_utf8(msg); + send_message_to(jid, msg); + + g_free(jid); + g_free(msg); free_arg_lst(paramlst); } @@ -1090,6 +1125,7 @@ const char *jid, *group; guint type; char *newname, *p; + char *name_utf8; if (!*arg) { scr_LogPrint(LPRINT_NORMAL, "Please specify a Jabber ID to rename."); @@ -1115,9 +1151,11 @@ strip_arg_special_chars(newname); - buddy_setname(bud, newname); - jb_updatebuddy(jid, newname, group); + name_utf8 = to_utf8(newname); + buddy_setname(bud, name_utf8); + jb_updatebuddy(jid, name_utf8, group); + g_free(name_utf8); g_free(newname); update_roster = TRUE; } @@ -1128,6 +1166,7 @@ const char *jid, *name, *oldgroupname; guint type; char *newgroupname, *p; + char *group_utf8; if (!current_buddy) return; bud = BUDDATA(current_buddy); @@ -1150,12 +1189,14 @@ strip_arg_special_chars(newgroupname); - if (strcmp(oldgroupname, newgroupname)) { - jb_updatebuddy(jid, name, *newgroupname ? newgroupname : NULL); + group_utf8 = to_utf8(newgroupname); + if (strcmp(oldgroupname, group_utf8)) { + jb_updatebuddy(jid, name, *group_utf8 ? group_utf8 : NULL); scr_RosterUp(); - buddy_setgroup(bud, newgroupname); + buddy_setgroup(bud, group_utf8); } + g_free(group_utf8); g_free(newgroupname); update_roster = TRUE; } @@ -1164,19 +1205,22 @@ { guint assign; const gchar *option, *value; + gchar *option_utf8; assign = parse_assigment(arg, &option, &value); if (!option) { scr_LogPrint(LPRINT_NORMAL, "Set what option?"); return; } + option_utf8 = to_utf8(option); if (!assign) { // This is a query - value = settings_opt_get(option); + value = settings_opt_get(option_utf8); if (value) { - scr_LogPrint(LPRINT_NORMAL, "%s = [%s]", option, value); + scr_LogPrint(LPRINT_NORMAL, "%s = [%s]", option_utf8, value); } else - scr_LogPrint(LPRINT_NORMAL, "Option %s is not set", option); + scr_LogPrint(LPRINT_NORMAL, "Option %s is not set", option_utf8); + g_free(option_utf8); return; } // Update the option @@ -1184,10 +1228,13 @@ // (server, username, etc.). And we should catch some options here, too // (hide_offline_buddies for ex.) if (!value) { - settings_del(SETTINGS_TYPE_OPTION, option); + settings_del(SETTINGS_TYPE_OPTION, option_utf8); } else { - settings_set(SETTINGS_TYPE_OPTION, option, value); + gchar *value_utf8 = to_utf8(value); + settings_set(SETTINGS_TYPE_OPTION, option_utf8, value_utf8); + g_free(value_utf8); } + g_free(option_utf8); } static void do_alias(char *arg) @@ -1204,14 +1251,17 @@ // This is a query value = settings_get(SETTINGS_TYPE_ALIAS, alias); if (value) { - scr_LogPrint(LPRINT_NORMAL, "%s = %s", alias, value); + // XXX LPRINT_NOTUTF8 here, see below why it isn't encoded... + scr_LogPrint(LPRINT_NORMAL|LPRINT_NOTUTF8, "%s = %s", alias, value); } else - scr_LogPrint(LPRINT_NORMAL, "Alias '%s' does not exist", alias); + scr_LogPrint(LPRINT_NORMAL|LPRINT_NOTUTF8, + "Alias '%s' does not exist", alias); return; } // Check the alias does not conflict with a registered command if (cmd_get(alias)) { - scr_LogPrint(LPRINT_NORMAL, "'%s' is a reserved word!", alias); + scr_LogPrint(LPRINT_NORMAL|LPRINT_NOTUTF8, + "'%s' is a reserved word!", alias); return; } // Update the alias @@ -1222,7 +1272,11 @@ compl_del_category_word(COMPL_CMD, alias); } } else { - // Add alias to the completion list, if not already in + /* Add alias to the completion list, if not already in. + XXX We're not UTF8-encoding "alias" and "value" here because UTF-8 is + not yet supported in the UI... (and we use the values in the completion + system) + */ if (!settings_get(SETTINGS_TYPE_ALIAS, alias)) compl_add_category_word(COMPL_CMD, alias); settings_set(SETTINGS_TYPE_ALIAS, alias, value); @@ -1249,10 +1303,13 @@ return; } // Update the key binding - if (!value) + if (!value) { settings_del(SETTINGS_TYPE_BINDING, keycode); - else - settings_set(SETTINGS_TYPE_BINDING, keycode, value); + } else { + gchar *value_utf8 = to_utf8(value); + settings_set(SETTINGS_TYPE_BINDING, keycode, value_utf8); + g_free(value_utf8); + } } static void do_rawxml(char *arg) @@ -1360,10 +1417,13 @@ *p = 0; } } + } else { + nick = tmpnick = to_utf8(nick); } // If we still have no nickname, give up if (!nick || !*nick) { scr_LogPrint(LPRINT_NORMAL, "Please specify a nickname."); + g_free(tmpnick); free_arg_lst(paramlst); return; } @@ -1371,15 +1431,16 @@ // Note that roomname is part of the array allocated by split_arg(), // so we can modify it. mc_strtolower(roomname); + roomname = to_utf8(roomname); jb_room_join(roomname, nick); scr_LogPrint(LPRINT_LOGNORM, "Sent a join request to <%s>...", roomname); + g_free(roomname); + g_free(tmpnick); buddylist_build(); update_roster = TRUE; free_arg_lst(paramlst); - if (tmpnick) - g_free(tmpnick); } static void room_invite(gpointer bud, char *arg) @@ -1387,6 +1448,7 @@ char **paramlst; const gchar *roomname; char* jid; + gchar *reason_utf8; paramlst = split_arg(arg, 2, 1); // jid, [reason] jid = *paramlst; @@ -1402,8 +1464,10 @@ } roomname = buddy_getjid(bud); - jb_room_invite(roomname, jid, arg); + reason_utf8 = to_utf8(arg); + jb_room_invite(roomname, jid, reason_utf8); scr_LogPrint(LPRINT_LOGNORM, "Invitation sent to <%s>...", jid); + if (reason_utf8) g_free(reason_utf8); free_arg_lst(paramlst); } @@ -1431,9 +1495,14 @@ if (!strcasecmp(rolename, straffil[ra.val.affil])) break; - if (ra.val.affil < imaffiliation_size) - jb_room_setattrib(roomid, jid, NULL, ra, arg); - else + if (ra.val.affil < imaffiliation_size) { + gchar *jid_utf8, *reason_utf8; + jid_utf8 = to_utf8(jid); + reason_utf8 = to_utf8(arg); + jb_room_setattrib(roomid, jid_utf8, NULL, ra, reason_utf8); + if (jid_utf8) g_free(jid_utf8); + if (reason_utf8) g_free(reason_utf8); + } else scr_LogPrint(LPRINT_NORMAL, "Wrong affiliation parameter."); free_arg_lst(paramlst); @@ -1463,9 +1532,14 @@ if (!strcasecmp(rolename, strrole[ra.val.role])) break; - if (ra.val.role < imrole_size) - jb_room_setattrib(roomid, jid, NULL, ra, arg); - else + if (ra.val.role < imrole_size) { + gchar *jid_utf8, *reason_utf8; + jid_utf8 = to_utf8(jid); + reason_utf8 = to_utf8(arg); + jb_room_setattrib(roomid, jid_utf8, NULL, ra, reason_utf8); + if (jid_utf8) g_free(jid_utf8); + if (reason_utf8) g_free(reason_utf8); + } else scr_LogPrint(LPRINT_NORMAL, "Wrong role parameter."); free_arg_lst(paramlst); @@ -1477,6 +1551,7 @@ { char **paramlst; gchar *jid; + gchar *jid_utf8, *reason_utf8; struct role_affil ra; const char *roomid = buddy_getjid(bud); @@ -1493,7 +1568,11 @@ ra.type = type_affil; ra.val.affil = affil_outcast; - jb_room_setattrib(roomid, jid, NULL, ra, arg); + jid_utf8 = to_utf8(jid); + reason_utf8 = to_utf8(arg); + jb_room_setattrib(roomid, jid_utf8, NULL, ra, reason_utf8); + if (jid_utf8) g_free(jid_utf8); + if (reason_utf8) g_free(reason_utf8); free_arg_lst(paramlst); } @@ -1503,6 +1582,7 @@ { char **paramlst; gchar *nick; + gchar *nick_utf8, *reason_utf8; struct role_affil ra; const char *roomid = buddy_getjid(bud); @@ -1519,14 +1599,18 @@ ra.type = type_role; ra.val.affil = role_none; - jb_room_setattrib(roomid, NULL, nick, ra, arg); + nick_utf8 = to_utf8(nick); + reason_utf8 = to_utf8(arg); + jb_room_setattrib(roomid, NULL, nick_utf8, ra, reason_utf8); + if (nick_utf8) g_free(nick_utf8); + if (reason_utf8) g_free(reason_utf8); free_arg_lst(paramlst); } static void room_leave(gpointer bud, char *arg) { - gchar *roomid, *utf8_nickname; + gchar *roomid, *desc; const char *nickname; nickname = buddy_getnickname(bud); @@ -1535,10 +1619,10 @@ return; } - utf8_nickname = to_utf8(nickname); - roomid = g_strdup_printf("%s/%s", buddy_getjid(bud), utf8_nickname); - jb_setstatus(offline, roomid, arg); - g_free(utf8_nickname); + roomid = g_strdup_printf("%s/%s", buddy_getjid(bud), nickname); + desc = to_utf8(arg); + jb_setstatus(offline, roomid, desc); + g_free(desc); g_free(roomid); } @@ -1624,9 +1708,11 @@ return; } + arg = to_utf8(arg); // Set the topic msg = g_strdup_printf("/me has set the topic to: %s", arg); jb_send_msg(buddy_getjid(bud), msg, ROSTER_TYPE_ROOM, arg); + g_free(arg); g_free(msg); } @@ -1635,11 +1721,12 @@ gchar *msg; if (arg && *arg) - msg = arg; + msg = to_utf8(arg); else msg = NULL; jb_room_destroy(buddy_getjid(bud), NULL, msg); + if (msg) g_free(msg); } static void room_unlock(gpointer bud, char *arg) @@ -1812,6 +1899,7 @@ { char **paramlst; char *subcmd; + char *jid_utf8; if (!jb_getonline()) { scr_LogPrint(LPRINT_NORMAL, "You are not connected."); @@ -1849,32 +1937,38 @@ if (!current_buddy) return; bud = BUDDATA(current_buddy); - arg = (char*)buddy_getjid(bud); + jid_utf8 = arg = (char*)buddy_getjid(bud); type = buddy_gettype(bud); if (!(type & (ROSTER_TYPE_USER|ROSTER_TYPE_AGENT))) { scr_LogPrint(LPRINT_NORMAL, "Invalid buddy."); return; } + } else { + jid_utf8 = to_utf8(arg); } if (!strcasecmp(subcmd, "allow")) { - jb_subscr_send_auth(arg); + jb_subscr_send_auth(jid_utf8); scr_LogPrint(LPRINT_LOGNORM, - "<%s> is now allowed to receive your presence updates.", arg); + "<%s> is now allowed to receive your presence updates.", + jid_utf8); } else if (!strcasecmp(subcmd, "cancel")) { - jb_subscr_cancel_auth(arg); + jb_subscr_cancel_auth(jid_utf8); scr_LogPrint(LPRINT_LOGNORM, "<%s> will no longer receive your presence updates.", - arg); + jid_utf8); } else if (!strcasecmp(subcmd, "request")) { - jb_subscr_request_auth(arg); + jb_subscr_request_auth(jid_utf8); scr_LogPrint(LPRINT_LOGNORM, - "Sent presence notification request to <%s>...", arg); + "Sent presence notification request to <%s>...", jid_utf8); } else { scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!"); } + // Only free jid_utf8 if it has been allocated, i.e. if != arg. + if (jid_utf8 && jid_utf8 != arg) + g_free(jid_utf8); free_arg_lst(paramlst); } @@ -1888,6 +1982,7 @@ char **paramlst; char *jid, *type; enum iqreq_type numtype = iqreq_none; + char *jid_utf8 = NULL; paramlst = split_arg(arg, 2, 0); // type, jid type = *paramlst; @@ -1925,9 +2020,10 @@ jid = NULL; } else { // Convert jid to lowercase - char *p = jid; - for ( ; *p && *p != '/'; p++) + char *p; + for (p = jid; *p && *p != '/'; p++) *p = tolower(*p); + jid = jid_utf8 = to_utf8(jid); } } else { // Add the current buddy @@ -1947,6 +2043,7 @@ break; } } + g_free(jid_utf8); free_arg_lst(paramlst); } diff -r ce4f8a2129a4 -r 464be13343a9 mcabber/src/histolog.c --- a/mcabber/src/histolog.c Sat Mar 25 18:00:40 2006 +0100 +++ b/mcabber/src/histolog.c Sat Mar 25 18:10:36 2006 +0100 @@ -215,14 +215,19 @@ *(tail-1) = 0; if (type == 'M') { + char *converted; if (info == 'S') prefix_flags = HBB_PREFIX_OUT | HBB_PREFIX_HLIGHT; else prefix_flags = HBB_PREFIX_IN; - xtext = ut_expand_tabs(&data[26]); // Expand tabs - hbuf_add_line(p_buddyhbuf, xtext, timestamp, prefix_flags, width); - if (xtext != &data[26]) - g_free(xtext); + converted = from_utf8(&data[26]); + if (converted) { + xtext = ut_expand_tabs(converted); // Expand tabs + hbuf_add_line(p_buddyhbuf, xtext, timestamp, prefix_flags, width); + if (xtext != converted) + g_free(xtext); + g_free(converted); + } err = 0; } } diff -r ce4f8a2129a4 -r 464be13343a9 mcabber/src/hooks.c --- a/mcabber/src/hooks.c Sat Mar 25 18:00:40 2006 +0100 +++ b/mcabber/src/hooks.c Sat Mar 25 18:10:36 2006 +0100 @@ -157,7 +157,7 @@ inline void hk_message_out(const char *jid, const char *nick, time_t timestamp, const char *msg) { - char *wmsg = NULL, *bmsg = NULL, *mmsg = NULL;; + char *wmsg = NULL, *bmsg = NULL, *mmsg = NULL; if (nick) { wmsg = bmsg = g_strdup_printf("PRIV#<%s> %s", nick, msg); @@ -314,10 +314,14 @@ if (strchr("MG", type) && data && settings_opt_get_int("event_log_files")) { int fd; const char *prefix; + char *data_locale; + + data_locale = from_utf8(data); prefix = settings_opt_get("event_log_dir"); if (!prefix) prefix = ut_get_tmpdir(); datafname = g_strdup_printf("%s/mcabber-%d.XXXXXX", prefix, getpid()); + // XXX Some old systems may require us to set umask first. fd = mkstemp(datafname); if (fd == -1) { @@ -326,10 +330,11 @@ scr_LogPrint(LPRINT_LOGNORM, "Unable to create temp file for external command."); } - write(fd, data, strlen(data)); + write(fd, data_locale, strlen(data_locale)); write(fd, "\n", 1); close(fd); arg_data = datafname; + g_free(data_locale); } if ((pid=fork()) == -1) { diff -r ce4f8a2129a4 -r 464be13343a9 mcabber/src/jab_iq.c --- a/mcabber/src/jab_iq.c Sat Mar 25 18:00:40 2006 +0100 +++ b/mcabber/src/jab_iq.c Sat Mar 25 18:10:36 2006 +0100 @@ -167,15 +167,12 @@ { xmlnode y; const char *jid, *name, *group, *sub, *ask; - char *buddyname; char *cleanalias; enum subscr esub; int need_refresh = FALSE; guint roster_type; for (y = xmlnode_get_tag(x, "item"); y; y = xmlnode_get_nextsibling(y)) { - gchar *name_noutf8 = NULL; - gchar *group_noutf8 = NULL; jid = xmlnode_get_attrib(y, "jid"); name = xmlnode_get_attrib(y, "name"); @@ -187,7 +184,7 @@ if (!jid) continue; - buddyname = cleanalias = jidtodisp(jid); + cleanalias = jidtodisp(jid); esub = sub_none; if (sub) { @@ -209,21 +206,8 @@ if (ask && !strcmp(ask, "subscribe")) esub |= sub_pending; - if (name) { - name_noutf8 = from_utf8(name); - if (name_noutf8) - buddyname = name_noutf8; - else - scr_LogPrint(LPRINT_LOG, "Decoding of buddy alias has failed: %s", - name); - } - - if (group) { - group_noutf8 = from_utf8(group); - if (!group_noutf8) - scr_LogPrint(LPRINT_LOG, "Decoding of buddy group has failed: %s", - group); - } + if (!name) + name = cleanalias; // Tricky... :-\ My guess is that if there is no '@', this is an agent if (strchr(cleanalias, '@')) @@ -231,10 +215,8 @@ else roster_type = ROSTER_TYPE_AGENT; - roster_add_user(cleanalias, buddyname, group_noutf8, roster_type, esub); + roster_add_user(cleanalias, name, group, roster_type, esub); - if (name_noutf8) g_free(name_noutf8); - if (group_noutf8) g_free(group_noutf8); g_free(cleanalias); } @@ -244,7 +226,7 @@ scr_ShowBuddyWindow(); } -void iqscallback_version(eviqs *iqp, xmlnode xml_result, guint iqcontext) +static void iqscallback_version(eviqs *iqp, xmlnode xml_result, guint iqcontext) { xmlnode ansqry; char *p, *p_noutf8; @@ -265,12 +247,7 @@ scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:version result (no sender name)."); return; } - bjid = from_utf8(p); - if (!bjid) { - scr_LogPrint(LPRINT_LOGNORM, "UTF-8 decoding error in IQ:version result " - "(sender name)."); - return; - } + bjid = p; buf = g_strdup_printf("IQ:version result from <%s>", bjid); scr_LogPrint(LPRINT_LOGNORM, "%s", buf); @@ -313,22 +290,19 @@ g_free(buf); } } - g_free(bjid); } void request_version(const char *fulljid) { eviqs *iqn; - gchar *utf8_jid = to_utf8(fulljid); iqn = iqs_new(JPACKET__GET, NS_VERSION, "version", IQS_DEFAULT_TIMEOUT); - xmlnode_put_attrib(iqn->xmldata, "to", utf8_jid); - if (utf8_jid) g_free(utf8_jid); + xmlnode_put_attrib(iqn->xmldata, "to", fulljid); iqn->callback = &iqscallback_version; jab_send(jc, iqn->xmldata); } -void iqscallback_time(eviqs *iqp, xmlnode xml_result, guint iqcontext) +static void iqscallback_time(eviqs *iqp, xmlnode xml_result, guint iqcontext) { xmlnode ansqry; char *p, *p_noutf8; @@ -349,12 +323,7 @@ scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:time result (no sender name)."); return; } - bjid = from_utf8(p); - if (!bjid) { - scr_LogPrint(LPRINT_LOGNORM, "UTF-8 decoding error in IQ:time result " - "(sender name)."); - return; - } + bjid = p; buf = g_strdup_printf("IQ:time result from <%s>", bjid); scr_LogPrint(LPRINT_LOGNORM, "%s", buf); @@ -397,17 +366,14 @@ g_free(buf); } } - g_free(bjid); } void request_time(const char *fulljid) { eviqs *iqn; - gchar *utf8_jid = to_utf8(fulljid); iqn = iqs_new(JPACKET__GET, NS_TIME, "time", IQS_DEFAULT_TIMEOUT); - xmlnode_put_attrib(iqn->xmldata, "to", utf8_jid); - if (utf8_jid) g_free(utf8_jid); + xmlnode_put_attrib(iqn->xmldata, "to", fulljid); iqn->callback = &iqscallback_time; jab_send(jc, iqn->xmldata); } diff -r ce4f8a2129a4 -r 464be13343a9 mcabber/src/jabglue.c --- a/mcabber/src/jabglue.c Sat Mar 25 18:00:40 2006 +0100 +++ b/mcabber/src/jabglue.c Sat Mar 25 18:10:36 2006 +0100 @@ -96,7 +96,6 @@ jconn jb_connect(const char *jid, const char *server, unsigned int port, int ssl, const char *pass) { - char *utf8_jid; if (!port) { if (ssl) port = JABBERSSLPORT; @@ -106,11 +105,9 @@ jb_disconnect(); - utf8_jid = to_utf8(jid); - if (!utf8_jid) return jc; + if (!jid) return jc; - jc = jab_new(utf8_jid, (char*)pass, (char*)server, port, ssl); - g_free(utf8_jid); + jc = jab_new((char*)jid, (char*)pass, (char*)server, port, ssl); /* These 3 functions can deal with a NULL jc, no worry... */ jab_logger(jc, logger); @@ -268,13 +265,11 @@ { unsigned int prio; xmlnode x; - gchar *utf8_recipient = to_utf8(recipient); x = jutil_presnew(JPACKET__UNKNOWN, 0, 0); - if (utf8_recipient) { - xmlnode_put_attrib(x, "to", utf8_recipient); - g_free(utf8_recipient); + if (recipient) { + xmlnode_put_attrib(x, "to", recipient); } switch(st) { @@ -318,12 +313,8 @@ strprio, (unsigned) -1); } - if (msg) { - gchar *utf8_msg = to_utf8(msg); - xmlnode_insert_cdata(xmlnode_insert_tag(x, "status"), utf8_msg, - (unsigned) -1); - g_free(utf8_msg); - } + if (msg) + xmlnode_insert_cdata(xmlnode_insert_tag(x, "status"), msg, (unsigned) -1); return x; } @@ -393,8 +384,6 @@ { xmlnode x; gchar *strtype; - gchar *utf8_jid; - gchar *buffer; if (!online) return; @@ -403,23 +392,15 @@ else strtype = TMSG_CHAT; - buffer = to_utf8(text); - utf8_jid = to_utf8(jid); // Resource can require UTF-8 - - x = jutil_msgnew(strtype, utf8_jid, NULL, (char*)buffer); + x = jutil_msgnew(strtype, (char*)jid, NULL, (char*)text); if (subject) { xmlnode y; - char *bs = to_utf8(subject); y = xmlnode_insert_tag(x, "subject"); - xmlnode_insert_cdata(y, bs, (unsigned) -1); - if (bs) g_free(bs); + xmlnode_insert_cdata(y, subject, (unsigned) -1); } jab_send(jc, x); xmlnode_free(x); - if (buffer) g_free(buffer); - if (utf8_jid) g_free(utf8_jid); - jb_reset_keepalive(); } @@ -428,12 +409,10 @@ void jb_subscr_send_auth(const char *jid) { xmlnode x; - char *utf8_jid = to_utf8(jid); - x = jutil_presnew(JPACKET__SUBSCRIBED, utf8_jid, NULL); + x = jutil_presnew(JPACKET__SUBSCRIBED, (char *)jid, NULL); jab_send(jc, x); xmlnode_free(x); - g_free(utf8_jid); } // jb_subscr_cancel_auth(jid) @@ -441,12 +420,10 @@ void jb_subscr_cancel_auth(const char *jid) { xmlnode x; - char *utf8_jid = to_utf8(jid); - x = jutil_presnew(JPACKET__UNSUBSCRIBED, utf8_jid, NULL); + x = jutil_presnew(JPACKET__UNSUBSCRIBED, (char *)jid, NULL); jab_send(jc, x); xmlnode_free(x); - g_free(utf8_jid); } // jb_subscr_request_auth(jid) @@ -454,12 +431,10 @@ void jb_subscr_request_auth(const char *jid) { xmlnode x; - char *utf8_jid = to_utf8(jid); - x = jutil_presnew(JPACKET__SUBSCRIBE, utf8_jid, NULL); + x = jutil_presnew(JPACKET__SUBSCRIBE, (char *)jid, NULL); jab_send(jc, x); xmlnode_free(x); - g_free(utf8_jid); } // Note: the caller should check the jid is correct @@ -481,17 +456,12 @@ xmlnode_put_attrib(y, "jid", cleanjid); - if (name) { - gchar *name_utf8 = to_utf8(name); - xmlnode_put_attrib(y, "name", name_utf8); - g_free(name_utf8); - } + if (name) + xmlnode_put_attrib(y, "name", name); if (group) { - char *group_utf8 = to_utf8(group); z = xmlnode_insert_tag(y, "group"); - xmlnode_insert_cdata(z, group_utf8, (unsigned) -1); - g_free(group_utf8); + xmlnode_insert_cdata(z, group, (unsigned) -1); } jab_send(jc, iqn->xmldata); @@ -557,30 +527,25 @@ xmlnode y; eviqs *iqn; char *cleanjid; - gchar *name_utf8; if (!online) return; // XXX We should check name's and group's correctness cleanjid = jidtodisp(jid); - name_utf8 = to_utf8(name); iqn = iqs_new(JPACKET__SET, NS_ROSTER, NULL, IQS_DEFAULT_TIMEOUT); y = xmlnode_insert_tag(xmlnode_get_tag(iqn->xmldata, "query"), "item"); xmlnode_put_attrib(y, "jid", cleanjid); - xmlnode_put_attrib(y, "name", name_utf8); + xmlnode_put_attrib(y, "name", name); if (group) { - gchar *group_utf8 = to_utf8(group); y = xmlnode_insert_tag(y, "group"); - xmlnode_insert_cdata(y, group_utf8, (unsigned) -1); - g_free(group_utf8); + xmlnode_insert_cdata(y, group, (unsigned) -1); } jab_send(jc, iqn->xmldata); iqs_del(iqn->id); // XXX - g_free(name_utf8); g_free(cleanjid); } @@ -711,10 +676,8 @@ xmlnode_put_attrib(z, "jid", venue); if (reason) { - gchar *utf8_reason = to_utf8(reason); y = xmlnode_insert_tag(z, "reason"); - xmlnode_insert_cdata(y, utf8_reason, (unsigned) -1); - g_free(utf8_reason); + xmlnode_insert_cdata(y, reason, (unsigned) -1); } jab_send(jc, iqn->xmldata); @@ -759,13 +722,9 @@ z = xmlnode_insert_tag(y, "item"); if (jid) { - gchar *utf8_jid = to_utf8(jid); - xmlnode_put_attrib(z, "jid", utf8_jid); - if (utf8_jid) g_free(utf8_jid); - } else { // nick - gchar *utf8_nickname = to_utf8(nick); - xmlnode_put_attrib(z, "nick", utf8_nickname); - g_free(utf8_nickname); + xmlnode_put_attrib(z, "jid", jid); + } else { // nickname + xmlnode_put_attrib(z, "nick", nick); } if (ra.type == type_affil) @@ -774,10 +733,8 @@ xmlnode_put_attrib(z, "role", strrole[ra.val.role]); if (reason) { - gchar *utf8_reason = to_utf8(reason); y = xmlnode_insert_tag(z, "reason"); - xmlnode_insert_cdata(y, utf8_reason, (unsigned) -1); - g_free(utf8_reason); + xmlnode_insert_cdata(y, reason, (unsigned) -1); } jab_send(jc, iqn->xmldata); @@ -793,7 +750,6 @@ void jb_room_invite(const char *room, const char *jid, const char *reason) { xmlnode x, y, z; - gchar *utf8_jid; if (!online || !room || !jid) return; @@ -802,16 +758,12 @@ y = xmlnode_insert_tag(x, "x"); xmlnode_put_attrib(y, "xmlns", "http://jabber.org/protocol/muc#user"); - utf8_jid = to_utf8(jid); // Resource can require UTF-8 z = xmlnode_insert_tag(y, "invite"); - xmlnode_put_attrib(z, "to", utf8_jid); - if (utf8_jid) g_free(utf8_jid); + xmlnode_put_attrib(z, "to", jid); if (reason) { - gchar *utf8_reason = to_utf8(reason); y = xmlnode_insert_tag(z, "reason"); - xmlnode_insert_cdata(y, utf8_reason, (unsigned) -1); - g_free(utf8_reason); + xmlnode_insert_cdata(y, reason, (unsigned) -1); } jab_send(jc, x); @@ -824,27 +776,13 @@ { char *jid; const char *rname; - gchar *buffer = from_utf8(body); jid = jidtodisp(from); - if (!buffer && body) { - scr_LogPrint(LPRINT_NORMAL, "Decoding of message from <%s> has failed", - from); - scr_LogPrint(LPRINT_LOG, "Decoding of message from <%s> has failed: %s", - from, body); - scr_WriteIncomingMessage(jid, "Cannot display message: " - "UTF-8 conversion failure", - 0, HBB_PREFIX_ERR | HBB_PREFIX_IN); - g_free(jid); - return; - } - rname = strchr(from, '/'); if (rname) rname++; - hk_message_in(jid, rname, timestamp, buffer, type); + hk_message_in(jid, rname, timestamp, body, type); g_free(jid); - g_free(buffer); } static const char *defaulterrormsg(int code) @@ -924,7 +862,7 @@ // And sometimes there is a text message s = xmlnode_get_tag_data(x, "text"); - if (s && *s) desc = s; // FIXME utf8?? + if (s && *s) desc = s; scr_LogPrint(LPRINT_LOGNORM, "Error code from server: %d %s", code, desc); } @@ -1077,23 +1015,16 @@ // Check for nickname change if (statuscode == 303 && mbnick) { gchar *mbuf; - gchar *newname_noutf8 = from_utf8(mbnick); - if (!newname_noutf8) - scr_LogPrint(LPRINT_LOG, "Decoding of new nickname has failed: %s", - mbnick); - mbuf = g_strdup_printf("%s is now known as %s", rname, - (newname_noutf8 ? newname_noutf8 : "(?)")); + mbuf = g_strdup_printf("%s is now known as %s", rname, mbnick); scr_WriteIncomingMessage(roomjid, mbuf, usttime, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG); if (log_muc_conf) hlog_write_message(roomjid, 0, FALSE, mbuf); g_free(mbuf); - if (newname_noutf8) { - buddy_resource_setname(room_elt->data, rname, newname_noutf8); - m = buddy_getnickname(room_elt->data); - if (m && !strcmp(rname, m)) - buddy_setnickname(room_elt->data, newname_noutf8); - g_free(newname_noutf8); - } + buddy_resource_setname(room_elt->data, rname, mbnick); + // Maybe it's _our_ nickname... + m = buddy_getnickname(room_elt->data); + if (m && !strcmp(rname, m)) + buddy_setnickname(room_elt->data, mbnick); } // Check for departure/arrival @@ -1125,18 +1056,9 @@ gchar *mbuf_end; // Forced leave if (actorjid) { - gchar *rsn_noutf8 = from_utf8(reason); - if (!rsn_noutf8 && reason) { - scr_LogPrint(LPRINT_NORMAL, "UTF-8 decoding of reason has failed"); - scr_LogPrint(LPRINT_LOG, "UTF-8 decoding of reason has failed: %s", - reason); - } mbuf_end = g_strdup_printf("%s from %s by <%s>.\nReason: %s", (how == ban ? "banned" : "kicked"), - roomjid, actorjid, - (rsn_noutf8 ? rsn_noutf8 : "None given")); - if (rsn_noutf8) - g_free(rsn_noutf8); + roomjid, actorjid, reason); } else { mbuf_end = g_strdup_printf("%s from %s.", (how == ban ? "banned" : "kicked"), @@ -1153,14 +1075,10 @@ if (we_left) { xmlnode destroynode = xmlnode_get_tag(xmldata, "destroy"); if (destroynode) { - gchar *rsn_noutf8 = NULL; - if ((reason = xmlnode_get_tag_data(destroynode, "reason"))) - rsn_noutf8 = from_utf8(reason); - if (rsn_noutf8) { + if ((reason = xmlnode_get_tag_data(destroynode, "reason"))) { mbuf = g_strdup_printf("You have left %s, " "the room has been destroyed: %s", - roomjid, rsn_noutf8); - g_free(rsn_noutf8); + roomjid, reason); } else { mbuf = g_strdup_printf("You have left %s, " "the room has been destroyed", roomjid); @@ -1196,7 +1114,7 @@ // I think it shouldn't happen, but let's put a warning for a while... mbuf = g_strdup_printf("MUC ERR: you have no nickname, " "please send a bug report!"); - scr_LogPrint(LPRINT_LOGNORM, mbuf); + scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf); scr_WriteIncomingMessage(roomjid, mbuf, 0, HBB_PREFIX_INFO); g_free(mbuf); buddylist_build(); @@ -1245,11 +1163,8 @@ // Update room member status if (rname) { - gchar *mbrjid_noutf8 = from_utf8(mbjid); roster_setstatus(roomjid, rname, bpprio, ust, ustmsg, usttime, - mbrole, mbaffil, mbrjid_noutf8); - if (mbrjid_noutf8) - g_free(mbrjid_noutf8); + mbrole, mbaffil, mbjid); } else scr_LogPrint(LPRINT_LOGNORM, "MUC DBG: no rname!"); /* DBG */ @@ -1314,15 +1229,7 @@ if (type && !strcmp(type, "unavailable")) ust = offline; - ustmsg = NULL; - p = xmlnode_get_tag_data(xmldata, "status"); - if (p) { - ustmsg = from_utf8(p); - if (!ustmsg) - scr_LogPrint(LPRINT_LOG, - "Decoding of status message of <%s> has failed: %s", - from, p); - } + ustmsg = xmlnode_get_tag_data(xmldata, "status"); // Timestamp? timestamp = xml_get_timestamp(xmldata); @@ -1342,7 +1249,6 @@ } g_free(r); - if (ustmsg) g_free(ustmsg); } static void handle_packet_message(jconn conn, char *type, char *from, @@ -1362,10 +1268,7 @@ if (type && !strcmp(type, TMSG_GROUPCHAT)) { // Room topic GSList *roombuddy; gchar *mbuf; - gchar *subj_noutf8 = from_utf8(p); - if (!subj_noutf8) - scr_LogPrint(LPRINT_LOG, - "Decoding of room topic has failed: %s", p); + gchar *subj = p; // Get the room (s) and the nickname (r) s = g_strdup(from); r = strchr(s, '/'); @@ -1374,21 +1277,18 @@ // Set the new topic roombuddy = roster_find(s, jidsearch, 0); if (roombuddy) - buddy_settopic(roombuddy->data, subj_noutf8); + buddy_settopic(roombuddy->data, subj); // Display inside the room window if (r == s) { // No specific resource (this is certainly history) - mbuf = g_strdup_printf("The topic has been set to: %s", - (subj_noutf8 ? subj_noutf8 : "(?)")); + mbuf = g_strdup_printf("The topic has been set to: %s", subj); } else { - mbuf = g_strdup_printf("%s has set the topic to: %s", r, - (subj_noutf8 ? subj_noutf8 : "(?)")); + mbuf = g_strdup_printf("%s has set the topic to: %s", r, subj); } scr_WriteIncomingMessage(s, mbuf, 0, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG); if (settings_opt_get_int("log_muc_conf")) hlog_write_message(s, 0, FALSE, mbuf); - if (subj_noutf8) g_free(subj_noutf8); g_free(s); g_free(mbuf); // The topic is displayed in the chat status line, so refresh now. @@ -1490,15 +1390,11 @@ g_free(buf); if (msg) { - char *msg_noutf8 = from_utf8(msg); - if (msg_noutf8) { - buf = g_strdup_printf("<%s> said: %s", from, msg_noutf8); - scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO); - replace_nl_with_dots(buf); - scr_LogPrint(LPRINT_LOGNORM, buf); - g_free(buf); - g_free(msg_noutf8); - } + buf = g_strdup_printf("<%s> said: %s", from, msg); + scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO); + replace_nl_with_dots(buf); + scr_LogPrint(LPRINT_LOGNORM, "%s", buf); + g_free(buf); } // Create a new event item @@ -1548,8 +1444,11 @@ static void packethandler(jconn conn, jpacket packet) { - char *p, *r, *s; + char *p; + /* + char *r, *s; const char *m; + */ char *from=NULL, *type=NULL; jb_reset_keepalive(); // reset keepalive timeout @@ -1564,33 +1463,7 @@ if (p) type = p; p = xmlnode_get_attrib(packet->x, "from"); - if (p) { // Convert from UTF8 - // We need to be careful because from_utf8() can fail on some chars - // Thus we only convert the resource part - from = g_new0(char, strlen(p)+1); - strcpy(from, p); - r = strchr(from, '/'); - m = strchr(p, '/'); - if (m++) { - s = from_utf8(m); - if (s) { - // In some cases the allocated memory size could be too small because - // when chars cannot be converted strings like "\uxxxx" or "\Uxxxxyyyy" - // are used. - if (strlen(r+1) < strlen(s)) { - from = g_realloc(from, 1+m-p+strlen(s)); - r = strchr(from, '/'); - } - strcpy(r+1, s); - g_free(s); - } else { - *(r+1) = 0; - scr_LogPrint(LPRINT_NORMAL, "Decoding of message sender has failed"); - scr_LogPrint(LPRINT_LOG, "Decoding of message sender has failed: %s", - m); - } - } - } + if (p) from = p; if (!from && packet->type != JPACKET_IQ) { scr_LogPrint(LPRINT_LOGNORM, "Error in packet (could be UTF8-related)"); @@ -1617,8 +1490,6 @@ default: scr_LogPrint(LPRINT_LOG, "Unhandled packet type (%d)", packet->type); } - if (from) - g_free(from); } /* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */ diff -r ce4f8a2129a4 -r 464be13343a9 mcabber/src/main.c --- a/mcabber/src/main.c Sat Mar 25 18:00:40 2006 +0100 +++ b/mcabber/src/main.c Sat Mar 25 18:10:36 2006 +0100 @@ -132,8 +132,6 @@ } } } while (pid > 0); - //if (pid < 0) - // scr_LogPrint(LPRINT_LOGNORM, "Error in waitpid: errno=%d", errno); signal(SIGCHLD, sig_handler); } else if (signum == SIGTERM) { mcabber_disconnect("Killed by SIGTERM"); diff -r ce4f8a2129a4 -r 464be13343a9 mcabber/src/roster.c --- a/mcabber/src/roster.c Sat Mar 25 18:00:40 2006 +0100 +++ b/mcabber/src/roster.c Sat Mar 25 18:10:36 2006 +0100 @@ -23,6 +23,7 @@ #include #include "roster.h" +#include "utils.h" char *strrole[] = { /* Should match enum in roster.h */ @@ -1123,15 +1124,29 @@ roster *roster_usr; if (!buddylist || !current_buddy) return NULL; for (;;) { + gchar *jid_locale, *name_locale; + char *found = NULL; + buddy = g_list_next(buddy); if (!buddy) buddy = buddylist; roster_usr = (roster*)buddy->data; - if (roster_usr->jid && strcasestr(roster_usr->jid, string)) - return buddy; - if (roster_usr->name && strcasestr(roster_usr->name, string)) - return buddy; + + jid_locale = from_utf8(roster_usr->jid); + if (jid_locale) { + found = strcasestr(jid_locale, string); + g_free(jid_locale); + if (found) + return buddy; + } + name_locale = from_utf8(roster_usr->name); + if (name_locale) { + found = strcasestr(name_locale, string); + g_free(name_locale); + if (found) + return buddy; + } if (buddy == current_buddy) return NULL; // Back to the beginning, and no match found @@ -1181,12 +1196,12 @@ if (btype == ROSTER_TYPE_GROUP) { const char *bname = buddy_getname(BUDDATA(buddy)); if ((bname) && (*bname)) - list = g_slist_append(list, g_strdup(bname)); + list = g_slist_append(list, from_utf8(bname)); } } else { // ROSTER_TYPE_USER (jid) (or agent, or chatroom...) const char *bjid = buddy_getjid(BUDDATA(buddy)); if (bjid) - list = g_slist_append(list, g_strdup(bjid)); + list = g_slist_append(list, from_utf8(bjid)); } } diff -r ce4f8a2129a4 -r 464be13343a9 mcabber/src/screen.c --- a/mcabber/src/screen.c Sat Mar 25 18:00:40 2006 +0100 +++ b/mcabber/src/screen.c Sat Mar 25 18:10:36 2006 +0100 @@ -576,6 +576,7 @@ unsigned int prefix_flags, int force_show) { window_entry_t *win_entry; + char *text_locale; int dont_show = FALSE; // Look for the window entry. @@ -596,8 +597,10 @@ if (win_entry->cleared) win_entry->top = g_list_last(win_entry->hbuf); - hbuf_add_line(&win_entry->hbuf, text, timestamp, prefix_flags, + text_locale = from_utf8(text); + hbuf_add_line(&win_entry->hbuf, text_locale, timestamp, prefix_flags, maxX - Roster_Width - PREFIX_WIDTH); + g_free(text_locale); if (win_entry->cleared) { win_entry->cleared = FALSE; @@ -1591,8 +1594,8 @@ } else return; } - scr_LogPrint(LPRINT_NORMAL, "Multi-line mode: line #%d added [%.25s...", - num, line); + scr_LogPrint(LPRINT_NORMAL|LPRINT_NOTUTF8, + "Multi-line mode: line #%d added [%.25s...", num, line); } // scr_cmdhisto_addline() @@ -2055,10 +2058,13 @@ boundcmd = settings_get(SETTINGS_TYPE_BINDING, asciikey); if (boundcmd) { - gchar *cmd = g_strdup_printf("/%s", boundcmd); + gchar *cmd, *boundcmd_locale; + boundcmd_locale = from_utf8(boundcmd); + cmd = g_strdup_printf("/%s", boundcmd_locale); scr_CheckAutoAway(TRUE); if (process_command(cmd)) return 255; // Quit + g_free(boundcmd_locale); g_free(cmd); return 0; }