summaryrefslogtreecommitdiff
path: root/plugins/YAMN/src/mails/mime.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/YAMN/src/mails/mime.cpp')
-rw-r--r--plugins/YAMN/src/mails/mime.cpp718
1 files changed, 0 insertions, 718 deletions
diff --git a/plugins/YAMN/src/mails/mime.cpp b/plugins/YAMN/src/mails/mime.cpp
deleted file mode 100644
index 076e139c40..0000000000
--- a/plugins/YAMN/src/mails/mime.cpp
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
- * This code implements retrieving info from MIME header
- *
- * (c) majvan 2002-2004
- */
-
-#include "../stdafx.h"
-
-//--------------------------------------------------------------------------------------------------
-
-//Copies one string to another
-// srcstart- source string
-// srcend- address to the end of source string
-// dest- pointer that stores new allocated string that contains copy of source string
-// mode- MIME_PLAIN or MIME_MAIL (MIME_MAIL deletes '"' characters (or '<' and '>') if they are at start and end of source string
-void CopyToHeader(char *srcstart,char *srcend,char **dest,int mode);
-
-//Extracts email address (finds nick name and mail and then stores them to strings)
-// finder- source string
-// storeto- pointer that receives address of mail string
-// storetonick- pointer that receives address of nickname
-void ExtractAddressFromLine(char *finder,char **storeto,char **storetonick);
-
-//Extracts simple text from string
-// finder- source string
-// storeto- pointer that receives address of string
-void ExtractStringFromLine(char *finder,char **storeto);
-
-//Extracts some item from content-type string
-//Example: ContentType string: "TEXT/PLAIN; charset=US-ASCII", item:"charset=", returns: "US-ASCII"
-// ContetType- content-type string
-// value- string item
-// returns extracted string (or NULL when not found)
-char *ExtractFromContentType(char *ContentType,char *value);
-
-//Extracts info from header text into header members
-//Note that this function as well as struct CShortHeadwer can be always changed, because there are many items to extract
-//(e.g. the X-Priority and Importance and so on)
-// items- translated header (see TranslateHeaderFcn)
-// head- header to be filled with values extracted from items
-void ExtractShortHeader(struct CMimeItem *items,struct CShortHeader *head);
-
-//Extracts header to mail using ExtractShortHeader fcn.
-// items- translated header (see TranslateHeaderFcn)
-// CP- codepage used when no default found
-// head- header to be filled with values extracted from items, in unicode (wide char)
-void ExtractHeader(struct CMimeItem *items,int &CP,struct CHeader *head);
-
-//Deletes items in CShortHeader structure
-// head- structure whose items are deleted
-void DeleteShortHeaderContent(struct CShortHeader *head);
-
-//Deletes list of YAMN_MIMENAMES structures
-// Names- pointer to first item of list
-void DeleteNames(PYAMN_MIMENAMES Names);
-
-//Deletes list of YAMN_MIMESHORTNAMES structures
-// Names- pointer to first item of list
-void DeleteShortNames(PYAMN_MIMESHORTNAMES Names);
-
-//Makes a string lowercase
-// string- string to be lowercased
-void inline ToLower(char *string);
-
-//--------------------------------------------------------------------------------------------------
-//--------------------------------------------------------------------------------------------------
-
-void CopyToHeader(char *srcstart,char *srcend,char **dest,int mode)
-{
- char *dst;
-
- if (dest==nullptr)
- return;
- if (srcstart>=srcend)
- return;
-
- if ((mode==MIME_MAIL) && (((*srcstart=='"') && (*(srcend-1)=='"')) || ((*srcstart=='<') && (*(srcend-1)=='>'))))
- {
- srcstart++;
- srcend--;
- }
-
- if (srcstart>=srcend)
- return;
-
- if (nullptr != *dest)
- delete[] *dest;
- if (nullptr==(*dest=new char[srcend-srcstart+1]))
- return;
-
- dst=*dest;
-
- for (;srcstart<srcend;dst++,srcstart++)
- {
- if (ENDLINE(srcstart))
- {
- while(ENDLINE(srcstart) || WS(srcstart)) srcstart++;
- *dst=' ';
- srcstart--; //because at the end of "for loop" we increment srcstart
- }
- else
- *dst=*srcstart;
- }
- *dst=0;
-}
-
-void ExtractAddressFromLine(char *finder,char **storeto,char **storetonick)
-{
- if (finder==nullptr)
- {
- *storeto=*storetonick=nullptr;
- return;
- }
- while(WS(finder)) finder++;
- if ((*finder) != '<')
- {
- char *finderend=finder+1;
- do
- {
- if (ENDLINEWS(finderend)) //after endline information continues
- finderend+=2;
- while(!ENDLINE(finderend) && !EOS(finderend)) finderend++; //seek to the end of line or to the end of string
- }while(ENDLINEWS(finderend));
- finderend--;
- while(WS(finderend) || ENDLINE(finderend)) finderend--; //find the end of text, no whitespace
- if (*finderend != '>') //not '>' at the end of line
- CopyToHeader(finder,finderend+1,storeto,MIME_MAIL);
- else //at the end of line, there's '>'
- {
- char *finder2=finderend;
- while((*finder2 != '<') && (finder2>finder)) finder2--; //go to matching '<' or to the start
- CopyToHeader(finder2,finderend+1,storeto,MIME_MAIL);
- if (*finder2=='<') //if we found '<', the rest copy as from nick
- {
- finder2--;
- while(WS(finder2) || ENDLINE(finder2)) finder2--; //parse whitespace
- CopyToHeader(finder,finder2+1,storetonick,MIME_MAIL); //and store nickname
- }
- }
- }
- else
- {
- char *finderend=finder+1;
- do
- {
- if (ENDLINEWS(finderend)) //after endline information continues
- finderend+=2;
- while(!ENDLINE(finderend) && (*finderend != '>') && !EOS(finderend)) finderend++; //seek to the matching < or to the end of line or to the end of string
- }while(ENDLINEWS(finderend));
- CopyToHeader(finder,finderend+1,storeto,MIME_MAIL); //go to first '>' or to the end and copy
- finder=finderend+1;
- while(WS(finder)) finder++; //parse whitespace
- if (!ENDLINE(finder) && !EOS(finder)) //if there are chars yet, it's nick
- {
- finderend=finder+1;
- while(!ENDLINE(finderend) && !EOS(finderend)) finderend++; //seek to the end of line or to the end of string
- finderend--;
- while(WS(finderend)) finderend--; //find the end of line, no whitespace
- CopyToHeader(finder,finderend+1,storetonick,MIME_MAIL);
- }
- }
-}
-
-void ExtractStringFromLine(char *finder,char **storeto)
-{
- if (finder==nullptr)
- {
- *storeto=nullptr;
- return;
- }
- while(WS(finder)) finder++;
- char *finderend=finder;
-
- do
- {
- if (ENDLINEWS(finderend)) finderend++; //after endline information continues
- while(!ENDLINE(finderend) && !EOS(finderend)) finderend++;
- }while(ENDLINEWS(finderend));
- finderend--;
- while(WS(finderend)) finderend--; //find the end of line, no whitespace
- CopyToHeader(finder,finderend+1,storeto,MIME_PLAIN);
-}
-
-char *ExtractFromContentType(char *ContentType,char *value)
-{
- char *lowered = _strdup(ContentType);
- ToLower(lowered);
- char *finder=strstr(lowered,value);
- if (finder==nullptr) {
- free (lowered);
- return nullptr;
- }
- finder = finder-lowered+ContentType;
- free (lowered);
-
- char *temp,*copier;
- char *CopiedString;
-
- temp=finder-1;
- while((temp>ContentType) && WS(temp)) temp--; //now we have to find, if the word "Charset=" is located after ';' like "; Charset="
- if (*temp != ';' && !ENDLINE(temp) && temp != ContentType)
- return nullptr;
- finder=finder+mir_strlen(value); //jump over value string
-
- while(WS(finder)) finder++; //jump over whitespaces
- temp=finder;
- while(*temp != 0 && *temp != ';') temp++; //jump to the end of setting (to the next ;)
- temp--;
- while(WS(temp)) temp--; //remove whitespaces from the end
- if (*finder=='\"') { //remove heading and tailing quotes
- finder++;
- if (*temp=='\"') temp--;
- }
- if (nullptr==(CopiedString=new char[++temp-finder+1]))
- return nullptr;
- for (copier=CopiedString;finder != temp;*copier++=*finder++); //copy string
- *copier=0; //and end it with zero character
-
- return CopiedString;
-}
-
-void ExtractShortHeader(struct CMimeItem *items,struct CShortHeader *head)
-{
- for (;items != nullptr;items=items->Next)
- {
- //at the start of line
- //MessageBox(NULL,items->value,items->name,0);
- if (0==_strnicmp(items->name,"From",4))
- {
- if (items->value==nullptr)
- continue;
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"<Extracting from>");
- #endif
- ExtractAddressFromLine(items->value,&head->From,&head->FromNick);
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"</Extracting>\n");
- #endif
- }
- else if (0==_strnicmp(items->name,"Return-Path",11))
- {
- if (items->value==nullptr)
- continue;
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"<Extracting return-path>");
- #endif
- ExtractAddressFromLine(items->value,&head->ReturnPath,&head->ReturnPathNick);
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"</Extracting>\n");
- #endif
- }
- else if (0==_strnicmp(items->name,"Subject",7))
- {
- if (items->value==nullptr)
- continue;
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"<Extracting subject>");
- #endif
- ExtractStringFromLine(items->value,&head->Subject);
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"</Extracting>\n");
- #endif
- }
- else if (0==_strnicmp(items->name,"Body",4))
- {
- if (items->value==nullptr)
- continue;
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"<Extracting body>");
- #endif
- ExtractStringFromLine(items->value,&head->Body);
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"</Extracting>\n");
- #endif
- }
- else if (0==_strnicmp(items->name,"Date",4))
- {
- if (items->value==nullptr)
- continue;
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"<Extracting date>");
- #endif
- ExtractStringFromLine(items->value,&head->Date);
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"</Extracting>\n");
- #endif
- }
- else if (0==_strnicmp(items->name,"Content-Type",12))
- {
- if (items->value==nullptr)
- continue;
-
- char *ContentType=nullptr,*CharSetStr;
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"<Extracting Content-Type>");
- #endif
- ExtractStringFromLine(items->value,&ContentType);
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"</Extracting>\n");
- #endif
- ToLower(ContentType);
- if (nullptr != (CharSetStr=ExtractFromContentType(ContentType,"charset=")))
- {
- head->CP=GetCharsetFromString(CharSetStr,mir_strlen(CharSetStr));
- delete[] CharSetStr;
- }
- delete[] ContentType;
- }
- else if (0==_strnicmp(items->name,"Importance",10))
- {
- if (items->value==nullptr)
- continue;
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"<Extracting importance>");
- #endif
- if (head->Priority != -1)
- {
- if (0==strncmp(items->value,"low",3))
- head->Priority=5;
- else if (0==strncmp(items->value,"normal",6))
- head->Priority=3;
- else if (0==strncmp(items->value,"high",4))
- head->Priority=1;
- }
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"</Extracting>\n");
- #endif
- }
- else if (0==_strnicmp(items->name,"X-Priority",10))
- {
- if (items->value==nullptr)
- continue;
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"<X-Priority>");
- #endif
- if ((*items->value>='1') && (*items->value<='5'))
- head->Priority=*items->value-'0';
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"</Extracting>\n");
- #endif
- }
-
- }
-}
-
-void ExtractHeader(struct CMimeItem *items,int &CP,struct CHeader *head)
-{
- struct CShortHeader ShortHeader;
-
- memset(&ShortHeader, 0, sizeof(struct CShortHeader));
- ShortHeader.Priority=ShortHeader.CP=-1;
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"<Extracting header>\n");
- #endif
- ExtractShortHeader(items,&ShortHeader);
-
- head->Priority=ShortHeader.Priority==-1 ? 3 : ShortHeader.Priority;
- CP=ShortHeader.CP==-1 ? CP : ShortHeader.CP;
- #ifdef DEBUG_DECODE
- if (NULL != ShortHeader.From)
- DebugLog(DecodeFile,"<Decoded from>%s</Decoded)\n",ShortHeader.From);
- if (NULL != ShortHeader.FromNick)
- DebugLog(DecodeFile,"<Decoded from-nick>%s</Decoded)\n",ShortHeader.FromNick);
- if (NULL != ShortHeader.ReturnPath)
- DebugLog(DecodeFile,"<Decoded return-path>%s</Decoded)\n",ShortHeader.ReturnPath);
- if (NULL != ShortHeader.ReturnPathNick)
- DebugLog(DecodeFile,"<Decoded return-path nick>%s</Decoded)\n",ShortHeader.ReturnPathNick);
- if (NULL != ShortHeader.Subject)
- DebugLog(DecodeFile,"<Decoded subject>%s</Decoded)\n",ShortHeader.Subject);
- if (NULL != ShortHeader.Date)
- DebugLog(DecodeFile,"<Decoded date>%s</Decoded)\n",ShortHeader.Date);
- DebugLog(DecodeFile,"</Extracting header>\n");
- DebugLog(DecodeFile,"<Convert>\n");
- #endif
-
- ConvertCodedStringToUnicode(ShortHeader.From,&head->From,CP,MIME_PLAIN);
-
- #ifdef DEBUG_DECODE
- if (NULL != head->From)
- DebugLogW(DecodeFile,L"<Converted from>%s</Converted>\n",head->From);
- #endif
- ConvertCodedStringToUnicode(ShortHeader.FromNick,&head->FromNick,CP,MIME_MAIL);
- #ifdef DEBUG_DECODE
- if (NULL != head->FromNick)
- DebugLogW(DecodeFile,L"<Converted from-nick>%s</Converted>\n",head->FromNick);
- #endif
- ConvertCodedStringToUnicode(ShortHeader.ReturnPath,&head->ReturnPath,CP,MIME_PLAIN);
- #ifdef DEBUG_DECODE
- if (NULL != head->ReturnPath)
- DebugLogW(DecodeFile,L"<Converted return-path>%s</Converted>\n",head->ReturnPath);
- #endif
- ConvertCodedStringToUnicode(ShortHeader.ReturnPathNick,&head->ReturnPathNick,CP,MIME_MAIL);
- #ifdef DEBUG_DECODE
- if (NULL != head->ReturnPathNick)
- DebugLogW(DecodeFile,L"<Converted return-path nick>%s</Converted>\n",head->ReturnPathNick);
- #endif
- ConvertCodedStringToUnicode(ShortHeader.Subject,&head->Subject,CP,MIME_PLAIN);
- #ifdef DEBUG_DECODE
- if (NULL != head->Subject)
- DebugLogW(DecodeFile,L"<Converted subject>%s</Converted>\n",head->Subject);
- #endif
- ConvertCodedStringToUnicode(ShortHeader.Date,&head->Date,CP,MIME_PLAIN);
- #ifdef DEBUG_DECODE
- if (NULL != head->Date)
- DebugLogW(DecodeFile,L"<Converted date>%s</Converted>\n",head->Date);
- #endif
-
- ConvertCodedStringToUnicode(ShortHeader.Body,&head->Body,CP,MIME_PLAIN);
- #ifdef DEBUG_DECODE
- if (NULL != head->Body)
- DebugLogW(DecodeFile,L"<Converted Body>%s</Converted>\n",head->Body);
- #endif
-
- #ifdef DEBUG_DECODE
- DebugLog(DecodeFile,"</Convert>\n");
- #endif
-
- DeleteShortHeaderContent(&ShortHeader);
-
-// head->From=L"Frommmm";
-// head->Subject=L"Subject";
- return;
-}
-
-void DeleteShortHeaderContent(struct CShortHeader *head)
-{
- if (head->From != nullptr) delete[] head->From;
- if (head->FromNick != nullptr) delete[] head->FromNick;
- if (head->ReturnPath != nullptr) delete[] head->ReturnPath;
- if (head->ReturnPathNick != nullptr) delete[] head->ReturnPathNick;
- if (head->Subject != nullptr) delete[] head->Subject;
- if (head->Date != nullptr) delete[] head->Date;
- if (head->To != nullptr) DeleteShortNames(head->To);
- if (head->Cc != nullptr) DeleteShortNames(head->Cc);
- if (head->Bcc != nullptr) DeleteShortNames(head->Bcc);
- if (head->Body != nullptr) delete[] head->Body;
-}
-
-void DeleteHeaderContent(struct CHeader *head)
-{
- if (head->From != nullptr) delete[] head->From;
- if (head->FromNick != nullptr) delete[] head->FromNick;
- if (head->ReturnPath != nullptr) delete[] head->ReturnPath;
- if (head->ReturnPathNick != nullptr) delete[] head->ReturnPathNick;
- if (head->Subject != nullptr) delete[] head->Subject;
- if (head->Date != nullptr) delete[] head->Date;
- if (head->Body != nullptr) delete[] head->Body;
- if (head->To != nullptr) DeleteNames(head->To);
- if (head->Cc != nullptr) DeleteNames(head->Cc);
- if (head->Bcc != nullptr) DeleteNames(head->Bcc);
-}
-
-void DeleteNames(PYAMN_MIMENAMES Names)
-{
- PYAMN_MIMENAMES Parser=Names,Old;
- for (;Parser != nullptr;Parser=Parser->Next)
- {
- if (Parser->Value != nullptr)
- delete[] Parser->Value;
- if (Parser->ValueNick != nullptr)
- delete[] Parser->ValueNick;
- Old=Parser;
- Parser=Parser->Next;
- delete Old;
- }
-}
-
-void DeleteShortNames(PYAMN_MIMESHORTNAMES Names)
-{
- PYAMN_MIMESHORTNAMES Parser=Names,Old;
- for (;Parser != nullptr;Parser=Parser->Next)
- {
- if (Parser->Value != nullptr)
- delete[] Parser->Value;
- if (Parser->ValueNick != nullptr)
- delete[] Parser->ValueNick;
- Old=Parser;
- Parser=Parser->Next;
- delete Old;
- }
-}
-
-
-void inline ToLower(char *string)
-{
- for (;*string != 0;string++)
- if (*string>='A' && *string<='Z') *string=*string-'A'+'a';
-}
-
-#define TE_UNKNOWN
-#define TE_QUOTEDPRINTABLE 1
-#define TE_BASE64 2
-struct APartDataType
-{
- char *Src;//Input
- char *ContType;
- int CodePage;
- char *TransEnc;
- BYTE TransEncType; //TE_something
- char *body;
- int bodyLen;
- WCHAR *wBody;
-};
-
-
-void ParseAPart(APartDataType *data)
-{
- size_t len = mir_strlen(data->Src);
- try
- {
- char *finder=data->Src;
- char *prev1,*prev2,*prev3;
-
- while(finder<=(data->Src+len))
- {
- while(ENDLINEWS(finder)) finder++;
-
- //at the start of line
- if (finder>data->Src) {
- if (*(finder-2)=='\r' || *(finder-2)=='\n')
- *(finder-2)=0;
- if (*(finder-1)=='\r' || *(finder-1)=='\n')
- *(finder-1)=0;
- }
- prev1=finder;
-
- while(*finder != ':' && !EOS(finder) && !ENDLINE(finder)) finder++;
- if (ENDLINE(finder)||EOS(finder)) {
- // no ":" in the line? here the body begins;
- data->body = prev1;
- break;
- }
- prev2=finder++;
-
- while(WS(finder) && !EOS(finder)) finder++;
- if (!EOS(finder))
- prev3=finder;
- else
- break;
-
- do
- {
- if (ENDLINEWS(finder)) finder+=2; //after endline information continues
- while(!ENDLINE(finder) && !EOS(finder)) finder++;
- }while(ENDLINEWS(finder));
-
- if (!_strnicmp(prev1,"Content-type",prev2-prev1)) {
- data->ContType = prev3;
- } else if (!_strnicmp(prev1,"Content-Transfer-Encoding",prev2-prev1)) {
- data->TransEnc = prev3;
- }
-
- if (EOS(finder))
- break;
- finder++;
- if (ENDLINE(finder)) {
- finder++;
- if (ENDLINE(finder)) {
- // end of headers. message body begins
- if (finder>data->Src) {
- if (*(finder-2)=='\r' || *(finder-2)=='\n')
- *(finder-2)=0;
- if (*(finder-1)=='\r' || *(finder-1)=='\n')
- *(finder-1)=0;
- }
- finder++;
- if (ENDLINE(finder))finder++;
- prev1 = finder;
- while (!EOS(finder+1))finder++;
- if (ENDLINE(finder))finder--;
- prev2 = finder;
- if (prev2>prev1) { // yes, we have body
- data->body = prev1;
- }
- break; // there is nothing else
- }
- }
- }
- }
- catch(...)
- {
- MessageBox(nullptr, TranslateT("Translate header error"), L"", 0);
- }
- if (data->body) data->bodyLen = (int)mir_strlen(data->body);
-}
-
-//from decode.cpp
-int DecodeQuotedPrintable(char *Src,char *Dst,int DstLen, BOOL isQ);
-int DecodeBase64(char *Src,char *Dst,int DstLen);
-int ConvertStringToUnicode(char *stream,unsigned int cp,WCHAR **out);
-
-WCHAR *ParseMultipartBody(char *src, char *bond)
-{
- char *srcback = _strdup(src);
- size_t sizebond = mir_strlen(bond);
- int numparts = 1;
- int i;
- char *courbond = srcback;
- WCHAR *dest;
- for (;(courbond=strstr(courbond,bond));numparts++,courbond+=sizebond);
- APartDataType *partData = new APartDataType[numparts];
- memset(partData, 0, sizeof(APartDataType)*numparts);
- partData[0].Src = courbond = srcback;
- for (i=1;(courbond=strstr(courbond,bond));i++,courbond+=sizebond) {
- *(courbond-2) = 0;
- partData[i].Src = courbond+sizebond;
- while (ENDLINE(partData[i].Src)) partData[i].Src++;
- }
- size_t resultSize=0;
- for (i=0;i<numparts;i++) {
- ParseAPart(&partData[i]);
- if (partData[i].body) {
- if (partData[i].TransEnc) {
- if (!_stricmp(partData[i].TransEnc,"base64")) partData[i].TransEncType=TE_BASE64;
- else if (!_stricmp(partData[i].TransEnc,"quoted-printable"))partData[i].TransEncType=TE_QUOTEDPRINTABLE;
- }
- if (partData[i].ContType) {
- char *CharSetStr;
- if (nullptr != (CharSetStr=ExtractFromContentType(partData[i].ContType,"charset=")))
- {
- partData[i].CodePage=GetCharsetFromString(CharSetStr,mir_strlen(CharSetStr));
- delete[] CharSetStr;
- }
- }
- if (partData[i].ContType && !_strnicmp(partData[i].ContType,"text",4)) {
- char *localBody=nullptr;
- switch (partData[i].TransEncType) {
- case TE_BASE64:
- {
- int size =partData[i].bodyLen*3/4+5;
- localBody = new char[size+1];
- DecodeBase64(partData[i].body,localBody,size);
- }break;
- case TE_QUOTEDPRINTABLE:
- {
- int size = partData[i].bodyLen+2;
- localBody = new char[size+1];
- DecodeQuotedPrintable(partData[i].body,localBody,size,FALSE);
- }break;
- }
- ConvertStringToUnicode(localBody?localBody:partData[i].body,partData[i].CodePage,&partData[i].wBody);
- if (localBody) delete[] localBody;
- } else if (partData[i].ContType && !_strnicmp(partData[i].ContType,"multipart/",10)) {
- //Multipart in mulitipart recursive? should be SPAM. Ah well
- char *bondary=nullptr;
- if (nullptr != (bondary=ExtractFromContentType(partData[i].ContType,"boundary=")))
- {
- partData[i].wBody = ParseMultipartBody(partData[i].body,bondary);
- delete[] bondary;
- } else goto FailBackRaw; //multipart with no boundary? badly formatted messages.
- } else {
-FailBackRaw:
- ConvertStringToUnicode(partData[i].body,partData[i].CodePage,&partData[i].wBody);
- }
- resultSize += mir_wstrlen(partData[i].wBody);
- }// if (partData[i].body)
- resultSize += 100+4+3; //cr+nl+100+ 3*bullet
- }
- dest = new WCHAR[resultSize+1];
- size_t destpos = 0;
- for (i=0;i<numparts;i++) {
- if (i) { // part before first boudary should not have headers
- char infoline[1024]; size_t linesize = 0;
- mir_snprintf(infoline, "%s %d", Translate("Part"), i);
- linesize = mir_strlen(infoline);
- if (partData[i].TransEnc) {
- mir_snprintf(infoline + linesize, _countof(infoline) - linesize, "; %s", partData[i].TransEnc);
- linesize = mir_strlen(infoline);
- }
- if (partData[i].ContType) {
- char *CharSetStr=strchr(partData[i].ContType,';');
- if (CharSetStr) {
- CharSetStr[0]=0;
- mir_snprintf(infoline + linesize, _countof(infoline) - linesize, "; %s", partData[i].ContType);
- linesize = mir_strlen(infoline);
- partData[i].ContType=CharSetStr+1;
- if (nullptr != (CharSetStr=ExtractFromContentType(partData[i].ContType,"charset="))) {
- mir_snprintf(infoline + linesize, _countof(infoline) - linesize, "; %s", CharSetStr);
- linesize = mir_strlen(infoline);
- delete[] CharSetStr;
- }
- if (nullptr != (CharSetStr=ExtractFromContentType(partData[i].ContType,"name="))) {
- mir_snprintf(infoline + linesize, _countof(infoline) - linesize, "; \"%s\"", CharSetStr);
- linesize = mir_strlen(infoline);
- delete[] CharSetStr;
- }
- }
- else {
- mir_snprintf(infoline + linesize, _countof(infoline) - linesize, "; %s", partData[i].ContType);
- linesize = mir_strlen(infoline);
- }
- }
- mir_snprintf(infoline + linesize, _countof(infoline) - linesize, ".\r\n");
- {
- WCHAR *temp=nullptr;
- dest[destpos] = dest[destpos+1] = dest[destpos+2] = 0x2022; // bullet;
- destpos += 3;
- ConvertStringToUnicode(infoline,CP_ACP,&temp);
- size_t wsize = mir_wstrlen(temp);
- mir_wstrcpy(&dest[destpos],temp);
- destpos += wsize;
- delete[] temp;
- }
- } // if (i)
-
- if (partData[i].wBody) {
- size_t wsize = mir_wstrlen(partData[i].wBody);
- mir_wstrcpy(&dest[destpos],partData[i].wBody);
- destpos += wsize;
- delete[] partData[i].wBody;
- }
- }
-
- free (srcback);
- delete[] partData;
- dest[resultSize] = 0;//just in case
- return dest;
-}