Using Fidogate code to do charset translation
This commit is contained in:
parent
d296b1fb8a
commit
7a7b810aec
@ -38,8 +38,8 @@ v0.51.1 21-Feb-2004
|
|||||||
Added experimental characterset translation to message read.
|
Added experimental characterset translation to message read.
|
||||||
This will translate the message character set used to the users
|
This will translate the message character set used to the users
|
||||||
character set. When translation is impossible a ? is printed.
|
character set. When translation is impossible a ? is printed.
|
||||||
Doesn't work well with Russion, but seems to work with German
|
After problems with iconv, switched to use code from Martin
|
||||||
text.
|
Junius Fidogate package.
|
||||||
In delete file in home directory the Y/N keys were read from
|
In delete file in home directory the Y/N keys were read from
|
||||||
the wrong language prompt.
|
the wrong language prompt.
|
||||||
|
|
||||||
|
2
TODO
2
TODO
@ -112,6 +112,8 @@ mbfido:
|
|||||||
N: Force processing of arealists so that all tags are forced to
|
N: Force processing of arealists so that all tags are forced to
|
||||||
uppercase. Seems to give problems in some nets.
|
uppercase. Seems to give problems in some nets.
|
||||||
|
|
||||||
|
N: Make tic areas check case insensitive.
|
||||||
|
|
||||||
N: Let mbfido areas with a special switch update area descriptions.
|
N: Let mbfido areas with a special switch update area descriptions.
|
||||||
|
|
||||||
N: Send rulefile via netmail for each new connected mail area.
|
N: Send rulefile via netmail for each new connected mail area.
|
||||||
|
@ -182,9 +182,6 @@
|
|||||||
/* Define if you have the <utmpx.h> header file. */
|
/* Define if you have the <utmpx.h> header file. */
|
||||||
#undef HAVE_UTMPX_H
|
#undef HAVE_UTMPX_H
|
||||||
|
|
||||||
/* Define if you have the <iconv.h> header file. */
|
|
||||||
#undef HAVE_ICONV_H
|
|
||||||
|
|
||||||
/* Define if you have the memcpy function. */
|
/* Define if you have the memcpy function. */
|
||||||
#undef HAVE_MEMCPY
|
#undef HAVE_MEMCPY
|
||||||
|
|
||||||
|
3
configure
vendored
3
configure
vendored
@ -5373,8 +5373,7 @@ done
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for ac_header in sys/resource.h usersec.h gshadow.h shadow.h
|
||||||
for ac_header in sys/resource.h usersec.h gshadow.h shadow.h iconv.h
|
|
||||||
do
|
do
|
||||||
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||||
if eval "test \"\${$as_ac_Header+set}\" = set"; then
|
if eval "test \"\${$as_ac_Header+set}\" = set"; then
|
||||||
|
@ -203,7 +203,7 @@ AC_HEADER_DIRENT
|
|||||||
AC_HEADER_TIME
|
AC_HEADER_TIME
|
||||||
AC_HEADER_SYS_WAIT
|
AC_HEADER_SYS_WAIT
|
||||||
AC_CHECK_HEADERS(sys/time.h termios.h sys/vfs.h unistd.h netinet/in.h regex.h)
|
AC_CHECK_HEADERS(sys/time.h termios.h sys/vfs.h unistd.h netinet/in.h regex.h)
|
||||||
AC_CHECK_HEADERS(sys/resource.h usersec.h gshadow.h shadow.h iconv.h)
|
AC_CHECK_HEADERS(sys/resource.h usersec.h gshadow.h shadow.h)
|
||||||
AC_CHECK_HEADERS(limits.h utmp.h utmpx.h lastlog.h rpc/key_prot.h)
|
AC_CHECK_HEADERS(limits.h utmp.h utmpx.h lastlog.h rpc/key_prot.h)
|
||||||
AC_STRUCT_TIMEZONE
|
AC_STRUCT_TIMEZONE
|
||||||
|
|
||||||
|
21
lib/Makefile
21
lib/Makefile
@ -33,17 +33,22 @@ MBINET_HDRS = mbinet.h
|
|||||||
DIESEL_SRCS = diesel.c mbdiesel.c
|
DIESEL_SRCS = diesel.c mbdiesel.c
|
||||||
DIESEL_HDRS = diesel.h
|
DIESEL_HDRS = diesel.h
|
||||||
DIESEL_OBJS = diesel.o mbdiesel.o
|
DIESEL_OBJS = diesel.o mbdiesel.o
|
||||||
|
CHC_SRCS = mbcharsetc.c
|
||||||
|
CHC_HDRS = mbcharsetc.h
|
||||||
|
CHC_OBJS = mbcharsetc.o
|
||||||
OTHER_HDRS = bluewave.h mbse.h users.h
|
OTHER_HDRS = bluewave.h mbse.h users.h
|
||||||
SRCS = ${COMMON_SRCS} ${DBASE_SRCS} ${MSGBASE_SRCS} ${MBINET_SRCS} \
|
SRCS = ${COMMON_SRCS} ${DBASE_SRCS} ${MSGBASE_SRCS} ${MBINET_SRCS} \
|
||||||
${DIESEL_SRCS} ${NODELIST_SRCS}
|
${DIESEL_SRCS} ${NODELIST_SRCS} ${CHC_SRCS}
|
||||||
OBJS = ${COMMON_OBJS} ${DBASE_OBJS} ${MSGBASE_OBJS} ${MBINET_OBJS} \
|
OBJS = ${COMMON_OBJS} ${DBASE_OBJS} ${MSGBASE_OBJS} ${MBINET_OBJS} \
|
||||||
${DIESEL_OBJS} ${NODELIST_OBJS}
|
${DIESEL_OBJS} ${NODELIST_OBJS} ${CHC_OBJS}
|
||||||
HDRS = ${COMMON_HDRS} ${DBASE_HDRS} ${MSGBASE_HDRS} ${MBINET_HDRS} \
|
HDRS = ${COMMON_HDRS} ${DBASE_HDRS} ${MSGBASE_HDRS} ${MBINET_HDRS} \
|
||||||
${DIESEL_HDRS} ${NODELIST_HDRS} ${OTHER_HDRS}
|
${DIESEL_HDRS} ${NODELIST_HDRS} ${CHC_HDRS} ${OTHER_HDRS}
|
||||||
|
MAPS = charset.map russian.map
|
||||||
OTHER = Makefile README ftscprod.008 mkprod.awk \
|
OTHER = Makefile README ftscprod.008 mkprod.awk \
|
||||||
README.diesel README.macro Diesel.doc nodelist.conf
|
README.diesel README.macro Diesel.doc nodelist.conf
|
||||||
TARGET = libmbse.a libdbase.a libmsgbase.a libmbinet.a libdiesel.a \
|
TARGET = libmbse.a libdbase.a libmsgbase.a libmbinet.a libdiesel.a \
|
||||||
libnodelist.a
|
libnodelist.a mbcharsetc charset.bin
|
||||||
|
LIBS += ../lib/libmbse.a
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
@ -79,8 +84,16 @@ libnodelist.a: ${NODELIST_OBJS}
|
|||||||
ar r $@ $?
|
ar r $@ $?
|
||||||
${RANLIB} $@
|
${RANLIB} $@
|
||||||
|
|
||||||
|
mbcharsetc: ${CHC_OBJS} ${LIBS}
|
||||||
|
${CC} -o mbcharsetc ${CHC_OBJS} ${LDFLAGS} ${LIBS}
|
||||||
|
|
||||||
|
charset.bin: mbcharsetc ${MAPS}
|
||||||
|
./mbcharsetc charset.map charset.bin
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
${INSTALL} -c -o ${OWNER} -g ${GROUP} -m 0444 nodelist.conf ${ETCDIR}
|
${INSTALL} -c -o ${OWNER} -g ${GROUP} -m 0444 nodelist.conf ${ETCDIR}
|
||||||
|
${INSTALL} -c -s -g ${GROUP} -o ${OWNER} -m 0751 mbcharsetc ${BINDIR}
|
||||||
|
${INSTALL} -c -o ${OWNER} -g ${GROUP} -m 0444 charset.bin ${ETCDIR}
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f ${TARGET} *.o *.h~ *.c~ ftscprod.c core filelist Makefile.bak
|
rm -f ${TARGET} *.o *.h~ *.c~ ftscprod.c core filelist Makefile.bak
|
||||||
|
382
lib/charset.c
382
lib/charset.c
@ -32,6 +32,84 @@
|
|||||||
#include "mbselib.h"
|
#include "mbselib.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define strieq(a,b) (strcasecmp ((a),(b)) == 0)
|
||||||
|
#define BUF_APPEND(d,s) str_append(d,sizeof(d),s)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Alias linked list
|
||||||
|
*/
|
||||||
|
static CharsetAlias *charset_alias_list = NULL;
|
||||||
|
static CharsetAlias *charset_alias_last = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table linked list
|
||||||
|
*/
|
||||||
|
static CharsetTable *charset_table_list = NULL;
|
||||||
|
static CharsetTable *charset_table_last = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Current charset mapping table
|
||||||
|
*/
|
||||||
|
static CharsetTable *charset_table_used = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* str_printf(): wrapper for sprintf()/snprintf()
|
||||||
|
*/
|
||||||
|
int str_printf(char *buf, size_t len, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
#ifdef HAS_SNPRINTF
|
||||||
|
n = vsnprintf(buf, len, fmt, args);
|
||||||
|
/**FIXME: check for n==-1 and errno**/
|
||||||
|
#else
|
||||||
|
n = vsprintf(buf, fmt, args);
|
||||||
|
if(n >= len) {
|
||||||
|
WriteError("Internal error - str_printf() buf overflow");
|
||||||
|
/**NOT REACHED**/
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Make sure that buf[] is terminated with a \0. vsnprintf()
|
||||||
|
* should do this automatically as required by the ANSI C99
|
||||||
|
* proposal, but one never knows ... see also discussion on
|
||||||
|
* BugTraq */
|
||||||
|
buf[len - 1] = 0;
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *str_append(char *d, size_t n, char *s)
|
||||||
|
{
|
||||||
|
int max = n - strlen(d) - 1;
|
||||||
|
|
||||||
|
strncat(d, s, max);
|
||||||
|
d[n-1] = 0;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
char *str_copy(char *d, size_t n, char *s)
|
||||||
|
{
|
||||||
|
strncpy(d, s, n);
|
||||||
|
d[n-1] = 0;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BUF_COPY(d,s) str_copy (d,sizeof(d),s)
|
||||||
|
|
||||||
|
|
||||||
char *getchrs(int val)
|
char *getchrs(int val)
|
||||||
{
|
{
|
||||||
switch (val) {
|
switch (val) {
|
||||||
@ -67,34 +145,288 @@ char *getchrsdesc(int val)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
char *get_iconv_name(char *name)
|
/*
|
||||||
|
* Alloc new CharsetTable and put into linked list
|
||||||
|
*/
|
||||||
|
CharsetTable *charset_table_new(void)
|
||||||
{
|
{
|
||||||
if (!strncasecmp(name, "CP437", 5))
|
CharsetTable *p;
|
||||||
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);
|
/* Alloc and clear */
|
||||||
return NULL;
|
p = (CharsetTable *)xmalloc(sizeof(CharsetTable));
|
||||||
|
memset(p, 0, sizeof(CharsetTable));
|
||||||
|
p->next = NULL; /* Just to be sure */
|
||||||
|
|
||||||
|
/* Put into linked list */
|
||||||
|
if(charset_table_list)
|
||||||
|
charset_table_last->next = p;
|
||||||
|
else
|
||||||
|
charset_table_list = p;
|
||||||
|
charset_table_last = p;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Alloc new CharsetAlias and put into linked list
|
||||||
|
*/
|
||||||
|
CharsetAlias *charset_alias_new(void)
|
||||||
|
{
|
||||||
|
CharsetAlias *p;
|
||||||
|
|
||||||
|
/* Alloc and clear */
|
||||||
|
p = (CharsetAlias *)xmalloc(sizeof(CharsetAlias));
|
||||||
|
memset(p, 0, sizeof(CharsetAlias));
|
||||||
|
p->next = NULL; /* Just to be sure */
|
||||||
|
|
||||||
|
/* Put into linked list */
|
||||||
|
if(charset_alias_list)
|
||||||
|
charset_alias_last->next = p;
|
||||||
|
else
|
||||||
|
charset_alias_list = p;
|
||||||
|
charset_alias_last = p;
|
||||||
|
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write binary mapping file
|
||||||
|
*/
|
||||||
|
int charset_write_bin(char *name)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
CharsetTable *pt;
|
||||||
|
CharsetAlias *pa;
|
||||||
|
|
||||||
|
// debug(14, "Writing charset.bin file %s", name);
|
||||||
|
|
||||||
|
fp = fopen(name, "w+");
|
||||||
|
if(!fp)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Write aliases */
|
||||||
|
for (pa = charset_alias_list; pa; pa=pa->next) {
|
||||||
|
fputc(CHARSET_FILE_ALIAS, fp);
|
||||||
|
fwrite(pa, sizeof(CharsetAlias), 1, fp);
|
||||||
|
if(ferror(fp)) {
|
||||||
|
fclose(fp);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write tables */
|
||||||
|
for(pt = charset_table_list; pt; pt=pt->next) {
|
||||||
|
fputc(CHARSET_FILE_TABLE, fp);
|
||||||
|
fwrite(pt, sizeof(CharsetTable), 1, fp);
|
||||||
|
if(ferror(fp)) {
|
||||||
|
fclose(fp);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read binary mapping file
|
||||||
|
*/
|
||||||
|
int charset_read_bin(void)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int c, n;
|
||||||
|
CharsetTable *pt;
|
||||||
|
CharsetAlias *pa;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
name = calloc(PATH_MAX, sizeof(char));
|
||||||
|
sprintf(name, "%s/etc/charset.bin", getenv("MBSE_ROOT"));
|
||||||
|
Syslog('s', "Reading %s", name);
|
||||||
|
if ((fp = fopen(name, "r")) == NULL) {
|
||||||
|
WriteError("$Can't open %s", name);
|
||||||
|
free(name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
free(name);
|
||||||
|
|
||||||
|
while( (c = fgetc(fp)) != EOF ) {
|
||||||
|
switch(c) {
|
||||||
|
case CHARSET_FILE_ALIAS:
|
||||||
|
pa = charset_alias_new();
|
||||||
|
n = fread((void *)pa, sizeof(CharsetAlias), 1, fp);
|
||||||
|
pa->next = NULL; /* overwritten by fread() */
|
||||||
|
if(n != 1)
|
||||||
|
return FALSE;
|
||||||
|
Syslog('s', "read charset alias: %s -> %s", pa->alias, pa->name);
|
||||||
|
break;
|
||||||
|
case CHARSET_FILE_TABLE:
|
||||||
|
pt = charset_table_new();
|
||||||
|
n = fread((void *)pt, sizeof(CharsetTable), 1, fp);
|
||||||
|
pt->next = NULL; /* overwritten by fread() */
|
||||||
|
if(n != 1)
|
||||||
|
return FALSE;
|
||||||
|
Syslog('s', "read charset table: %s -> %s", pt->in, pt->out);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ferror(fp))
|
||||||
|
return FALSE;
|
||||||
|
fclose(fp);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert to MIME quoted-printable =XX if qp==TRUE
|
||||||
|
*/
|
||||||
|
char *charset_qpen(int c, int qp)
|
||||||
|
{
|
||||||
|
static char buf[4];
|
||||||
|
|
||||||
|
c &= 0xff;
|
||||||
|
|
||||||
|
if( qp && (c == '=' || c >= 0x80) )
|
||||||
|
str_printf(buf, sizeof(buf), "=%02.2X", c & 0xff);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf[0] = c;
|
||||||
|
buf[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map single character
|
||||||
|
*/
|
||||||
|
char *charset_map_c(int c, int qp)
|
||||||
|
{
|
||||||
|
static char buf[MAX_CHARSET_OUT * 4];
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
c &= 0xff;
|
||||||
|
buf[0] = 0;
|
||||||
|
|
||||||
|
if(charset_table_used && c>=0x80)
|
||||||
|
{
|
||||||
|
s = charset_table_used->map[c - 0x80];
|
||||||
|
while(*s)
|
||||||
|
BUF_APPEND(buf, charset_qpen(*s++, qp));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BUF_COPY(buf, charset_qpen(c, qp));
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search alias
|
||||||
|
*/
|
||||||
|
char *charset_alias_fsc(char *name)
|
||||||
|
{
|
||||||
|
CharsetAlias *pa;
|
||||||
|
|
||||||
|
/* Search for aliases */
|
||||||
|
for(pa = charset_alias_list; pa; pa=pa->next)
|
||||||
|
{
|
||||||
|
if(strieq(pa->name, name))
|
||||||
|
return pa->alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
char *charset_alias_rfc(char *name)
|
||||||
|
{
|
||||||
|
CharsetAlias *pa;
|
||||||
|
|
||||||
|
/* Search for aliases */
|
||||||
|
for(pa = charset_alias_list; pa; pa=pa->next)
|
||||||
|
{
|
||||||
|
if(strieq(pa->alias, name))
|
||||||
|
return pa->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set character mapping table
|
||||||
|
*/
|
||||||
|
int charset_set_in_out(char *in, char *out)
|
||||||
|
{
|
||||||
|
CharsetTable *pt;
|
||||||
|
CharsetAlias *pa;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!in || !out)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if charset.bin is loaded.
|
||||||
|
*/
|
||||||
|
if ((charset_alias_list == NULL) || (charset_table_list == NULL))
|
||||||
|
charset_read_bin();
|
||||||
|
Syslog('s', "charset1: in=%s out=%s", in, out);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For charset names with a space (level number), shorten the name.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < strlen(in); i++)
|
||||||
|
if (in[i] == ' ') {
|
||||||
|
in[i] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < strlen(out); i++)
|
||||||
|
if (out[i] == ' ') {
|
||||||
|
out[i] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Syslog('s', "charset2: in=%s out=%s", in, out);
|
||||||
|
|
||||||
|
/* Search for aliases */
|
||||||
|
for (pa = charset_alias_list; pa; pa=pa->next) {
|
||||||
|
if (strieq(pa->alias, in))
|
||||||
|
in = pa->name;
|
||||||
|
if (strieq(pa->alias, out))
|
||||||
|
out = pa->name;
|
||||||
|
}
|
||||||
|
Syslog('s', "charset3: in=%s out=%s", in, out);
|
||||||
|
|
||||||
|
/* Search for matching table */
|
||||||
|
for (pt = charset_table_list; pt; pt=pt->next) {
|
||||||
|
if(strieq(pt->in, in) && strieq(pt->out, out)) {
|
||||||
|
Syslog('s', "charset: table found in=%s out=%s", pt->in, pt->out);
|
||||||
|
charset_table_used = pt;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Syslog('b', "charset: no table found in=%s out=%s", in, out);
|
||||||
|
charset_table_used = NULL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
1321
lib/charset.map
Normal file
1321
lib/charset.map
Normal file
File diff suppressed because it is too large
Load Diff
388
lib/mbcharsetc.c
Normal file
388
lib/mbcharsetc.c
Normal file
@ -0,0 +1,388 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
* Purpose ...............: Characterset Compiler
|
||||||
|
* Author ................: Martin Junius, for Fidogate
|
||||||
|
*
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 1997-2004
|
||||||
|
*
|
||||||
|
* Michiel Broek FIDO: 2:280/2802
|
||||||
|
* Beekmansbos 10
|
||||||
|
* 1971 BV IJmuiden
|
||||||
|
* the Netherlands
|
||||||
|
*
|
||||||
|
* This file is part of MBSE BBS.
|
||||||
|
*
|
||||||
|
* This BBS is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
* later version.
|
||||||
|
*
|
||||||
|
* MBSE BBS is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with MBSE BBS; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* FIDOGATE --- Gateway UNIX Mail/News <-> FTN NetMail/EchoMail
|
||||||
|
*
|
||||||
|
* Charset mapping table compiler
|
||||||
|
*
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (C) 1990-2002
|
||||||
|
* _____ _____
|
||||||
|
* | |___ | Martin Junius <mj@fidogate.org>
|
||||||
|
* | | | | | | Radiumstr. 18
|
||||||
|
* |_|_|_|@home| D-51069 Koeln, Germany
|
||||||
|
*
|
||||||
|
* This file is part of FIDOGATE.
|
||||||
|
*
|
||||||
|
* FIDOGATE is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
* later version.
|
||||||
|
*
|
||||||
|
* FIDOGATE is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with FIDOGATE; see the file COPYING. If not, write to the Free
|
||||||
|
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "../config.h"
|
||||||
|
#include "mbselib.h"
|
||||||
|
#include "mbcharsetc.h"
|
||||||
|
|
||||||
|
|
||||||
|
char *str_copy(char *, size_t, char *);
|
||||||
|
|
||||||
|
#define strieq(a,b) (strcasecmp ((a),(b)) == 0)
|
||||||
|
#define PROGRAM "mbcharsetc"
|
||||||
|
#define BUFFERSIZE (32*1024) /* Global buffer */
|
||||||
|
#define BUF_COPY(d,s) str_copy (d,sizeof(d),s)
|
||||||
|
|
||||||
|
char buffer[BUFFERSIZE];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prototypes
|
||||||
|
*/
|
||||||
|
int charset_parse_c (char *);
|
||||||
|
int charset_do_file (char *);
|
||||||
|
int compile_map (char *, char *);
|
||||||
|
void usage (void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for hex digits, signed char-safe version of isxdigit()
|
||||||
|
*/
|
||||||
|
int is_xdigit(int c)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Some <ctype.h> implementation only accept a parameter value range
|
||||||
|
* of [-1,255]. This may lead to problems, because we're quite often
|
||||||
|
* passing *p's to is_digit() with a char *p variable. The default
|
||||||
|
* char type is signed in most C implementation.
|
||||||
|
*/
|
||||||
|
return isxdigit((c & 0xff));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for octal digits
|
||||||
|
*/
|
||||||
|
int is_odigit(int c)
|
||||||
|
{
|
||||||
|
return c>='0' && c<'8';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* isspace() replacement, checking for SPACE, TAB, CR, LF
|
||||||
|
*/
|
||||||
|
int is_space(int c)
|
||||||
|
{
|
||||||
|
return c==' ' || c=='\t' || c=='\r' || c=='\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read line from config file. Strip `\n', leading spaces,
|
||||||
|
* comments (starting with `#'), and empty lines. cf_getline() returns
|
||||||
|
* a pointer to the first non-whitespace in buffer.
|
||||||
|
*/
|
||||||
|
static long cf_lineno = 0;
|
||||||
|
|
||||||
|
long cf_lineno_get(void)
|
||||||
|
{
|
||||||
|
return cf_lineno;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long cf_lineno_set(long n)
|
||||||
|
{
|
||||||
|
long old;
|
||||||
|
|
||||||
|
old = cf_lineno;
|
||||||
|
cf_lineno = n;
|
||||||
|
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *cf_getline(char *cbuffer, int len, FILE *fp)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
while (fgets(cbuffer, len, fp)) {
|
||||||
|
cf_lineno++;
|
||||||
|
Striplf(cbuffer);
|
||||||
|
for(p = cbuffer; *p && is_space(*p); p++) ; /* Skip white spaces */
|
||||||
|
if (*p != '#')
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse character
|
||||||
|
*/
|
||||||
|
int charset_parse_c(char *s)
|
||||||
|
{
|
||||||
|
int val, n;
|
||||||
|
|
||||||
|
if(s[0] == '\\') { /* Special: \NNN or \xNN */
|
||||||
|
s++;
|
||||||
|
val = 0;
|
||||||
|
n = 0;
|
||||||
|
if(s[0]=='x' || s[0]=='X') { /* Hex */
|
||||||
|
s++;
|
||||||
|
while (is_xdigit(s[0]) && n<2) {
|
||||||
|
s[0] = toupper(s[0]);
|
||||||
|
val = val * 16 + s[0] - (s[0]>'9' ? 'A'-10 : '0');
|
||||||
|
s++;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
if(*s)
|
||||||
|
return ERROR;
|
||||||
|
} else { /* Octal */
|
||||||
|
while(is_odigit(s[0]) && n<3) {
|
||||||
|
val = val * 8 + s[0] - '0';
|
||||||
|
s++;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
if(*s)
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(s[1] == 0) /* Single char */
|
||||||
|
val = s[0] & 0xff;
|
||||||
|
else
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process one line from charset.map file
|
||||||
|
*/
|
||||||
|
int charset_do_line(char *line)
|
||||||
|
{
|
||||||
|
static CharsetTable *pt = NULL;
|
||||||
|
char *key, *w1, *w2;
|
||||||
|
CharsetAlias *pa;
|
||||||
|
int i, c1, c2;
|
||||||
|
|
||||||
|
key = strtok(line, " \t");
|
||||||
|
if(!key)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (strieq(key, "include")) {
|
||||||
|
w1 = strtok(NULL, " \t");
|
||||||
|
if (charset_do_file(w1) == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Define alias */
|
||||||
|
else if (strieq(key, "alias")) {
|
||||||
|
w1 = strtok(NULL, " \t");
|
||||||
|
w2 = strtok(NULL, " \t");
|
||||||
|
if(!w1 || !w2) {
|
||||||
|
fprintf(stderr, "%s:%ld: argument(s) for alias missing\n", PROGRAM, cf_lineno_get());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pa = charset_alias_new();
|
||||||
|
BUF_COPY(pa->alias, w1);
|
||||||
|
BUF_COPY(pa->name, w2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Define table */
|
||||||
|
else if (strieq(key, "table")) {
|
||||||
|
w1 = strtok(NULL, " \t");
|
||||||
|
w2 = strtok(NULL, " \t");
|
||||||
|
if(!w1 || !w2) {
|
||||||
|
fprintf(stderr, "%s:%ld: argument(s) for table missing\n", PROGRAM, cf_lineno_get());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pt = charset_table_new();
|
||||||
|
BUF_COPY(pt->in, w1);
|
||||||
|
BUF_COPY(pt->out, w2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Define mapping for character(s) in table */
|
||||||
|
else if (strieq(key, "map")) {
|
||||||
|
w1 = strtok(NULL, " \t");
|
||||||
|
if (!w1) {
|
||||||
|
fprintf(stderr, "%s:%ld: argument for map missing\n", PROGRAM, cf_lineno_get());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1:1 mapping */
|
||||||
|
if (strieq(w1, "1:1")) {
|
||||||
|
for(i=0; i<MAX_CHARSET_IN; i++) {
|
||||||
|
if(pt->map[i][0] == 0) {
|
||||||
|
pt->map[i][0] = 0x80 + i;
|
||||||
|
pt->map[i][1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 1:1 mapping, but not for 0x80...0x9f */
|
||||||
|
if(strieq(w1, "1:1-noctrl")) {
|
||||||
|
for(i=0x20; i<MAX_CHARSET_IN; i++) {
|
||||||
|
if(pt->map[i][0] == 0) {
|
||||||
|
pt->map[i][0] = 0x80 + i;
|
||||||
|
pt->map[i][1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Mapping for undefined characters */
|
||||||
|
else if(strieq(w1, "default")) {
|
||||||
|
/**FIXME: not yet implemented**/
|
||||||
|
}
|
||||||
|
/* Normal mapping */
|
||||||
|
else {
|
||||||
|
if ((c1 = charset_parse_c(w1)) == ERROR) {
|
||||||
|
fprintf(stderr, "%s:%ld: illegal char %s\n", PROGRAM, cf_lineno_get(), w1);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (c1 < 0x80) {
|
||||||
|
fprintf(stderr, "%s:%ld: illegal char %s, must be >= 0x80\n", PROGRAM, cf_lineno_get(), w1);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<MAX_CHARSET_OUT-1 && (w2 = strtok(NULL, " \t")); i++ ) {
|
||||||
|
if( (c2 = charset_parse_c(w2)) == ERROR) {
|
||||||
|
fprintf(stderr, "%s:%ld: illegal char definition %s\n", PROGRAM, cf_lineno_get(), w2);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
pt->map[c1 & 0x7f][i] = c2;
|
||||||
|
}
|
||||||
|
for (; i<MAX_CHARSET_OUT; i++)
|
||||||
|
pt->map[c1 & 0x7f][i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Error */
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "%s:%ld: illegal key word %s\n", PROGRAM, cf_lineno_get(), key);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process charset.map file
|
||||||
|
*/
|
||||||
|
int charset_do_file(char *name)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *p;
|
||||||
|
long oldn;
|
||||||
|
|
||||||
|
if(!name)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
oldn = cf_lineno_set(0);
|
||||||
|
fp = fopen(name, "r");
|
||||||
|
if(!fp)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
while ((p = cf_getline(buffer, BUFFERSIZE, fp)))
|
||||||
|
charset_do_line(p);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
cf_lineno_set(oldn);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compile charset.map
|
||||||
|
*/
|
||||||
|
int compile_map(char *in, char *out)
|
||||||
|
{
|
||||||
|
/* Read charset.map and compile */
|
||||||
|
if(charset_do_file(in) == FALSE) {
|
||||||
|
fprintf(stderr, "%s: compiling map file %s failed", PROGRAM, in);
|
||||||
|
return MBERR_GENERAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write binary output file */
|
||||||
|
if (charset_write_bin(out) == ERROR) {
|
||||||
|
fprintf(stderr, "%s: writing binary map file %s failed", PROGRAM, out);
|
||||||
|
return MBERR_GENERAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MBERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "\n%s: MBSE BBS %s Character Map Compiler\n", PROGRAM, VERSION);
|
||||||
|
fprintf(stderr, " %s\n\n", COPYRIGHT);
|
||||||
|
fprintf(stderr, "usage: %s charset.map charset.bin\n\n", PROGRAM);
|
||||||
|
exit(MBERR_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret = MBERR_OK;
|
||||||
|
char *name_in, *name_out;
|
||||||
|
|
||||||
|
if (argc != 3)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
name_in = argv[1];
|
||||||
|
name_out = argv[2];
|
||||||
|
ret = compile_map(name_in, name_out);
|
||||||
|
|
||||||
|
exit(ret);
|
||||||
|
}
|
||||||
|
|
7
lib/mbcharsetc.h
Normal file
7
lib/mbcharsetc.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef _MBCHARSET_H
|
||||||
|
#define _MBCHARSET_H
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -92,9 +92,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
#ifdef HAVE_ICONV_H
|
|
||||||
#include <iconv.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -376,39 +373,6 @@ struct icmp_filter {
|
|||||||
#define FTNC_MAXCHARS 8 /* Highest charset number */
|
#define FTNC_MAXCHARS 8 /* Highest charset number */
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Mapping:
|
|
||||||
*
|
|
||||||
* Kludge iconv name
|
|
||||||
* ---------- ---------------
|
|
||||||
* ASCII 1 ISO646-US
|
|
||||||
* DUTCH 1
|
|
||||||
* FINNISH 1 ISO646-FI
|
|
||||||
* FRENCH 1 ISO646-FR
|
|
||||||
* CANADIAN 1 ISO646-CA
|
|
||||||
* GERMAN 1
|
|
||||||
* ITALIAN 1 ISO646-IT
|
|
||||||
* NORWEIG 1 ISO646-NO
|
|
||||||
* PORTU 1 ISO646-PT
|
|
||||||
* SPANISH 1 ISO646-ES
|
|
||||||
* SWEDISH 1 ISO646-SE
|
|
||||||
* SWISS 1
|
|
||||||
* UK 1 ISO646-GB
|
|
||||||
* CP437 2 CP437
|
|
||||||
* CP850 2 CP850
|
|
||||||
* CP865 2 CP865
|
|
||||||
* CP866 2 CP766
|
|
||||||
* LATIN-1 2 ISO8859-1
|
|
||||||
* LATIN-2 2 ISO8859-2
|
|
||||||
* LATIN-5 2 ISO8859-5
|
|
||||||
* MAC 2 MAC
|
|
||||||
* PC-8 ISO646-US
|
|
||||||
* IBMPC 2 CP437
|
|
||||||
* UKR 2 CP866
|
|
||||||
* +7_FIDO CP866
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* Global typedefs.
|
* Global typedefs.
|
||||||
@ -2129,15 +2093,6 @@ int attach(faddr, char *, int, char);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* From charset.c
|
|
||||||
*/
|
|
||||||
char *getchrs(int); /* Return characterset name */
|
|
||||||
char *getchrsdesc(int); /* Return characterset description */
|
|
||||||
char *get_iconv_name(char *); /* Return usable name for iconv */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* From dostran.c
|
* From dostran.c
|
||||||
*/
|
*/
|
||||||
@ -2461,6 +2416,48 @@ int gpt_running(int); /* Is timer running */
|
|||||||
int msleep(int); /* Milliseconds timer */
|
int msleep(int); /* Milliseconds timer */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
*
|
||||||
|
* Charset mapping
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MAX_CHARSET_NAME 16
|
||||||
|
#define MAX_CHARSET_IN 128
|
||||||
|
#define MAX_CHARSET_OUT 4
|
||||||
|
|
||||||
|
#define CHARSET_FILE_ALIAS 'A' /* Id for binary file */
|
||||||
|
#define CHARSET_FILE_TABLE 'T' /* Id for binary file */
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct st_charset_alias {
|
||||||
|
char alias[MAX_CHARSET_NAME]; /* Alias charset name */
|
||||||
|
char name[MAX_CHARSET_NAME]; /* Real charset name */
|
||||||
|
struct st_charset_alias *next;
|
||||||
|
} CharsetAlias;
|
||||||
|
|
||||||
|
typedef struct st_charset_table {
|
||||||
|
char in[MAX_CHARSET_NAME]; /* Input charset name */
|
||||||
|
char out[MAX_CHARSET_NAME]; /* Output charset name */
|
||||||
|
char map[MAX_CHARSET_IN][MAX_CHARSET_OUT];
|
||||||
|
struct st_charset_table *next;
|
||||||
|
} CharsetTable;
|
||||||
|
|
||||||
|
|
||||||
|
char *getchrs(int); /* Return characterset name */
|
||||||
|
char *getchrsdesc(int); /* Return characterset description */
|
||||||
|
CharsetTable *charset_table_new(void); /* Add table to linked list */
|
||||||
|
CharsetAlias *charset_alias_new(void); /* Add alias to linked list */
|
||||||
|
int charset_write_bin(char *); /* Save charset.bin */
|
||||||
|
int charset_read_bin(void); /* Load ~/etc/charset.bin */
|
||||||
|
char *charset_qpen(int, int); /* Convert to MIME quoted-printable */
|
||||||
|
char *charset_map_c(int, int); /* map single character */
|
||||||
|
char *charset_alias_fsc(char *); /* Search FSC alias */
|
||||||
|
char *charset_alias_rfc(char *); /* Search RFC alias */
|
||||||
|
int charset_set_in_out(char *, char *); /* Setup mapping */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
*
|
*
|
||||||
* Records data
|
* Records data
|
||||||
|
1111
lib/russian.map
Normal file
1111
lib/russian.map
Normal file
File diff suppressed because it is too large
Load Diff
@ -1137,14 +1137,8 @@ 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, *charset = NULL, *charsin = NULL, *charsout = NULL;
|
char *p = NULL, *fn, *charset = NULL, *charsin = NULL, *charsout = NULL;
|
||||||
int ShowMsg = TRUE, UseIconv = FALSE;
|
int i, 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;
|
||||||
@ -1234,25 +1228,16 @@ int Read_a_Msg(unsigned long Num, int UpdateLR)
|
|||||||
*/
|
*/
|
||||||
charset = xstrcpy(getchrs(msgs.Charset));
|
charset = xstrcpy(getchrs(msgs.Charset));
|
||||||
}
|
}
|
||||||
charsin = xstrcpy(get_iconv_name(charset));
|
charsin = xstrcpy(charset);
|
||||||
charsout = xstrcpy(get_iconv_name(getchrs(exitinfo.Charset)));
|
charsout = xstrcpy(getchrs(exitinfo.Charset));
|
||||||
Syslog('b', "Stage 3: charset %s, translate %s to %s", MBSE_SS(charset), MBSE_SS(charsin), MBSE_SS(charsout));
|
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.
|
* Try to setup charset mapping if the charactersets are different.
|
||||||
*/
|
*/
|
||||||
if (charsin && charsout && strcmp(charsout, charsin)) {
|
if (charsin && charsout && strcmp(charsout, charsin)) {
|
||||||
|
UseIconv = charset_set_in_out(charsin, charsout);
|
||||||
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
|
||||||
@ -1273,42 +1258,18 @@ 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) {
|
if (UseIconv) {
|
||||||
/*
|
/*
|
||||||
* Try to translate character sets with iconv
|
* Try to translate character sets
|
||||||
*/
|
*/
|
||||||
inleft = outleft = strlen(p);
|
for (i = 0; i < strlen(p); i++) {
|
||||||
memset(&inbuf, 0, sizeof(inbuf));
|
printf("%s", charset_map_c(p[i], FALSE));
|
||||||
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);
|
|
||||||
} 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);
|
|
||||||
}
|
}
|
||||||
|
printf("\n");
|
||||||
} else {
|
} else {
|
||||||
printf("%s\n", p);
|
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;
|
||||||
}
|
}
|
||||||
@ -1323,12 +1284,6 @@ int Read_a_Msg(unsigned long Num, int UpdateLR)
|
|||||||
if (charsin)
|
if (charsin)
|
||||||
free(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.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user