Charset, InternetRFCBody changes; Quotecheck fixed

This commit is contained in:
Alexander S. Aganichev 2001-05-26 20:29:38 +00:00
parent d8ca130bd0
commit 6a5125b7e5
11 changed files with 192 additions and 159 deletions

View File

@ -12,6 +12,12 @@ ______________________________________________________________________
Notes for GoldED+ 1.1.5, /snapshot/
______________________________________________________________________
! A lot of improvements in charset handling added. QP postfix now
could be used with any charset, not only with LATIN1. Completely
untested!
! Changed InternetRFCBody parsing algorithm. Should be quicker.
! A lot of manipulations with Internet addressing was done.
! GoldED+ now produce Internet addresses in RFC preferable form

View File

@ -172,15 +172,11 @@ char* mime_header_encode(char* dest, const char* source, GMsg* msg) {
if(msg->charset) {
bp = stpcpy(bp, "=?");
if(strneql(msg->charset, "latin", 5)) {
static const char *isono[] = { "15", "1", "2", "3", "4", "9", "10", "13", "14", "15" };
int chsno = atoi(msg->charset+5);
if(chsno < 0) chsno = -chsno; // support for both latin-1 and latin1
chsno = chsno > sizeof(isono)/sizeof(const char *) ? 0 : chsno;
bp = strxmerge(bp, 12, "iso-8859-", isono[chsno]);
bp = Latin2ISO(bp, msg->charset);
}
else {
char *pbp = bp;
bp = stpcpy(bp, strlword(msg->charset));
bp = stpcpy(bp, IsQuotedPrintable(msg->charset) ? ExtractPlainCharset(msg->charset) : strlword(msg->charset));
strlwr(pbp);
}
bp = stpcpy(bp, "?Q?");
@ -495,17 +491,27 @@ void DoKludges(int mode, GMsg* msg, bool attronly) {
line->kludge = GKLUD_RFC;
}
if(striinc("LATIN-1", msg->charset) or striinc("LATIN1QP", msg->charset) or striinc("ASCII", msg->charset)) {
sprintf(buf, "%sMIME-Version: 1.0", rfc);
line = AddKludge(line, buf);
line->kludge = GKLUD_RFC;
sprintf(buf, "%sContent-Type: text/plain; charset=%s", rfc, striinc("ASCII", msg->charset) ? "us-ascii" : "iso-8859-1");
char encoding[100];
bool isusascii = striinc("ASCII", msg->charset);
bool isqp = not isusascii and IsQuotedPrintable(msg->charset);
if(strneql(msg->charset, "latin", 5))
Latin2ISO(encoding, msg->charset);
else if(isusascii)
strcpy(encoding, "us-ascii");
else if(isqp)
strcpy(encoding, ExtractPlainCharset(msg->charset));
else
strcpy(encoding, msg->charset);
strlwr(encoding);
sprintf(buf, "%sContent-Type: text/plain; charset=%s", rfc, strlword(encoding));
line = AddKludge(line, buf);
line->kludge = GKLUD_RFC;
sprintf(buf, "%sContent-Transfer-Encoding: %s", rfc, striinc("LATIN1QP", msg->charset) ? "quoted-printable" : striinc("ASCII", msg->charset) ? "7bit" : "8bit");
sprintf(buf, "%sContent-Transfer-Encoding: %s", rfc, isqp ? "quoted-printable" : isusascii ? "7bit" : "8bit");
line = AddKludge(line, buf);
line->kludge = GKLUD_RFC;
}
if(*to_buf and AA->isnewsgroup()) {
line = AddKludge(line, to_buf);

View File

@ -469,7 +469,7 @@ void IEclass::GoEOL() {
// Move cursor to the last char on the line
col = currline->txt.length();
if((currline->txt[col-1] == '\n') or ((col == (maxcol + 1)) and (currline->txt[col-1] == ' ')))
if((currline->txt[col-1] == '\n') or ((col != mincol) and (currline->txt[col-1] == ' ')))
--col;
// String must not be longer than the window width
@ -564,7 +564,6 @@ void IEclass::GoLeft() {
if(currline->prev) {
GoUp();
GoEOL();
// if((col != mincol) and ((currline->txt[col] == '\n') or not ((col == (maxcol + 1)) and (currline->txt[col-1] == ' '))))
if((col != mincol) and (currline->txt.c_str()[col] == NUL))
col--;
}

View File

@ -377,7 +377,7 @@ char* mime_header_decode(char* decoded, const char* encoded, char *charset) {
while(*eptr) {
if(*eptr == '=') {
const char* mptr = mime_crack_encoded_word(eptr, cbuf, ebuf, tbuf);
if(mptr) { // and strieql(cbuf, "ISO-8859-1")) {
if(mptr) {
if(charset) {
strxcpy(charset, cbuf, 100);
charset = NULL;
@ -1881,9 +1881,8 @@ void MakeLineIndex(GMsg* msg, int margin, bool header_recode) {
bool reflow = false, quoteflag = false;
bool getvalue = not msg->attr.tou();
bool quotewraphard = AA->Quotewraphard();
bool qpencoded = getvalue and (strieql(AA->Xlatimport(), "LATIN1QP") ? true : false);
bool qpencoded = getvalue and IsQuotedPrintable(AA->Xlatimport());
bool gotmime = false;
bool firstemptyline = false;
bool gotmultipart = false;
bool inheader = false;
char boundary[100];
@ -2045,8 +2044,8 @@ void MakeLineIndex(GMsg* msg, int margin, bool header_recode) {
}
else if(kludgetype == FSC_CHARSET) {
*chsbuf = NUL;
qpencoded = striinc("LATIN1QP", ptr) ? true : false;
strxcpy(chsbuf, qpencoded ? "LATIN-1" : ptr, sizeof(chsbuf));
qpencoded = IsQuotedPrintable(ptr);
strxcpy(chsbuf, qpencoded ? ExtractPlainCharset(ptr) : ptr, sizeof(chsbuf));
// Workaround for buggy mailreaders which stores '_' in charset name
strchg(chsbuf,'_',' ');
chslev = LoadCharset(chsbuf, CFG->xlatlocalset);
@ -2068,6 +2067,8 @@ void MakeLineIndex(GMsg* msg, int margin, bool header_recode) {
}
else
strxcpy(chsbuf, strrword(mime_charset+8), sizeof(chsbuf));
if(striinc("8859", chsbuf))
ISO2Latin(chsbuf, chsbuf);
chslev = LoadCharset(chsbuf, CFG->xlatlocalset);
if(chslev) {
level = msg->charsetlevel = chslev;
@ -2077,7 +2078,7 @@ void MakeLineIndex(GMsg* msg, int margin, bool header_recode) {
strcpy(msg->charset, chsbuf);
gotmime = true;
}
if(check_multipart(ptr, keptr, boundary)) {
else if(check_multipart(ptr, keptr, boundary)) {
gotmultipart = true;
gotmime = true;
}
@ -2086,20 +2087,20 @@ void MakeLineIndex(GMsg* msg, int margin, bool header_recode) {
if(striinc("quoted-printable", ptr)) {
qpencoded = true;
msg->charsetencoding |= GCHENC_QP;
// ASA: What the stuff below for? I never saw such messages...
if(striinc("LATIN-1", msg->charset)) {
strcpy(chsbuf, "LATIN1QP");
chslev = LoadCharset("LATIN-1", CFG->xlatlocalset);
strcpy(chsbuf, MakeQuotedPrintable(msg->charset));
chslev = LoadCharset(msg->charset, CFG->xlatlocalset);
if(chslev) {
level = msg->charsetlevel = chslev;
strcpy(msg->charset, chsbuf);
}
}
}
}
else if(kludgetype == RFC_X_CHARSET) {
if(not gotmime) {
strcpy(chsbuf, (striinc("8859-1", ptr) or striinc("Latin1", ptr)) ? "LATIN-1" : ptr);
if(striinc("8859", ptr))
ISO2Latin(chsbuf, ptr);
else
strxcpy(chsbuf, ptr, sizeof(chsbuf));
chslev = LoadCharset(chsbuf, CFG->xlatlocalset);
if(chslev) {
level = msg->charsetlevel = chslev;
@ -2434,75 +2435,33 @@ void MakeLineIndex(GMsg* msg, int margin, bool header_recode) {
else
line->color = C_READW;
prevline = line;
line = new Line();
throw_xnew(line);
line->prev = prevline;
ptr = spanfeeds(ptr);
}
throw_release(linetmp);
throw_xdelete(line);
// Scan msg body top for RFC headerlines
if(line->txt.empty() and not firstemptyline) {
firstemptyline = true;
if(AA->Internetrfcbody()) {
Line* linep = FirstLine(line);
if(msg->lin) {
Line* linep = msg->lin;
int headerlines = 0;
while(linep) {
if(not linep->txt.empty()) {
const char* tptr = linep->txt.c_str();
if(*tptr) {
if(*tptr != CTRL_A) {
int kludgetype = ScanLine(msg, linep, tptr, getvalue, MASK_RFC);
if(kludgetype) {
tptr = strchr(tptr, ' ');
if(tptr) {
tptr = strskip_wht(tptr);
if(kludgetype == HEADERLINE) {
linep->type |= GLINE_HIDD;
}
else if(getvalue) {
if(kludgetype == RFC_CONTENT_TYPE) {
if(striinc("iso-8859-1", tptr)) {
strcpy(chsbuf, "LATIN-1");
chslev = LoadCharset(chsbuf, CFG->xlatlocalset);
if(chslev) {
level = msg->charsetlevel = chslev;
strcpy(msg->charset, chsbuf);
}
gotmime = true;
}
else {
const char* keptr = linep->next ? linep->next->txt.c_str() : " ";
if(check_multipart(ptr, keptr, boundary)) {
gotmultipart = true;
gotmime = true;
}
}
}
else if(kludgetype == RFC_CONTENT_TRANSFER_ENCODING) {
if(striinc("quoted-printable", tptr)) {
qpencoded = true;
msg->charsetencoding |= GCHENC_QP;
if(striinc("LATIN-1", msg->charset)) {
strcpy(chsbuf, "LATIN1QP");
chslev = LoadCharset("LATIN-1", CFG->xlatlocalset);
if(chslev) {
level = msg->charsetlevel = chslev;
strcpy(msg->charset, chsbuf);
}
}
}
}
else if(kludgetype == RFC_X_CHARSET) {
if(not gotmime) {
strcpy(chsbuf, (striinc("8859-1", tptr) or striinc("Latin1", tptr)) ? "LATIN-1" : CFG->xlatlocalset);
chslev = LoadCharset(chsbuf, CFG->xlatlocalset);
if(chslev) {
level = msg->charsetlevel = chslev;
strcpy(msg->charset, chsbuf);
}
}
}
else if(kludgetype == RFC_X_CHAR_ESC) {
if(not gotmime)
msg->charsetencoding |= GCHENC_MNE;
}
}
}
headerlines++;
if(linep->type == GLINE_HIDD)
if(linep->type & GLINE_HIDD)
linep->color = C_READKH;
else
linep->color = C_READK;
@ -2531,8 +2490,13 @@ void MakeLineIndex(GMsg* msg, int margin, bool header_recode) {
break;
}
if(linep->type & GLINE_WRAP) {
while(linep and (linep->type & GLINE_WRAP))
while(linep and (linep->type & GLINE_WRAP)) {
linep = linep->next;
if(linep) {
linep->type |= linep->prev->type & (GLINE_KLUD|GLINE_HIDD);
linep->color = linep->prev->color;
}
}
}
if(linep)
linep = linep->next;
@ -2540,17 +2504,6 @@ void MakeLineIndex(GMsg* msg, int margin, bool header_recode) {
}
}
prevline = line;
line = new Line();
throw_xnew(line);
line->prev = prevline;
ptr = spanfeeds(ptr);
}
throw_release(linetmp);
throw_xdelete(line);
// Scan for kludge-, tear- and originlines
ScanKludges(msg, getvalue);
@ -2699,6 +2652,70 @@ void MsgLineReIndex(GMsg* msg, int viewhidden, int viewkludge, int viewquote) {
}
// ------------------------------------------------------------------
bool IsQuotedPrintable(const char *encoding) {
if(striinc("LATIN1QP", encoding))
return true;
else {
const char *lencoding = strlword(encoding);
int len = strlen(lencoding);
if((len > 2) and strnieql("QP", lencoding+len-2, 2))
return true;
}
return false;
}
// ------------------------------------------------------------------
static char qpencodingbuf[100];
char *MakeQuotedPrintable(const char *encoding) {
strxmerge(qpencodingbuf, sizeof(qpencodingbuf), strlword(encoding), "QP", NULL);
return qpencodingbuf;
}
// ------------------------------------------------------------------
char *ExtractPlainCharset(const char *encoding) {
strxcpy(qpencodingbuf, strlword(encoding), sizeof(qpencodingbuf));
int len = strlen(qpencodingbuf);
if(len > 2)
qpencodingbuf[len-2] = NUL;
return qpencodingbuf;
}
// ------------------------------------------------------------------
char *Latin2ISO(char *iso_encoding, const char *latin_encoding) {
static const char *isono[] = { "15", "1", "2", "3", "4", "9", "10", "13", "14", "15" };
int chsno = atoi(latin_encoding+5);
if(chsno < 0) chsno = -chsno; // support for both latin-1 and latin1
chsno = chsno > sizeof(isono)/sizeof(const char *) ? 0 : chsno;
return strxmerge(iso_encoding, 12, "iso-8859-", isono[chsno], NULL);
}
// ------------------------------------------------------------------
char *ISO2Latin(char *latin_encoding, const char *iso_encoding) {
static const char *latinno[] = { NULL, "1", "2", "3", "4", NULL, NULL, NULL, NULL, "5", "6", NULL, NULL, "7", "8", "9" };
int chsno = atoi(iso_encoding+9);
chsno = chsno > sizeof(latinno)/sizeof(const char *) ? 0 : chsno;
if(latinno[chsno] == NULL)
return strxmerge(latin_encoding, 12, iso_encoding, NULL);
else
return strxmerge(latin_encoding, 8, "latin-", latinno[chsno], NULL);
}
// ------------------------------------------------------------------
int LoadCharset(const char* imp, const char* exp, int query) {

View File

@ -163,6 +163,11 @@ void Initialize(int argc, char* argv[]);
// ------------------------------------------------------------------
// GELINE prototypes
char *Latin2ISO(char *iso_encoding, const char *latin_encoding);
char *ISO2Latin(char *latin_encoding, const char *iso_encoding);
char *MakeQuotedPrintable(const char *encoding);
char *ExtractPlainCharset(const char *encoding);
bool IsQuotedPrintable(const char *encoding);
int LoadCharset(const char* imp, const char* exp, int query = 0);
Line* AddKludge(Line* line, char* buf, int where=DIR_BELOW);
Line* AddLineFast(Line* line, char* text);

View File

@ -404,13 +404,12 @@ int ExportQwkMsg(GMsg* msg, gfile& fp, int confno, int& pktmsgno) {
if(not striinc("MNEMONIC", CharTable->exp))
LoadCharset(CFG->xlatlocalset, "MNEMONIC");
}
else if(striinc("LATIN1QP", msg->charset)) {
if(not striinc("LATIN1QP", CharTable->exp))
LoadCharset(CFG->xlatlocalset, "LATIN1QP");
// ASA: Do we need it at all?
else if(IsQuotedPrintable(msg->charset)) {
LoadCharset(CFG->xlatlocalset, ExtractPlainCharset(msg->charset));
}
else if(striinc("LATIN-1", msg->charset)) {
if(not striinc("LATIN-1", CharTable->exp))
LoadCharset(CFG->xlatlocalset, "LATIN-1");
else {
LoadCharset(CFG->xlatlocalset, msg->charset);
}
char qwkterm = '\xE3';

View File

@ -626,13 +626,11 @@ int ExportSoupMsg(GMsg* msg, char* msgfile, gfile& fp, int ismail) {
if(not CharTable or not striinc("MNEMONIC", CharTable->exp))
LoadCharset(CFG->xlatlocalset, "MNEMONIC");
}
else if(striinc("LATIN1QP", msg->charset)) {
else if(IsQuotedPrintable(msg->charset)) {
qp = true;
if(not CharTable or not striinc("LATIN1QP", CharTable->exp))
LoadCharset(CFG->xlatlocalset, "LATIN1QP");
LoadCharset(CFG->xlatlocalset, ExtractPlainCharset(msg->charset));
}
else {
if(not CharTable or not striinc(msg->charset, CharTable->exp))
LoadCharset(CFG->xlatlocalset, msg->charset);
}

View File

@ -832,8 +832,11 @@ bool guserbase::lookup_addressbook(GMsg* msg, char* name, char* aka, bool browse
else
strcpy(name, entry.name);
}
else
else {
strcpy(name, entry.name);
if(AA->isinternet())
strcpy(msg->realto, entry.name);
}
if(not strblank(entry.pseudo))
strcpy(msg->pseudoto, entry.pseudo);

View File

@ -423,7 +423,7 @@ int GetQuotestr(const char* ptr, char* qbuf, uint* qlen) {
if((*lp != NUL) and (isspace(*lp) or issoftcr(*lp)))
x++;
for(*qlen = n = 0; (n < x) and ((*qlen) < MAXQUOTELEN); n++, ptr++) {
for(*qlen = n = 0; (n < x) and ((*qlen) < MAXQUOTELEN-1); n++, ptr++) {
if((*ptr != LF) and not issoftcr(*ptr)) {
*qbuf++ = *ptr;
(*qlen)++;

View File

@ -104,9 +104,9 @@ Line* JamArea::make_dump_msg(Line*& lin, gmsg* __msg, char* lng_head) {
AddLineF(line, "ReplyTo : %lu", _hdr->replyto);
AddLineF(line, "Reply1st : %lu", _hdr->reply1st);
AddLineF(line, "ReplyNext : %lu", _hdr->replynext);
AddLineF(line, "DateWritten : %s (%08lXh)", TimeToStr(buf, _hdr->datewritten), _hdr->datewritten);
AddLineF(line, "DateReceived : %s (%08lXh)", TimeToStr(buf, _hdr->datereceived), _hdr->datereceived);
AddLineF(line, "DateProcessed : %s (%08lXh)", TimeToStr(buf, _hdr->dateprocessed), _hdr->dateprocessed);
AddLineF(line, "DateWritten : %s (%08lXh)", TimeToStr(buf, _hdr->datewritten), (long)_hdr->datewritten);
AddLineF(line, "DateReceived : %s (%08lXh)", TimeToStr(buf, _hdr->datereceived), (long)_hdr->datereceived);
AddLineF(line, "DateProcessed : %s (%08lXh)", TimeToStr(buf, _hdr->dateprocessed), (long)_hdr->dateprocessed);
AddLineF(line, "MessageNumber : %lu", _hdr->messagenumber);
AddLineF(line, "Attribute : %08lXh (%sb)", _hdr->attribute, ltob(buf, _hdr->attribute, 0));
AddLineF(line, "Attribute2 : %08lXh (%sb)", _hdr->attribute2, ltob(buf, _hdr->attribute2, 0));
@ -130,7 +130,7 @@ Line* JamArea::make_dump_msg(Line*& lin, gmsg* __msg, char* lng_head) {
line = AddLine(line, "");
AddLineF(line, "Base Header:");
line = AddLine(line, "");
AddLineF(line, "DateCreated : %s (%08lXh)", TimeToStr(buf, _base->datecreated), _base->datecreated);
AddLineF(line, "DateCreated : %s (%08lXh)", TimeToStr(buf, _base->datecreated), (long)_base->datecreated);
AddLineF(line, "ModCounter : %lu", _base->modcounter);
AddLineF(line, "ActiveMsgs : %lu", _base->activemsgs);
AddLineF(line, "PasswordCRC : %08lXh", _base->passwordcrc);
@ -155,7 +155,7 @@ Line* JamArea::make_dump_msg(Line*& lin, gmsg* __msg, char* lng_head) {
_subfieldpos += sizeof(JamSubFieldHdr);
uint _datlen = (uint)_subfieldptr->datlen;
if(_subfieldpos > _hdr->subfieldlen) {
AddLineF(line, "Error: SubfieldHdr at pos %u exceeds SubfieldLen (%lu)!", _subfieldpos-sizeof(JamSubFieldHdr), _hdr->subfieldlen);
AddLineF(line, "Error: SubfieldHdr at pos %lu exceeds SubfieldLen (%lu)!", (unsigned long)(_subfieldpos-sizeof(JamSubFieldHdr)), _hdr->subfieldlen);
break;
}
if((_subfieldpos + _datlen) > _hdr->subfieldlen) {

View File

@ -84,7 +84,7 @@ Line* XbbsArea::make_dump_msg(Line*& lin, gmsg* msg, char* lng_head) {
AddLineF(line, "InDate : %u-%u-%u", hdr.indate[0]+1989, hdr.indate[1], hdr.indate[2]);
AddLineF(line, "MsgNum : %lu", hdr.msgnum);
AddLineF(line, "TimesRead : %lu", hdr.timesread);
AddLineF(line, "TimeRecv : %s (%08lXh)", TimeToStr(buf, hdr.timerecv), hdr.timerecv);
AddLineF(line, "TimeRecv : %s (%08lXh)", TimeToStr(buf, hdr.timerecv), (long)hdr.timerecv);
AddLineF(line, "Length : %lu", hdr.length);
AddLineF(line, "Start : %lu", hdr.start);
AddLineF(line, "Extra1,2,3 : %lu, %lu, %lu", hdr.extra1, hdr.extra2, hdr.extra3);