📄 client.cpp
字号:
attachmentNames);
if(bodyhtml.length())
{
GivenUniqueFileName(mailboxname,"htmlmail",tagStr,".htm");
downloadFile.open(tagStr.c_str());
assert(!downloadFile.fail());
if(!downloadFile.fail())
downloadFile.write(bodyhtml.c_str(),bodyhtml.length());
downloadFile.close();
}
return TRUE;
}
void WriteAttachmentToFile(const string& dir,
const string& filename,
const char* content,
int length,
string& newfilename)
{
string posfix=filename;
string prefix;
string::size_type pos=0;
ofstream file;
if(!filename.length())
return;
if((pos=posfix.find('.',pos))!=string::npos && pos!=0)
{
prefix=posfix.substr(0,pos);
posfix=posfix.substr(pos,posfix.length()-pos);
}
else
{
prefix=filename;
posfix="";
}
GivenUniqueFileName(dir,prefix,newfilename,posfix);
file.open(newfilename.c_str(),ios::binary);
assert(!file.fail());
if(!file.fail())
file.write(content,length);
file.close();
}
void DataBody( ifstream& file,
const string& mailbox,
BOOL bBase64,
int contentType,
string& tagStr, //if content==2 , it standards the filename else majorSplitTag
string& bodytext,
string& bodyhtml,
map<string, string> & attachmentNames)
{
string majorSplitTag;
string subSplitTag;
string attachStr;
string text;
string newfilename;
char buffer[BUFFER_BLOCK_SIZE];
char * result;
int length;
bodytext="";
bodyhtml="";
attachmentNames.clear();
//text/plain, text/html, attachment
if(contentType==0 || contentType==1 || contentType==2)
{
SimpleMail(file,bBase64,text);
if(contentType==0)
bodytext=text;
else if(contentType==1)
bodyhtml=text;
else
{
WriteAttachmentToFile(mailbox,tagStr, text.c_str(), text.length(),newfilename);
attachmentNames.insert(make_pair(tagStr,newfilename));
}
return;
}
majorSplitTag=tagStr;
while(!file.eof())
{
file.getline(buffer,BUFFER_BLOCK_SIZE);
if(strstr(buffer,tagStr.c_str())!=NULL)
break;
}
BOOL b_Base64;
int content_Type;
while(1)
{
if(!FilterHead(file,b_Base64,content_Type, tagStr))
break;
if(content_Type==0)
SubResolve(file,b_Base64,majorSplitTag,bodytext);
else if(content_Type==1)
SubResolve(file,b_Base64,majorSplitTag,bodyhtml);
else if(content_Type==2)
{
SubResolveAdv(file,b_Base64,majorSplitTag,&result,length);
WriteAttachmentToFile(mailbox,tagStr, result, length,newfilename);
attachmentNames.insert(make_pair(tagStr,newfilename));
delete[] result;
}
else
{
//sub boundary
subSplitTag=tagStr;
while(1)
{
if(!FilterHead(file,b_Base64,content_Type, subSplitTag,majorSplitTag))
break;
subSplitTag=tagStr;
assert(content_Type!=3);
tagStr=subSplitTag;
if(content_Type==0)
SubResolve(file,b_Base64,tagStr,bodytext);
else if(content_Type==1)
SubResolve(file,b_Base64,tagStr,bodyhtml);
else if(content_Type==2)
{
SubResolveAdv(file,b_Base64,tagStr,&result,length);
WriteAttachmentToFile(mailbox,tagStr, result, length,newfilename);
attachmentNames.insert(make_pair(tagStr,newfilename));
delete[] result;
}
}
}
}
}
//type one: plain mail
BOOL SimpleMail(ifstream& file, BOOL bBase64, string& text)
{
char *des;
int length;
filebuf *fB;
string str;
text="";
if(bBase64)
{
// file.getline(buffer,BUFFER_BLOCK_SIZE);
// while(strlen(buffer)==0)
// file.getline(buffer,BUFFER_BLOCK_SIZE);
getline(file,str,'\n');
while(str.length()==0 && !file.eof())
getline(file,str,'\n');
do
{
text+=str;
// file.getline(buffer,BUFFER_BLOCK_SIZE);
getline(file,str,'\n');
}while(str.length()!=0 && !file.eof());
// assert(text.length()%4==0);
if(text.length()%4!=0)
return FALSE;
if(text.length()>0)
{
des= new char[text.length()/4*3+1];
DecodingBase64Adv(text.c_str(), text.length(), des);
text=des;
delete []des;
}
}
else
{
fB=file.rdbuf();
length=fB->pubseekoff(0,ios::end,ios::in) - fB->pubseekoff(0,ios::beg,ios::in);
fB->pubseekoff(length,ios::end,ios::in);
length-=3; //-3 is \n.\n
if(length>0)
{
des= new char[length+1];// + 1 is NULL
file.read(des,length);
des[length]='\0';
text=des;
delete []des;
}
}
return TRUE;
}
void SubResolve(ifstream& file,BOOL bBase64, string& splitTag,string& text)
{
// char buffer[BUFFER_BLOCK_SIZE];
string str;
char *des;
text="";
if(bBase64)
{
// file.getline(buffer,BUFFER_BLOCK_SIZE);
getline(file,str,'\n');
while(!file.eof())
{
// if(strstr(buffer,splitTag.c_str())!=NULL)
// break;
if(str.substr(0,splitTag.length())==splitTag)
break;
//text+=buffer;
text+=str;
getline(file,str,'\n');
//file.getline(buffer,BUFFER_BLOCK_SIZE);
}
assert(text.length()%4==0);
if(text.length()>0)
{
des= new char[text.length()/4*3+1];
DecodingBase64Adv(text.c_str(), text.length(), des);
text=des;
delete []des;
}
}
else
{
getline(file,str,'\n');
while(!file.eof())
{
//strstr(buffer,splitTag.c_str())!=buffer
// if(str==splitTag)
// break;
if(str.substr(0,splitTag.length())==splitTag)
break;
text+=str+"\n";
getline(file,str,'\n');
}
}
}
void SubResolveAdv(ifstream& file,BOOL bBase64, string& splitTag,char** result, int& length)
{
string text;
string str;
if(bBase64)
{
getline(file,str,'\n');
while(!file.eof())
{
if(str.substr(0,splitTag.length())==splitTag)
break;
text+=str;
getline(file,str,'\n');
}
assert(text.length()%4==0);
if(text.length())
{
length=text.length()/4*3;
*result= new char[length+1];
DecodingBase64Adv(text.c_str(), text.length(), *result);
}
else
{
*result=NULL;
length=0;
}
}
else
{
getline(file,str,'\n');
while(!file.eof())
{
//strstr(buffer,splitTag.c_str())!=buffer
if(str==splitTag)
break;
text+=str+"\n";
getline(file,str,'\n');
}
if(text.length())
{
length=text.length();
*result= new char[length+1];
strcpy(*result,text.c_str());
}
else
{
*result=NULL;
length=0;
}
}
}
//contentType: 0 text/plain
// 1 text/html
// 2 attachment
// 3 multipart/alternative; boundary
//When contentType is 2, the tagStr standard the file name.
//When contentType is 3, the tagStr standard the subsplit tag.
BOOL FilterHead(ifstream& file, BOOL& bBase64,int& contentType,string& tagStr,string majorSplitPart)
{
string str;
char *tP;
char buffer[BUFFER_BLOCK_SIZE];
tagStr="";
//read until an empty line
while(!file.eof())
{
file.getline(buffer,BUFFER_BLOCK_SIZE);
if(buffer[0]=='-' && buffer[1]=='-' && strcmp(buffer,majorSplitPart.c_str())==0) //sub boundary ending
return FALSE;
if(strlen(buffer)==0 && str.length()!=0)
break;
str+=buffer;
}
if(file.eof())
return FALSE;
if(strstr(str.c_str(),"base64")!=NULL)
bBase64=TRUE;
else
bBase64=FALSE;
//
if(strstr(str.c_str(),"multipart/alternative")!=NULL)//split tag
{
contentType=3;
tP=strstr(str.c_str(),"\"");
tP++;
assert(tP!=NULL);
while(*tP!='\"')
tagStr+=*tP++;
tagStr=string("--")+tagStr;
while(1)
{
file.getline(buffer,BUFFER_BLOCK_SIZE);
if(buffer[0]=='-' && buffer[1]=='-' && strcmp(buffer,tagStr.c_str())==0) //sub boundary ending
break;
}
}
else if(strstr(str.c_str(),"attachment")!=NULL ||
strstr(str.c_str(),"name=")!=NULL) //filename
{
contentType=2;
tP=strstr(str.c_str(),"\"");
assert(tP!=NULL);
tP++;
while(*tP!='\"')
tagStr+=*tP++;
strcpy(buffer,tagStr.c_str());
ResolveOneLineWords(buffer,tagStr);
}
else if(strstr(str.c_str(),"text/html")!=NULL) //html
{
contentType=1;
}
else if(strstr(str.c_str(),"text/plain")!=NULL) //plain
{
contentType=0;
}
return TRUE;
}
//For high efficient, pls rewrite it using looking-up table
UCHAR SixBitDecodeIndex(char a)
{
if(a>='A'&&a<='Z')
return a-'A';
else if(a>='a'&&a<='z')
return 26+a-'a';
else if(a>='0'&&a<='9')
return 52+a-'0';
else if(a=='+')
return 62;
else if(a=='/')
return 63;
else if(a=='=')
return 0;
else
{
assert(FALSE);
return -1;
}
}
void DecodingBase64(const char* src, char* des)
{
assert(src&&des);
assert(strlen(src)%4==0);
while(*src!=NULL)
{
*des++=SixBitDecodeIndex(*src)<<2 | SixBitDecodeIndex(*(src+1))>>4; //6+2
src++;
*des++=SixBitDecodeIndex(*src)<<4 | SixBitDecodeIndex(*(src+1))>>2;//4+4
src++;
*des++=SixBitDecodeIndex(*src)<<6 | SixBitDecodeIndex(*(src+1)); //2+6
src+=2;
}
*des=NULL;
}
void DecodingBase64Adv(const char* src, int length, char* des)
{
int i=0;
assert(des);
assert(length%4==0);
while(i<length)
{
*des++=SixBitDecodeIndex(src[i])<<2 | SixBitDecodeIndex(src[i+1])>>4; //6+2
i++;
*des++=SixBitDecodeIndex(src[i])<<4 | SixBitDecodeIndex(src[i+1])>>2;//4+4
i++;
*des++=SixBitDecodeIndex(src[i])<<6 | SixBitDecodeIndex(src[i+1]); //2+6
i+=2;
}
*des=NULL;
}
/**********************************************************************************/
u_long ConvertHostnameToLongHostAddress(const char * destAddress)
{
hostent * host=gethostbyname((const char *)destAddress);
if(host==NULL)
{
cout<<"Cann't resolve this host name: "<<GetLastError()<<endl;
return -1;
}
return ntohl((*(struct in_addr*)host->h_addr).S_un.S_addr);
}
int Socks5StartIPv4(const string& proxyServerHostName,
u_int proxyServerPort,
const string& username,
const string& pass,
u_long destAddress,
u_int destPort,
SOCKET& sock)
{
sockaddr_in serverAddr;
int retCode;
char buffer[BUFFER_BLOCK_SIZE];
BYTE version=5;
BYTE authorWay1=0; //no authority
BYTE authorWay2=2; //user/pass authority
int rsv=0;
string addrStr;
u_int t;
sock=socket(AF_INET, SOCK_STREAM,0);
serverAddr.sin_addr.S_un.S_addr=htonl(ConvertHostnameToLongHostAddress(proxyServerHostName.c_str()));
serverAddr.sin_family=AF_INET;
serverAddr.sin_port=htons(proxyServerPort);
cout<<"Connecting to "<<inet_ntoa(serverAddr.sin_addr)<<"\tPort:"<<proxyServerPort<<endl;
cout.flush();
if(connect(sock,(const sockaddr*)&serverAddr,sizeof(sockaddr))==SOCKET_ERROR)
{
cout<<"Cannot connect to Server: "<<proxyServerHostName.c_str()<<endl;
cout.flush();
closesocket(sock);
return -1;
}
//1. authoutication negotiation
sprintf(buffer,"%c%c%c%c",version,2,authorWay1,authorWay2);
send(sock,buffer,4,0);
retCode=recv(sock,buffer,BUFFER_BLOCK_SIZE,0);
DEAL_SOCK_ERROR(retCode,sock);
if(char(retCode)==0xFF)
return 1;
buffer[retCode]='\0';
cout<<buffer;
//user/pass authentication
if(buffer[1]==authorWay2)
{
//user name
sprintf(buffer,"%c%c%s%c%s",char(0x01),char(username.length()),username.c_str(),
char(pass.length()),pass.c_str());
t=3+username.length()+pass.length();
send(sock, buffer, t, 0);
retCode=recv(sock,buffer,BUFFER_BLOCK_SIZE,0);
DEAL_SOCK_ERROR(retCode,sock);
if(char(retCode)==0xFF)
return 1;
buffer[retCode]='\0';
if(buffer[1]!=0)
return 1;
}
//1. authoutication negotiation
addrStr=buffer;
t=htons(destPort);
sprintf(buffer,"%c%c%c%c%c%c%c%c%c%c",version,char(0x01),rsv,char(0x01),
((char*)&destAddress)[3],((char*)&destAddress)[2],((char*)&destAddress)[1],((char*)&destAddress)[0],
((char *)&t)[0],((char *)&t)[1]);
cout<<buffer;
send(sock,buffer,10,0);
retCode=recv(sock,buffer,BUFFER_BLOCK_SIZE,0);
DEAL_SOCK_ERROR(retCode,sock);
buffer[retCode]='\0';
if(buffer[1]!=0)
{
sprintf(buffer,"%x",buffer[1]);
cout<<"Failure in negotiation: "<<buffer<<endl;
return 1;
}
return 0;
}
BOOL ReceiveMessage(SOCKET sock, char* buffer, int bufferLen)
{
int startPos;
int ret;
startPos=0;
while(bufferLen>0)
{
ret=recv(sock,buffer+startPos,bufferLen,0);
if(ret==0)
break;
if(ret==SOCKET_ERROR)
return FALSE;
startPos+=ret;
bufferLen-=ret;
}
return bufferLen==0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -