Using Fidogate code to do charset translation

This commit is contained in:
Michiel Broek 2004-02-28 19:49:54 +00:00
parent d296b1fb8a
commit 7a7b810aec
13 changed files with 3259 additions and 137 deletions

View File

@ -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
View File

@ -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.

View File

@ -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
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

388
lib/mbcharsetc.c Normal file
View 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
View File

@ -0,0 +1,7 @@
#ifndef _MBCHARSET_H
#define _MBCHARSET_H
/* $Id$ */
#endif

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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.
*/ */