Experimental character set translation message reading

This commit is contained in:
Michiel Broek 2004-02-26 20:16:10 +00:00
parent ce30494be0
commit d296b1fb8a
6 changed files with 284 additions and 145 deletions

View File

@ -35,6 +35,13 @@ v0.51.1 21-Feb-2004
Added login check to see if user has a valid character set. Added login check to see if user has a valid character set.
Added Control-U 9 to display file to show the users character Added Control-U 9 to display file to show the users character
set in the menus screens. set in the menus screens.
Added experimental characterset translation to message read.
This will translate the message character set used to the users
character set. When translation is impossible a ? is printed.
Doesn't work well with Russion, but seems to work with German
text.
In delete file in home directory the Y/N keys were read from
the wrong language prompt.
mbmsg: mbmsg:
Writes the ^aCHRS: kludge again in new created messages. Writes the ^aCHRS: kludge again in new created messages.

View File

@ -66,3 +66,35 @@ char *getchrsdesc(int val)
} }
char *get_iconv_name(char *name)
{
if (!strncasecmp(name, "CP437", 5))
return (char *)"IBM437";
if (!strncasecmp(name, "CP850", 5))
return (char *)"IBM850";
if (!strncasecmp(name, "CP865", 5))
return (char *)"IBM865";
if (!strncasecmp(name, "CP866", 5))
return (char *)"IBM866";
if (!strncasecmp(name, "LATIN-1", 7))
return (char *)"ISO_8859-1";
if (!strncasecmp(name, "LATIN-2", 7))
return (char *)"ISO_8859-2";
if (!strncasecmp(name, "LATIN-5", 7))
return (char *)"ISO_8859-5";
if (!strncasecmp(name, "PC-8", 4))
return (char *)"IBM437";
if (!strncasecmp(name, "IBMPC", 5))
return (char *)"IBM437";
if (!strncasecmp(name, "+7_FIDO", 7))
return (char *)"IBM866";
if (!strncasecmp(name, "CP1125", 6))
return (char *)"CP1125";
Syslog('+', "get_iconv_name(%s): no usable character set name found", name);
return NULL;
}

View File

@ -2134,6 +2134,7 @@ int attach(faddr, char *, int, char);
*/ */
char *getchrs(int); /* Return characterset name */ char *getchrs(int); /* Return characterset name */
char *getchrsdesc(int); /* Return characterset description */ char *getchrsdesc(int); /* Return characterset description */
char *get_iconv_name(char *); /* Return usable name for iconv */

View File

@ -1481,7 +1481,7 @@ void Delete_Home()
fflush(stdout); fflush(stdout);
i = toupper(Getone()); i = toupper(Getone());
if (i == Keystroke(368, 0) || i == 13) { if (i == Keystroke(369, 0) || i == 13) {
i = unlink(temp); i = unlink(temp);
if (i == -1) { if (i == -1) {

View File

@ -1136,9 +1136,15 @@ int Export_a_Msg(unsigned long Num)
*/ */
int Read_a_Msg(unsigned long Num, int UpdateLR) int Read_a_Msg(unsigned long Num, int UpdateLR)
{ {
char *p = NULL, *fn; char *p = NULL, *fn, *charset = NULL, *charsin = NULL, *charsout = NULL;
int ShowMsg = TRUE; int ShowMsg = TRUE, UseIconv = FALSE;
lastread LR; lastread LR;
iconv_t iconvstr = (iconv_t)(0);
#ifdef HAVE_ICONV_H
size_t cnt, inleft, outleft;
char inbuf[256], outbuf[1024];
char *inb, *outb;
#endif
LastNum = Num; LastNum = Num;
iLineCount = 7; iLineCount = 7;
@ -1168,6 +1174,7 @@ int Read_a_Msg(unsigned long Num, int UpdateLR)
sleep(3); sleep(3);
return FALSE; return FALSE;
} }
if (Msg.Private) { if (Msg.Private) {
ShowMsg = FALSE; ShowMsg = FALSE;
if ((strcasecmp(exitinfo.sUserName, Msg.From) == 0) || (strcasecmp(exitinfo.sUserName, Msg.To) == 0)) if ((strcasecmp(exitinfo.sUserName, Msg.From) == 0) || (strcasecmp(exitinfo.sUserName, Msg.To) == 0))
@ -1195,6 +1202,15 @@ int Read_a_Msg(unsigned long Num, int UpdateLR)
if ((p = (char *)MsgText_First()) != NULL) if ((p = (char *)MsgText_First()) != NULL)
do { do {
if ((p[0] == '\001') || (!strncmp(p, "SEEN-BY:", 8)) || (!strncmp(p, "AREA:", 5))) { if ((p[0] == '\001') || (!strncmp(p, "SEEN-BY:", 8)) || (!strncmp(p, "AREA:", 5))) {
/*
* While we are here, check for the ^aCHRS: kludge and set the used charset.
*/
if (strncmp(p, "\001CHRS: ", 7) == 0) {
charset = xstrcpy(p + 7);
}
if (strncmp(p, "\001CHARSET: ", 10) == 0) {
charset = xstrcpy(p + 10);
}
if (Kludges) { if (Kludges) {
if (p[0] == '\001') { if (p[0] == '\001') {
p[0] = 'a'; p[0] = 'a';
@ -1212,6 +1228,32 @@ int Read_a_Msg(unsigned long Num, int UpdateLR)
} }
free(fn); free(fn);
if ((charset == NULL) && (msgs.Charset != FTNC_NONE)) {
/*
* No charset marked in the message, use the area charset
*/
charset = xstrcpy(getchrs(msgs.Charset));
}
charsin = xstrcpy(get_iconv_name(charset));
charsout = xstrcpy(get_iconv_name(getchrs(exitinfo.Charset)));
Syslog('b', "Stage 3: charset %s, translate %s to %s", MBSE_SS(charset), MBSE_SS(charsin), MBSE_SS(charsout));
#ifdef HAVE_ICONV_H
/*
* Try to setup iconv if the charactersets are different.
*/
if (charsin && charsout && strcmp(charsout, charsin)) {
charsout = xstrcat(charsout, (char *)"//TRANSLIT");
iconvstr = iconv_open(charsout, charsin);
if (iconvstr == (iconv_t)(-1)) {
Syslog('!', "$open_iconv(%s, %s)", charsin, charsout);
} else {
UseIconv = TRUE;
}
}
#endif
/* /*
* Show message text * Show message text
*/ */
@ -1231,7 +1273,42 @@ int Read_a_Msg(unsigned long Num, int UpdateLR)
if (strchr(p, '>') != NULL) if (strchr(p, '>') != NULL)
if ((strlen(p) - strlen(strchr(p, '>'))) < 10) if ((strlen(p) - strlen(strchr(p, '>'))) < 10)
colour(CFG.HiliteF, CFG.HiliteB); colour(CFG.HiliteF, CFG.HiliteB);
#ifdef HAVE_ICONV_H
if (UseIconv) {
/*
* Try to translate character sets with iconv
*/
inleft = outleft = strlen(p);
memset(&inbuf, 0, sizeof(inbuf));
memset(&outbuf, 0, sizeof(inbuf));
sprintf(inbuf, "%s", p);
inb = inbuf;
outb = outbuf;
cnt = iconv(iconvstr, &inb, &inleft, &outb, &outleft);
if (cnt == (size_t)(-1)) {
/*
* Failed, log and show original line.
*/
Syslog('b', "iconv cnt=%d inleft=%d outleft=%d", cnt, inleft, outleft);
Syslog('b', "%s", printable(p, 0));
Syslog('b', "$iconv");
printf("%s\n", p); printf("%s\n", p);
} else {
if (strcmp(inbuf, outbuf)) {
/*
* Success, translated and log
*/
Syslog('b', "< %s", MBSE_SS(inbuf));
Syslog('b', "> %s", MBSE_SS(outbuf));
}
printf("%s\n", outbuf);
}
} else {
printf("%s\n", p);
}
#else
printf("%s\n", p);
#endif
if (CheckLine(CFG.TextColourF, CFG.TextColourB, FALSE)) if (CheckLine(CFG.TextColourF, CFG.TextColourB, FALSE))
break; break;
} }
@ -1239,6 +1316,19 @@ int Read_a_Msg(unsigned long Num, int UpdateLR)
} }
} }
if (charset)
free(charset);
if (charsout)
free(charsout);
if (charsin)
free(charsin);
#ifdef HAVE_ICONV_H
if (UseIconv && (iconv_close(iconvstr) == -1)) {
Syslog('!', "$iconv_close()");
}
#endif
/* /*
* Set the Received status on this message if it's for the user. * Set the Received status on this message if it's for the user.
*/ */

View File

@ -43,6 +43,9 @@
#include "timeout.h" #include "timeout.h"
#include "funcs.h" #include "funcs.h"
#include <locale.h>
#include <langinfo.h>
extern int do_quiet; /* Logging quiet flag */ extern int do_quiet; /* Logging quiet flag */
time_t t_start; time_t t_start;
@ -205,6 +208,12 @@ int main(int argc, char **argv)
} }
} }
/*
* Some debugging for me
*/
Syslog('b', "setlocale() returns \"%s\"", printable(setlocale(LC_ALL, NULL), 0));
Syslog('b', "nl_langinfo(LC_CTYPE) returns \"%s\"", printable(nl_langinfo(LC_CTYPE), 0));
sprintf(sMailbox, "mailbox"); sprintf(sMailbox, "mailbox");
colour(LIGHTGRAY, BLACK); colour(LIGHTGRAY, BLACK);
user(); user();