From AlanSung@alansung.dragon2.net  Mon Nov 18 19:17:04 2002
Return-Path: <AlanSung@alansung.dragon2.net>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 2D4D537B401
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 18 Nov 2002 19:17:04 -0800 (PST)
Received: from alansung.dragon2.net (140-109-226-5.adsl.sinica.edu.tw [140.109.226.5])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 94C3443E9E
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 18 Nov 2002 19:16:58 -0800 (PST)
	(envelope-from AlanSung@alansung.dragon2.net)
Received: from alansung.dragon2.net (localhost [127.0.0.1])
	by alansung.dragon2.net (8.12.6/8.12.6) with ESMTP id gAJ3GrS4081495;
	Tue, 19 Nov 2002 11:16:54 +0800 (CST)
	(envelope-from AlanSung@alansung.dragon2.net)
Received: (from AlanSung@localhost)
	by alansung.dragon2.net (8.12.6/8.12.6/Submit) id gAJ3GrW6081494;
	Tue, 19 Nov 2002 11:16:53 +0800 (CST)
Message-Id: <200211190316.gAJ3GrW6081494@alansung.dragon2.net>
Date: Tue, 19 Nov 2002 11:16:53 +0800 (CST)
From: Cheng-Lung Sung <AlanSung@alansung.dragon2.net>
Reply-To: Cheng-Lung Sung <clsung@dragon2.net>
To: FreeBSD-gnats-submit@freebsd.org
Cc: clsung@dragon2.net
Subject: [PATCH] centericq with MSN UTF-8 Support (obsolete privious patch)
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         45465
>Category:       ports
>Synopsis:       [PATCH] centericq with MSN UTF-8 Support (obsolete privious patch)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    ijliao
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Mon Nov 18 19:20:01 PST 2002
>Closed-Date:    Tue Nov 19 20:04:56 PST 2002
>Last-Modified:  Wed Oct 26 04:47:05 GMT 2005
>Originator:     Cheng-Lung Sung <clsung@dragon2.net>
>Release:        FreeBSD 4.7-RELEASE i386
>Organization:
NCTU CSIE FreeBSD Server
>Environment:
System: FreeBSD AlanSung.dragon2.net 4.7-RELEASE FreeBSD 4.7-RELEASE #1: Fri Oct 11 14:23:08 CST 2002 root@AlanSung.dragon2.net:/usr/obj/usr/src/sys/SungSung i386

gnu iconv library needed
>Description:
After patching from privious path (http://www.freebsd.org/cgi/query-pr.cgi?pr=44740)
ijliao tell me that there is a problem about displaying big5 nickname, so
here I tried to collate centericq's source code and found another way to
patch original source code.

Following PR should be superseded by this one:
ports/44740 ports   [PATCH] centericq with MSN UTF-8 Support

>How-To-Repeat:
Please see privious send-pr(http://www.freebsd.org/cgi/query-pr.cgi?pr=44740)
Then , when displaying multibye nicknames, there will be the problem.
>Fix:
(one new header file and one patch file)
+++ src/hooks/utf8conv.h
+/*-------------------------------------------------------*/
+/* utf8conv.h     ( Utf8 Converter )                     */
+/*-------------------------------------------------------*/
+/* target : Converting Utf8 from/to string/char          */
+/* modifier : clsung@dragon2.net                         */
+/* create : unknown                                      */
+/* update : 02/11/19                                     */
+/*-------------------------------------------------------*/
+#ifndef _UTF8CONV_
+#define _UTF8CONV_
+
+#ifndef HAVE_ICONV_H
+#define HAVE_ICONV_H
+#endif
+
+#ifdef HAVE_ICONV_H
+#include <iconv.h>
+#endif
+#include <string>
+#define DEFAULT_CHARSET "ISO-8859-1"
+/* charset name cache buffer */
+static char loc_charset[32];
+/* 
+** Name:    safe_iconv
+** Purpose: 'Fault-tolerant' version if iconv. Replaces invalid seq with '?'
+** Input:   see iconv manpage
+*/
+int safe_iconv( iconv_t handle, const char **inbuf, size_t *inbytesleft,
+	     char **outbuf, size_t *outbytesleft);
+
+/*
+** Name:    guess_current_locale_charset
+** Purpose: Try to guess default charset for the current locale
+** Output:  charset name
+** FIXME:   is there more right method for guessing charset
+	    than scanning $LANG ?
+*/
+const char* guess_current_locale_charset();
+
+/*
+** Name:    Str2Utf8
+** Purpose: convert a string in UTF-8 format
+** Input:   inbuf     - the string to convert
+** Output:  a new string in UTF-8 format
+*/
+char *StrToUtf8( const char *inbuf );
+std::string StrToUtf8( const std::string &instr );
+/*
+** Name:    Utf8ToStr
+** Purpose: revert UTF-8 string conversion
+** Input:   inbuf  - the string to decode
+** Output:  a new decoded string
+*/
+char *Utf8ToStr( const char *inbuf );
+std::string Utf8ToStr( const std::string &instr );
+#endif

--- src/hooks/msnhook.cc.orig	Tue Nov 19 10:18:22 2002
+++ src/hooks/msnhook.cc	Tue Nov 19 10:18:35 2002
@@ -30,6 +30,7 @@
 #include "eventmanager.h"
 #include "centericq.h"
 #include "imlogger.h"
+#include "utf8conv.h"
 
 msnhook mhook;
 
@@ -159,7 +160,8 @@
     }
 
     icqcontact *c = clist.get(ev.getcontact());
-    text = siconv(text, conf.getrussian() ? "koi8-u" : DEFAULT_CHARSET, "utf8");
+    text = StrToUtf8(text);
+//    text = siconv(text, conf.getrussian() ? "koi8-u" : DEFAULT_CHARSET, "utf8");
 //    text = toutf8(rusconv("kw", text));
 
     if(c)
@@ -274,8 +276,8 @@
 	m.homepage = "http://members.msn.com/" + b.email;
 
 	if(!friendlynicks[ic.nickname].empty()) {
-	    c->setdispnick(friendlynicks[ic.nickname]);
-	    b.fname = friendlynicks[ic.nickname];
+	    c->setdispnick(Utf8ToStr(friendlynicks[ic.nickname]));
+	    b.fname = Utf8ToStr(friendlynicks[ic.nickname]);
 	}
 
 	c->setbasicinfo(b);
@@ -371,7 +373,8 @@
 	}
 
 //        text = rusconv("wk", fromutf8(d->msg));
-	text = siconv(d->msg, "utf8", conf.getrussian() ? "koi8-u" : DEFAULT_CHARSET);
+//	text = siconv(d->msg, "utf8", conf.getrussian() ? "koi8-u" : DEFAULT_CHARSET);
+	text = Utf8ToStr(d->msg);
 	em.store(immessage(ic, imevent::incoming, text));
 
 	if(c)
@@ -453,3 +456,117 @@
 	clist.get(contactroot)->playsound(imevent::email);
     }
 }
+#if HAVE_ICONV_H
+int safe_iconv( iconv_t handle, const char **inbuf, size_t *inbytesleft,
+	     char **outbuf, size_t *outbytesleft)
+{
+    int ret;
+    while (*inbytesleft) {
+	 ret = iconv( handle, inbuf, inbytesleft,
+		outbuf, outbytesleft);
+	if (!*inbytesleft || !*outbytesleft)
+	    return ret;
+	/*got invalid seq - so replace it with '?' */
+	**outbuf = '?'; (*outbuf)++; (*outbytesleft)--;
+	(*inbuf)++; (*inbytesleft)--;
+    }
+    return ret;
+}
+
+const char* guess_current_locale_charset()
+{
+    char *lang, *ch;
+    /* Return previously learned charset */
+    if (loc_charset[0])
+	return loc_charset;
+
+    lang = getenv("LANG");
+    ch = strrchr( lang, '.' ) + 1;
+    if (!ch)
+	strcpy( loc_charset, DEFAULT_CHARSET );
+    else {
+	iconv_t pt;
+	strncpy( loc_charset, ch, sizeof(loc_charset) );
+	/* try to open iconv handle using guessed charset */
+	if ( (pt = iconv_open( loc_charset, loc_charset )) == (iconv_t)(-1) )
+	{
+	    strcpy( loc_charset, DEFAULT_CHARSET );
+	} else {
+	    iconv_close(pt);
+	};
+	
+    }
+
+    return loc_charset;
+}
+
+char *StrToUtf8( const char *inbuf )
+{
+    size_t length = strlen( inbuf );
+    size_t outmaxlength = length * 4; /* FIXME: Is x4 multiplier enoght? */
+    char *outbuf = (char*) malloc( outmaxlength + 1 );
+    char *outbuf_save = outbuf;
+    int ret;
+
+    iconv_t handle = iconv_open( "utf-8", guess_current_locale_charset() );
+    ret = safe_iconv( handle, (const char **) &inbuf, &length, &outbuf, &outmaxlength );
+    
+    iconv_close( handle );
+
+    return outbuf_save;
+}
+ 
+std::string StrToUtf8( const std::string &instr )
+{
+    size_t length = instr.length();
+    size_t outmaxlength = length * 4; /* FIXME: Is x4 multiplier enoght? */
+    const char *inbuf = instr.c_str();
+    char *outbuf = (char*) malloc( outmaxlength + 1 );
+    char *outbuf_save = outbuf;
+    int ret;
+
+    iconv_t handle = iconv_open( "utf-8", guess_current_locale_charset() );
+    ret = safe_iconv( handle, (const char **) &inbuf, &length, &outbuf, &outmaxlength );
+    
+    iconv_close( handle );
+
+    std::string return_me = outbuf_save;
+    return return_me;
+}
+ 
+char *Utf8ToStr( const char *inbuf )
+{
+    size_t length = strlen( inbuf );
+    size_t outmaxlength = length;
+    char *outbuf = (char*) malloc( outmaxlength + 1 );
+    char *outbuf_save = outbuf;
+    int ret;
+
+    iconv_t handle = iconv_open( guess_current_locale_charset(), "utf-8" );
+
+    ret = safe_iconv( handle, (const char **) &inbuf, &length, &outbuf, &outmaxlength );
+    
+    iconv_close( handle );
+
+    return outbuf_save;
+}
+
+std::string Utf8ToStr( const std::string &instr )
+{
+    size_t length = instr.length();
+    size_t outmaxlength = length;
+    const char *inbuf = instr.c_str();
+    char *outbuf = (char*) malloc( outmaxlength + 1 );
+    char *outbuf_save = outbuf;
+    int ret;
+
+    iconv_t handle = iconv_open( guess_current_locale_charset(), "utf-8" );
+
+    ret = safe_iconv( handle, (const char **) &inbuf, &length, &outbuf, &outmaxlength );
+
+    iconv_close( handle );
+
+    std::string return_me = outbuf_save;
+    return return_me;
+}
+#endif /* HAVE_ICONV_H */
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: gnats-admin->freebsd-ports 
Responsible-Changed-By: tom 
Responsible-Changed-When: Tue Nov 19 07:05:51 PST 2002 
Responsible-Changed-Why:  
Misfiled PR 

http://www.freebsd.org/cgi/query-pr.cgi?pr=45465 
Responsible-Changed-From-To: freebsd-ports->ijliao 
Responsible-Changed-By: tom 
Responsible-Changed-When: Tue Nov 19 08:25:46 PST 2002 
Responsible-Changed-Why:  
Over to MAINTAINER 

http://www.freebsd.org/cgi/query-pr.cgi?pr=45465 
State-Changed-From-To: open->closed 
State-Changed-By: ijliao 
State-Changed-When: Tue Nov 19 20:04:44 PST 2002 
State-Changed-Why:  
committed, thanks 

http://www.freebsd.org/cgi/query-pr.cgi?pr=45465 
>Unformatted:
