@ -157,6 +157,35 @@ kaz::operator >> (istream &in, AttachMode &attachMode) {
return in ;
}
// ================================================================================
const string
kaz : : headerTypeLabels [ ] = {
" Same " , " Multi " , " MainPlain " , " AttachHtml "
} ;
const map < string , HeaderType >
kaz : : headerTypeMap = boost : : assign : : map_list_of
( " same " , SAME )
( " multi " , MULTI )
( " mainplain " , MAIN_PLAIN )
( " attachhtml " , ATTACH_HTML )
;
ostream &
kaz : : operator < < ( ostream & out , const HeaderType & headerType ) {
//BOOST_ASSERT (treeType >= MIN && treeType <= ALPHA);
return out < < headerTypeLabels [ headerType ] ;
}
istream &
kaz : : operator > > ( istream & in , HeaderType & headerType ) {
string token ;
in > > token ;
auto pos = headerTypeMap . find ( boost : : algorithm : : to_lower_copy ( token ) ) ;
if ( pos = = headerTypeMap . end ( ) )
in . setstate ( ios_base : : failbit ) ;
else
headerType = pos - > second ;
return in ;
}
// ================================================================================
void
MainAttachment : : copy ( ifstream & mbox , ofstream & outbox , const streamoff & begin , const streamoff & end ) {
@ -420,6 +449,7 @@ MainAttachment::extractPreviousKAZ (ifstream &mbox) {
void
MainAttachment : : removePreviousArchive ( ) {
DEF_LOG ( " MainAttachment::removePreviousArchive " , " " ) ;
vector < string > toRemove ;
for ( map < string , string > : : const_iterator it = previousLinks . begin ( ) ; it ! = previousLinks . end ( ) ; + + it ) {
const string key ( it - > first ) ;
@ -430,6 +460,41 @@ MainAttachment::removePreviousArchive () {
previousLinks . erase ( old ) ;
}
// ================================================================================
void MainAttachment : : rewriteHeaders ( ifstream & mbox , ofstream & outbox , const HeaderType & headerType ) {
DEF_LOG ( " MainAttachment::rewriteHeaders " , " headerType: " < < headerType ) ;
if ( SAME = = headerType ) {
copy ( mbox , outbox , 0 , contentPos ) ;
return ;
}
string mime ( getMime ( mbox ) ) ;
string : : size_type startPos = ( 0 ) ;
for ( string token : { string ( " content-transfer-encoding " ) , Attachment : : contentTypeToken } ) {
startPos = caseInsensitiveFind ( mime , token ) ;
for ( string : : size_type stopPos ( startPos ) ;
( stopPos = mime . find ( " \n " , stopPos ) ) ! = string : : npos ;
) {
if ( string ( " \t " ) . find ( mime [ stopPos + 1 ] ) = = string : : npos ) {
mime . erase ( startPos , stopPos - startPos ) ;
break ;
}
}
}
string contentType ( KAZ_EMPTY_TEXT_PLAIN ) ;
switch ( headerType ) {
case SAME : /* no way */ ;
case MAIN_PLAIN : contentType = KAZ_EMPTY_TEXT_PLAIN ; break ;
case ATTACH_HTML : contentType = KAZ_ATTACHMENT_TEXT_HTML ; break ;
case MULTI :
boundary = " __KAZ__ " + boundaryGen ( 40 ) ;
contentType = " Content-Type: multipart/mixed; boundary= \" " + boundary + " \" " ;
boundary = " -- " + boundary + " -- " ;
boundaryMiddleSize = boundary . length ( ) - 2 ;
}
mime . insert ( startPos , contentType ) ;
outbox < < mime < < flush ;
}
// ================================================================================
MainAttachment : : MainAttachment ( ifstream & mbox )
: Attachment ( mbox , initTmpLevel ( ) , 0 , initTmpPos ( ) ) ,
@ -566,6 +631,15 @@ MainAttachment::extract (ifstream &mbox, const SizeArg &minSize) const {
}
// ================================================================================
/*!
Régle à appliquer dans le cas où Kaz ajoute son cartouche et que le corps principale n ' est pas multipart :
< table >
< tr > < th > src < / th > < th > FOOTER < / th > < th > BOTH < / th > < th > ATTCH < / th > < / tr >
< tr > < th > text / plain < / th > < td > OK < / td > < td > mute multi < / td > < td > mute multi < / td > < / tr >
< tr > < th > empty mail < / th > < td > mute plain < / td > < td > mute multi < / td > < td > mute html < / td > < / tr >
< / table >
*/
void
MainAttachment : : substitute ( ifstream & mbox , ofstream & outbox , const SizeArg & minSize , AttachMode attachMode ) {
DEF_LOG ( " MainAttachment::substitute " , " minSize: " < < minSize < < " AttachMode: " < < attachMode ) ;
@ -600,53 +674,55 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min
string plainDisclaim , htmlDisclaim ;
getDisclaim ( plainDisclaim , htmlDisclaim ) ;
HeaderType headerType ( SAME ) ;
// copy email
if ( ! boundary . size ( ) & & plainDisclaim . size ( ) ) {
if ( attachMode & ATTACHMENT )
attachMode = FOOTER ;
if ( emptyEMail ) {
// only one attachment must be replace
cerr < < " eMailShrinker: force one attachment " < < endl ;
string mime ( getMime ( mbox ) ) ;
string : : size_type startPos = ( 0 ) ;
for ( string token : { string ( " Content-Transfer-Encoding " ) , Attachment : : contentTypeToken } ) {
startPos = caseInsensitiveFind ( mime , " Content-Transfer-Encoding " ) ;
for ( string : : size_type stopPos ( startPos ) ;
( stopPos = mime . find ( " \n " , stopPos ) ) ! = string : : npos ;
) {
if ( string ( " \t " ) . find ( mime [ stopPos + 1 ] ) = = string : : npos ) {
mime . erase ( startPos , stopPos - startPos ) ;
break ;
}
}
}
mime . insert ( startPos , KAZ_EMPTY_TEXT_PLAIN ) ;
if ( ! boundary . size ( ) & & plainDisclaim . size ( ) )
switch ( attachMode ) {
case NONE : LOG_BUG ( true , /* */ , " eMailShrinker: bug M12: nothing to do " ) ; break ;
case FOOTER : headerType = ( emptyEMail ? MAIN_PLAIN : SAME ) ; break ;
case BOTH : headerType = MULTI ; break ;
case ATTACHMENT : headerType = ATTACH_HTML ; break ;
}
rewriteHeaders ( mbox , outbox , headerType ) ;
streamoff curPos = contentPos ;
if ( MAIN_PLAIN = = headerType ) {
LOG ( " Replace old content with plain " ) ;
string content ( plainDisclaim ) ;
base64Encode ( content ) ;
outbox < < mime
< < content < < endl ;
outbox < < content < < endl ;
outbox . flush ( ) ;
outbox . close ( ) ;
return ;
}
}
streamoff curPos = 0 ;
copy ( mbox , outbox , curPos , contentPos ) ;
curPos = contentPos ;
if ( plainDisclaim . size ( ) ) {
if ( emptyEMail & & ( attachMode & FOOTER ) ) {
// check no main text
LOG ( " Force main text " ) ;
cerr < < " eMailShrinker: force footer " < < endl ;
string content ( plainDisclaim ) ;
base64Encode ( content ) ;
outbox < < boundary . substr ( 0 , boundary . length ( ) - 2 ) < < endl
< < KAZ_EMPTY_TEXT_PLAIN < < endl
< < content < < endl ;
outbox . flush ( ) ;
}
if ( ATTACH_HTML = = headerType ) {
LOG ( " Replace old content with html " ) ;
string content ( plainDisclaim ) ;
base64Encode ( content ) ;
outbox < < content < < endl ;
outbox . flush ( ) ;
return ;
}
if ( plainDisclaim . size ( ) & & emptyEMail & & ( attachMode & FOOTER ) ) {
// case : multi
LOG ( " Force main text " ) ;
cerr < < " eMailShrinker: force main text " < < endl ;
string content ( plainDisclaim ) ;
base64Encode ( content ) ;
outbox < < boundary . substr ( 0 , boundary . length ( ) - 2 ) < < endl
< < KAZ_EMPTY_TEXT_PLAIN < < endl
< < content < < endl ;
outbox . flush ( ) ;
}
if ( MULTI = = headerType ) {
LOG ( " New boundary " ) ;
map < string , string > : : const_iterator it ( env . find ( contentTypeToken ) ) ;
LOG_BUG ( it = = env . end ( ) , /* */ , " eMailShrinker: bug M13: no content-type " ) ;
outbox < < boundary . substr ( 0 , boundary . length ( ) - 2 ) < < endl
< < Attachment : : contentTypeToken < < " : " < < it - > second < < endl ;
}
for ( Attachment * attachP : allMarkedPtrs ) {
copy ( mbox , outbox , curPos , attachP - > beginInParent ) ;
LOG_BUG ( attachP - > toUpdate & & attachP - > toExtract , /**/ , " eMailShrinker: bug M5: update and extract. pos: " < < attachP - > beginPos ) ;
@ -727,12 +803,15 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min
outbox . flush ( ) ;
curPos = attachP - > endPos ;
}
if ( plainDisclaim . size ( ) & & ( attachMode & ATTACHMENT ) ) {
LOG ( " Add kaz attachment " ) ;
cerr < < " eMailShrinker: force attachment " < < endl ;
streamoff lastPos = subAttachements . back ( ) . endPos ;
copy ( mbox , outbox , curPos , lastPos ) ;
curPos = lastPos ;
if ( subAttachements . size ( ) ) {
streamoff lastPos = subAttachements . back ( ) . endPos ;
copy ( mbox , outbox , curPos , lastPos ) ;
curPos = lastPos ;
}
string content ( KAZ_HTML_CONTENT + htmlDisclaim + BODY_END + HTML_END ) ;
base64Encode ( content ) ;
@ -742,7 +821,8 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min
outbox . flush ( ) ;
}
copy ( mbox , outbox , curPos , endPos ) ;
//outbox << endl;
if ( MULTI = = headerType )
outbox < < boundary . substr ( 0 , boundary . length ( ) ) < < endl ;
outbox . close ( ) ;
}