changeset 772:464be13343a9

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.
author Mikael Berthe <mikael@lilotux.net>
date Sat, 25 Mar 2006 18:10:36 +0100
parents ce4f8a2129a4
children e25b8a348ebd
files mcabber/src/commands.c mcabber/src/histolog.c mcabber/src/hooks.c mcabber/src/jab_iq.c mcabber/src/jabglue.c mcabber/src/main.c mcabber/src/roster.c mcabber/src/screen.c
diffstat 8 files changed, 252 insertions(+), 289 deletions(-) [+]
line wrap: on
line diff
--- 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);
 }
 
--- 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;
     }
   }
--- 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) {
--- 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);
 }
--- 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... */
--- 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");
--- 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 <string.h>
 
 #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));
     }
   }
 
--- 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;
   }