Date: Wed, 30 Oct 2002 16:54:41 +0800 (CST) From: Cheng-Lung Sung <AlanSung@alansung.dragon2.net> To: FreeBSD-gnats-submit@FreeBSD.org Cc: clsung@dragon2.net Subject: ports/44740: [PATCH] centericq with MSN UTF-8 Support Message-ID: <200210300854.g9U8sfGX098193@alansung.dragon2.net>
next in thread | raw e-mail | index | archive | help
>Number: 44740 >Category: ports >Synopsis: [PATCH] centericq with MSN UTF-8 Support >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Wed Oct 30 01:00:09 PST 2002 >Closed-Date: >Last-Modified: >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: Because MSN Messager transfer msg with UTF-8 format, but original libmsn lacks of UTF-8 converter. After looking for solution at google.com, I found some patches which were not exactly suitable. Afterward, I examine patches and try to correct some bugs in patches. And here I sent the patch file with send-pr , hope this utf-8 patch can move to ports/centericq/patch. Original incorrect version patch: http://linux.cgs.pl/cicq/2002-02/0138.html >How-To-Repeat: Withour utf-8 , users can't transfer multibyte character to remote client correctly. Take myself for an example, using 'big5' charsets, can't deliver Chinese Big5 characters to remote client. >Fix: --- libmsn-0.1/msn_commands.cc.orig Wed Oct 16 18:20:59 2002 +++ libmsn-0.1/msn_commands.cc Wed Oct 30 16:44:55 2002 @@ -30,7 +30,10 @@ #include <sys/socket.h> #include <errno.h> #include <netdb.h> - +#define HAVE_ICONV_H 1 +#if HAVE_ICONV_H +#include <iconv.h> +#endif #include "libmsn.h" #include "msn_commands.h" #include "parse_utils.h" @@ -426,6 +429,128 @@ return 0; } +#if HAVE_ICONV_H +/* +** Name: safe_iconv +** Purpose: 'Fault-tolerant' version if iconv. Replaces invalid seq with '?' +** Input: see iconv manpage +*/ +static 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; +} + +/* charset name cache buffer */ +char loc_charset[32]; + +#define DEFAULT_CHARSET "ISO-8859-1" + +/* +** 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 ? +*/ +static char* guess_current_locale_charset() +{ + char *lang, *ch; + /* Return previously learned charset */ + return "big5"; + 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; +} +#endif /* HAVE_ICONV_H */ + +/* +** Name: Str2Utf8 +** Purpose: convert a string in UTF-8 format +** Input: inbuf - the string to convert +** Output: a new string in UTF-8 format +*/ +static char *StrToUtf8( const char *inbuf ) +{ +#if HAVE_ICONV_H + 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; +#else + char *outbuf = strdup( inbuf ); + char *outbuf_save = outbuf; + /* Clear eight bit */ + for (; *outbuf; ++outbuf) + *outbuf &= 0x7F; + return outbuf_save; +#endif +} + +/* +** Name: Utf8ToStr +** Purpose: revert UTF-8 string conversion +** Input: inbuf - the string to decode +** Output: a new decoded string +*/ +static char *Utf8ToStr( char *inbuf ) +{ +#if HAVE_ICONV_H + 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; +#else + return strdup( inbuf ); +#endif +} + /* ** Name: HandleMessage ** Purpose: This function handles an instant message from either the server @@ -440,6 +565,7 @@ { MSN_InstantMessage newIm; char *message; + char *decodedIm; char *mimeInfo, *im; int length, nread; struct timeval t; @@ -448,6 +574,8 @@ message = NULL; mimeInfo = NULL; im = NULL; + decodedIm = NULL; + if (numOfArgs != 4) return -1; @@ -470,13 +598,15 @@ if (mimeInfo != NULL) { if (strstr(mimeInfo, "text/plain") != NULL) { + + decodedIm = Utf8ToStr( im ); newIm.year = 0; newIm.month = 0; newIm.day = 0; newIm.hour = 0; newIm.minute = 0; newIm.sec = 0; - newIm.msg = im; + newIm.msg = decodedIm; RemoveHotmail(args[1], &newIm.sender); newIm.friendlyhandle = args[2]; newIm.fd = conn->fd; @@ -571,15 +701,18 @@ int SendMessage(MSN_Conn *conn, const char *message) { char *commandLine; + char *UTFmessage; int length; if (!message) return -1; + UTFmessage = NULL; - commandLine = (char *)malloc(strlen(MIME_HEADER)+strlen(message)+25); + UTFmessage = StrToUtf8( message ); + commandLine = (char *)malloc(strlen(MIME_HEADER)+strlen(UTFmessage)+25); length = sprintf(commandLine, "%s %lu N %d\r\n%s%s", CommandString[MSG], - TrID++, strlen(message)+strlen(MIME_HEADER), MIME_HEADER, - message); + TrID++, strlen(UTFmessage)+strlen(MIME_HEADER), MIME_HEADER, + UTFmessage); write(conn->fd, commandLine, length); free(commandLine); >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-ports" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200210300854.g9U8sfGX098193>