#include "emil.h"
#include "charset/strncnv.c"
int strptrncnv(CHARSET *, CHARSET *, struct data *, struct data *, int);
int
tocharset(struct message *m)
{
CHARSET *schar, *tchar;
struct data *inbuf, *outbuf;
char *sset, *tset;
int copy = 0;
inbuf = m->td;
schar = NULL;
tchar = NULL;
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* Tocharset");
#endif
if (inbuf->size == 0)
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, "--- Empty input (failed).\n");
#endif
return(NOK);
}
sset = m->td->charset;
#ifdef DEBUG
if (edebug)
{
if (sset == NULL)
fprintf(stderr, "Source charset is NULL\n");
else
fprintf(stderr, "Source charset is %s\n", sset);
}
#endif
if (sset != NULL)
{
if ((strcasecmp(sset, "DK-US") == 0) ||
(strcasecmp(sset, "US-DK") == 0))
{
m->td->charset = NEWSTR("US-ASCII");
return(OK);
}
if ((strncasecmp(sset, "ISO-8859-", 9) == 0) &&
m->td->encoding == E7BIT)
{
m->td->charset = NEWSTR("US-ASCII");
return(OK);
}
if (cmatch(sset, "US-ASCII"))
return(OK);
}
if (target->itext == E7BIT || target->itext == ESE)
tset = NEWSTR("ISO-8859-1");
else
{
tset = target->charset;
if (cmatch(sset, tset))
copy = 1;
}
if (sset == NULL || tset == NULL ||
(schar = (CHARSET *)getchset(sset, 29)) == NULL ||
(tchar = (CHARSET *)getchset(tset, 29)) == NULL)
copy = 1;
if (schar != NULL && schar->cs->bits == 7 && inbuf->encoding == E8BIT)
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, ", corrupt charset specification.\n");
#endif
logger(LOG_DEBUG, "tocharset: corrupt source charset specification");
return(NOK);
}
if (copy)
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, ", copying (failed).\n");
#endif
logger(LOG_DEBUG, "tocharset: just copying");
return(NOK);
}
else
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, ", from %s to %s",
sset, tset);
#endif
outbuf = (struct data *) Yalloc(sizeof(struct data ));
strptrncnv(tchar, schar, outbuf, inbuf, pz);
outbuf->bodyend = outbuf->end;
outbuf->charset = NEWSTR(tset);
outbuf->lineend = inbuf->lineend - inbuf->linestart;
safe_mchange(m, outbuf);
}
if (target->itext == E7BIT)
{
m->td->offset = m->td->bodystart;
to_stripped(m);
m->td->charset = target->charset;
}
if (target->itext == ESE)
{
m->td->offset = m->td->bodystart;
to_7bit(m);
m->td->charset = target->charset;
}
check_bits(m->td);
if (m->td->encoding == E7BIT &&
(m->td->charset == NULL || strncasecmp(m->td->charset, "ISO-8859-", 9 ) == 0))
m->td->charset = NEWSTR("US-ASCII");
#ifdef DEBUG
if (edebug)
fprintf(stderr, ", done.\n");
#endif
return(OK);
}
int
strptrncnv(register CHARSET *r_chset, register CHARSET *s_chset,
struct data *outbuf, struct data *inbuf, int busize)
{
CHAR8U *source;
CHAR8U c, c1;
/* 4 chars for ending: esc two-char nul */
int o; /* intermediate binary value */
/* INT16S mnem; ... Unused ... 941114 / TW */
int oc; /* 2-byte output value */
int bytes;
int gotesc2;
source = (CHAR8U *) (inbuf->contents + inbuf->offset);
bytes = r_chset->cs->outbytes;
gotesc2= 0;
while ((c = *source++) diff 0 && inbuf->offset < inbuf->bodyend) {
inbuf->offset += 1;
if (c == s_esc and (! s_esc2 || s_esc2 == *source))
{
if (s_esc2)
{
inbuf->offset += 1;
source++;
}
/* Two esc in a row -> one escape
* If esc followed by defined mnemonic,
* next char is mnemonic. */
if (*source == s_esc and (! s_esc2 || s_esc2 == *(source+1)))
{
if (s_esc2)
gotesc2++;
o = *(s_in + s_esc);
/* handle 2 escs */
source++;
inbuf->offset += 1;
if (s_esc2)
{
inbuf->offset += 1;
source++;
}
}
else
{ /* mnemonic */
inbuf->offset += 1;
c = *source++;
if (c == '_')
{
/* long ?? */
}
else
{
c1 = *source++;
inbuf->offset += 1;
o = *(ot1+*(s_in+c)) + *(ot2+*(s_in+c1));
}
}
}
else
o = *(s_in + c);
if (o > hdr.outsize) /* special handling */
{
if (o < hdr.begcombtabs ) /* long mnem */
{
}
else
{ /* combtabs */
c1 = *source++;
inbuf->offset += 1;
o=(char)*(s_in + (o-hdr.begcombtabs+1)*C256 +c1);
}
}
if (! o)
o = 141; /* if not defined: underline */
if (bytes ==2)
oc= *((INT16S *) r_out + o);
else
oc= *(r_out + o);
if (gotesc2) {
gotesc2= *(s_in+s_esc2);
if (! gotesc2)
gotesc2= 141;
if (bytes ==2)
gotesc2= *((INT16S *) r_out + gotesc2);
else
gotesc2= *(r_out + gotesc2);
oc = oc *C256 + gotesc2;
gotesc2=0;
}
if (oc == r_esca)
{ /* write 2 escs */
append_char(outbuf, r_esc, busize);
if (r_esc2)
append_char(outbuf, r_esc2, busize);
append_char(outbuf, r_esc, busize);
if (r_esc2)
append_char(outbuf, r_esc2, busize);
}
else
if (oc)
{
if (oc/C256)
append_char(outbuf, oc>>8, busize);
append_char(outbuf, oc%C256, busize);
}
else
{
append_char(outbuf, r_esc, busize);
if (r_esc2)
append_char(outbuf, r_esc2, busize);
if (bytes == 2)
{
append_char(outbuf, *((INT16S *)r_out + hdr.basechrs + o%hdr.basechrs), busize);
append_char(outbuf, *((INT16S *)r_out + hdr.basechrs + o/hdr.basechrs), busize);
}
else
{
append_char(outbuf, *(r_out + hdr.basechrs + o%hdr.basechrs), busize);
append_char(outbuf, *(r_out + hdr.basechrs + o/hdr.basechrs), busize);
}
}
}
return (OK);
}
syntax highlighted by Code2HTML, v. 0.9.1