#include "POP3.h"
POP3::POP3(char *username,char *password)
{
sockfd=0;
user=username;
pwd=password;
}
POP3::~POP3()
{
if(sockfd>0)
close(sockfd);
}
ssize_t POP3::readn(int fd,void *ptr,size_t n)
{
size_t leftLen;
ssize_t readLen;
char *temp;
temp =(char *)ptr;
leftLen = n;
while(leftLen>0)
{
readLen=read(fd,temp,leftLen);
if(readLen<0)
{
if(errno==EINTR)
readLen=0;
else
return -1;
}
leftLen-=readLen;
temp+=readLen;
}
return (n - leftLen);
}
ssize_t POP3::writen(int fd,void *ptr,size_t n)
{
size_t leftLen;
ssize_t writeLen;
char *temp;
temp=(char *)ptr;
leftLen = n;
while(leftLen>0)
{
writeLen=write(fd,temp,leftLen);
if(writeLen<0)
{
if(errno==EINTR)
writeLen=0;
else
return -1;
}
leftLen-=writeLen;
temp+=writeLen;
}
return n;
}
ssize_t POP3::readLine(int fd,void *ptr,size_t maxLen)
{
ssize_t n, rc;
char c, *temp;
temp = (char *)ptr;
for (n = 1; n < maxLen; n++)
{
again:
if ( (rc = read(fd, &c, 1)) == 1)
{
*temp++ = c;
if (c == '\n') //newline
break;
}
else if (rc == 0)
{
*temp = 0;
return (n - 1); //EOF, n - 1 bytes were read
}
else
{
if (errno == EINTR)
goto again;
return (-1); // error, errno set by read()
}
}
*temp = 0; // null terminate like fgets()
return (n);
}
int POP3::initialize(char* pop3Addr)
{
int retVal=0;
struct hostent *host;
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
perror("client socket");
return -1;
}
bzero(&servAddr,sizeof(servAddr));
servAddr.sin_family=AF_INET;
servAddr.sin_port=htons(SERVPORT);
if(pop3Addr!=NULL)
{
//servAddr.sin_addr.s_addr=inet_addr(pop3Addr);
host=gethostbyname(pop3Addr);
if( host==NULL )
{
perror("gethostbyname");
exit(1);
}
servAddr.sin_addr=*((struct in_addr *)host->h_addr);
}
return 0;
}
int POP3::makeMail(char* pop3Addr,unsigned int randNumber)
{
int retVal;
retVal=initialize(pop3Addr);
if(retVal == -1)
return -1;
int mailNum;
int mailSize;
char *p;
char buf[1024];
//create a email file
char temp[64];
sprintf(temp,"%u.eml",randNumber);
retVal=connect(sockfd,(struct sockaddr*)&servAddr,sizeof(servAddr));
if(retVal<0)
{
printf("connect pop3 server error\n");
return -1;
}
if(readLine(sockfd,buf,1024)==-1)
{
printf("readLine from connect error\n");
close(sockfd);
return -1;
}
if(strncasecmp(buf,"-ERR", 4) == 0)
{
printf("connect response error\n");
close(sockfd);
return -1;
}
//send username
sprintf(buf,"USER %s\r\n",user);
writen(sockfd,buf,strlen(buf));
readLine(sockfd,buf,1024);
if(strncasecmp(buf,"-ERR", 4) == 0)
{
printf("USER response error\n");
close(sockfd);
return -1;
}
//send password
sprintf(buf,"PASS %s\r\n",pwd);
writen(sockfd,buf,strlen(buf));
readLine(sockfd,buf,1024);
if(strncasecmp(buf,"-ERR", 4) == 0)
{
printf("PASS response error\n");
close(sockfd);
return -1;
}
//STAT
strcpy(buf,"STAT\r\n");
writen(sockfd,buf,strlen(buf));
readLine(sockfd,buf,1024);
if(strncasecmp(buf,"-ERR", 4) == 0)
{
printf("STAT response error");
close(sockfd);
return -1;
}
for(p=buf;*p!='\0';p++)
{
if(*p=='\t' || *p==' ')
mailNum=atoi(p);
break;
}
printf("Mail Number is:%d\n",mailNum);
if(mailNum<=0)
{
printf("Now no mail\n");
close(sockfd);
return -1;
}
//RETR--receive the mail
strcpy(buf,"RETR 1\r\n");
writen(sockfd,buf,strlen(buf));
readLine(sockfd,buf,1024);
if(strncasecmp(buf,"-ERR", 4) == 0)
{
printf("STAT response error\n");
close(sockfd);
return -1;
}
for (p=buf;*p!='\0';p++)
{
if (*p == '\t' || *p == ' ')
{
mailSize=0;
mailSize = atoi(p);
break;
}
}
printf("mail Size:%d\n",mailSize);
FILE *fp;
fp=fopen(temp,"w");
int block=mailSize/1024;
int nleft=mailSize%1024;
printf("Begin to download mail--------\n");
for(int i=0;i<block;i++)
{
readn(sockfd,buf,1024);
fwrite(buf,1024,1,fp);
}
readn(sockfd,buf,nleft);
fwrite(buf,1,nleft,fp);
fclose(fp);
printf("finish downloading mail--------\n");
//***********important***********************
readLine(sockfd,buf,1024); //for ".\r\n"
//DELE
strcpy(buf,"DELE 1\r\n");
writen(sockfd,buf,strlen(buf));
readLine(sockfd,buf,1024);
if(strncasecmp(buf,"-ERR",4) == 0)
{
printf("DELE response error\n");
close(sockfd);
//rm this file
sprintf(buf,"rm -f %s",temp);
system(buf);
return -1;
}
//QUIT
strcpy(buf,"QUIT\r\n");
writen(sockfd,buf,strlen(buf));
close(sockfd);
mailNum--;
return mailNum;
}