linux C pop邮件到本地笔记

#include "popeml.h"
void SetSocketConnect(char *server,int *sockfd)
{
    int nREUSEADDR = 1; //socket可重用
    char IPaddr[24];
    struct hostent *hp = NULL;    
  struct sockaddr_in addr;
  hp  = gethostbyname(server);
  if( hp != NULL )
  {        
          sprintf(IPaddr,"%d.%d.%d.%d",
                 (hp->h_addr_list[0][0]&0x00ff),
                 (hp->h_addr_list[0][1]&0x00ff),
                 (hp->h_addr_list[0][2]&0x00ff),
                 (hp->h_addr_list[0][3]&0x00ff));        
  }
#ifdef DEBUG_LOG
  printf("Get IP Addr: %s\n ", IPaddr );
#endif
    memset(&addr, 0, sizeof(addr));    
    addr.sin_family = AF_INET;   
  addr.sin_port = htons(110);
    addr.sin_addr.s_addr =  inet_addr(IPaddr);
    
    *sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);   
  if (*sockfd < 0) {
        printf("socket error!");
        exit(1);
  }        
  setsockopt(*sockfd,SOL_SOCKET,SO_REUSEADDR,(const char*)&nREUSEADDR,sizeof(int));
  if(connect(*sockfd, (struct sockaddr *) &addr,sizeof(addr)) < 0 ){
        printf("connect error!\n");
        exit(1);
    }   
    memset(recvbuf,0x0,BUFFLEN);
    while ( read(*sockfd, recvbuf, BUFFLEN) == 0)
    {    
          printf("reconnect...\n");
          sleep(1);
          close(*sockfd);    
          *sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    
          if (*sockfd < 0){
              printf("resocket wrong!\n");
                 continue;
          }    
          setsockopt(*sockfd,SOL_SOCKET,SO_REUSEADDR,(const char*)&nREUSEADDR,sizeof(int));
        if(connect(*sockfd, (struct sockaddr *) &addr,sizeof(addr)) < 0 ){
              printf("reconnect error!\n");
              continue; ;
          }   
          memset(recvbuf, 0, BUFFLEN);
    }
#ifdef DEBUG_LOG
    printf("recv :%s \n",recvbuf);
#endif     
    return ;
}

int send_recv_function(int sc,char *s,char *r)
{
   if (send(sc, s, strlen(s), 0) < 0)
   {
         printf(" send %s error!\n",s);
         return -1;
   }
   sleep(1);   
   memset(r, 0, BUFFLEN);  
   if (read(sc, r, BUFFLEN) < 0)    
   {
         printf(" read [send]%s error!\n",s);
         return -1;
   }    
   else
   {
#ifdef DEBUG_LOG
       printf("send:%s recv :%s \n",s,r);
#endif
   }
   return 0;
}
int send_recv_function2(int sc,char *s,char *maxr)
{
   if (send(sc, s, strlen(s), 0) < 0)
   {
         printf(" send %s error!\n",s);
         return -1;
   }
   sleep(1);   
   memset(maxr, 0, MAXBUFF);  
   if (read(sc, maxr, MAXBUFF) < 0)    
   {
         printf(" read [send]%s error!\n",s);
         return -1;
   }    
   else
   {
#ifdef DEBUG_LOG
       printf("send:%s recv :%s \n",s,maxr);
#endif
   }
   return 0;
}
void Dfree_mes_list(struct _message_list  *msl)
{
    struct _message_list *p ,*q;
    
    p = msl;
    while(p)
  {
      q = p->next;
      free(p);
      p = q;
  }
    return ;
}
void Show_mes_list(struct _message_list  *msl)
{
  int i = 0;
    struct _message_list *p ;
    
    p = msl;
    while(p)
  {
      printf("[%d] mid :%d ,size:%d .\n",i,p->mid,p->msize);
      p = p->next;
      i++;
  }
    return ;
}
void get_message_num(char *s,int *num)
{    
    char buff[10];    
    char *p ,*q;
    
    p = q = NULL;
    memset(buff,0x0,10);
    p = strstr(s,"has");
    q = strstr(s,"messages");
    if (q && p)
    {
         *q-- = '\0';
         strcpy(buff,p+4);
         *num = atoi(buff);
         printf("List %d messages \n",*num);
    }
    else{
         printf("List  messages num error \n");
  }
    return;    
}
int get_message_list(message_s *msl,char *buff,int emlsum)
{
    char *p;
    char id[10];
    char msize[10];
    int i;
    int flag;
    message_s *q;
    
    i = flag = 0;
        
    /*init message list*/
    q = msl;
    while(emlsum)
    {
        q->flag=0;
        q->next = (message_s *)calloc(1,sizeof(message_s));
        if (!q){
             return -1;
        }
        q = q->next;
        emlsum--;
    }
    /*get eml list*/
    p = buff;    
    while((*p != '\0')&&(*p != 0x2e))
    {
        if ((*p == 0x20)&&(i != 0)){                 
            id[i] = '\0';            
            msl->mid = atoi(id);
            i = 0;
            p++;
            flag = 1;
            continue;
      }
      if (*p == 0x0d){                 
            msize[i] = '\0';            
            msl->msize = atoi(msize);
            i =0;
            p++;
            flag = 0;
            msl = msl->next ;
            continue;
      }
        if ((*p >= 0x30) && (*p <= 0x39))
        {
                if (flag == 0)
                 id[i] = *p;
              else
                   msize[i] = *p;
              i++;
/*#ifdef DEBUG_LOG
                printf("%02x",*p);
#endif*/
        }    
/*#ifdef DEBUG_LOG        
        if (*p == 0x0a)   printf("\n\n");
#endif*/
            
        p ++;
        
    }
    return 0;    
}

static void  error_write_eml(FILE *fp, char *fname)
{
    fclose(fp);    
    fp = NULL;
    remove(fname);    
    return;
}
int write_eml (int id,int size,int *flag,char *fname,int sockfd)
{
      
        int rsize;
        int tmpsize;
        char *p = NULL;
        char *q = NULL;
        FILE *fp = NULL;
        char tmpstr[48];
        
        snprintf(tmpstr,48,"+OK %d octets\r\n",size);      
        tmpsize = strlen(tmpstr);
        
        fp = fopen(fname,"w+");
        if(!fp)
        {
         printf("fopen %s failed , because %s.\n",fname,strerror(errno));    
            return -1;    
    }    
    snprintf(sendbuf,BUFFLEN,"retr %d\r\n",id);       
    if (send(sockfd, sendbuf, strlen(sendbuf), 0) < 0)
    {
          printf(" send %s error!\n",sendbuf);
          return -1;
    }
    
    while(1)
   {
         rsize = 0;
         memset(recvbuf,0x0,BUFFLEN);
       if ( (rsize = read(sockfd,recvbuf,BUFFLEN)) > 0)
       {
#ifdef DEBUG_LOG
          printf("%s",recvbuf);
#endif
               if (rsize < 10)  
                    break;               
               
             if(strstr(recvbuf,"error code")) {
              error_write_eml(fp,fname);
                      break;             
              }
              if ((q = strstr(recvbuf,tmpstr)) != NULL)
              {
                   rsize = strlen(q);
                   fwrite(q+tmpsize+1,1,rsize,fp);
              }    
              else if (( p = strstr(recvbuf,"\r\n.\r\n")) != NULL)
              {
                   *(p+2) = '\0';
                   rsize = strlen(recvbuf);
                   fwrite(recvbuf,1,rsize,fp);
                   fclose(fp);
                   *flag = 1;
                   break;
              }
              else
                fwrite(recvbuf,1,rsize,fp);
       }                  
       else if (rsize == 0)
       {
              error_write_eml(fp,fname);
              close(sockfd);
              exit(-1);
       }
       else  //rsize < 0
       {
               if(errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN){
                      error_write_eml(fp,fname);
                        fprintf(stderr,"socket error errno=%d ,%s",errno,strerror(errno));
               
                           int j ;
                           for(j=1;j<=id;j++) {
                                snprintf(sendbuf,BUFFLEN,"dele %d\r\n",j);
                          send_recv_function(sockfd,sendbuf,recvbuf);    
                            }                      
               
                        snprintf(sendbuf,BUFFLEN,"%s\r\n","QUIT");
                   send_recv_function(sockfd,sendbuf,recvbuf);    
                   
                        exit(1);
                  }
               else if((errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)) {
                      printf("errno %d error:%s\n",errno,strerror(errno));                                  
                      continue;
                      sleep(1);
               }          
          
          }
    }
    
    return 0;
            
}
int download_eml(message_s *msl,int sockfd,char *dir)
{
    char fname[512];
    struct _message_list *p,*q ;

    time_t tNow;
    struct tm tmNow;
  char dirname[256];
 
    time(&tNow);
    localtime_r(&tNow, &tmNow);
    
  snprintf(dirname,256,"%s/%04d%02d%02d/dyn_10/key_%02d%02d",dir,
          (1900+tmNow.tm_year),(1+tmNow.tm_mon),tmNow.tm_mday,tmNow.tm_hour,tmNow.tm_min);
  if(access(dirname,0 ) != 0)
  {
       umask(0);
     mkdir(dirname,0777);
  }
            
#ifdef DEBUG_LOG    
    printf("maildata path %s\n",dirname);
#endif     
    
    q = p = msl->next;//第一行为邮件列表总数
    while(p)
  {     
      memset(fname,0x0,512);
      snprintf(fname,512,"%s/%ld.%d.eml",dirname,time(NULL),p->mid);
      write_eml(p->mid,p->msize,&(p->flag),fname,sockfd);
      p = p->next;      
  }
  while(q)
  {
          if (q->flag)
        {
            snprintf(sendbuf,BUFFLEN,"dele %d\r\n",q->mid);
            send_recv_function(sockfd,sendbuf,recvbuf);
        }
        q = q->next;      
    }
    return 0;    
}
int pop_eml_down(char *server,char *usr,char *pwd,char *path)
{
        int messageNum = 0;
        int sockfd = -1;
        struct _message_list  *msl ;
        
        msl = NULL;
        msl = (message_s*)calloc(1,sizeof(message_s));    
        //msl = (message_s *)malloc(sizeof(message_s));
        if (!msl){
             return -1;
        }
        /*create socket and connect*/
        SetSocketConnect(server,&sockfd);        
        
    /*auth login */    
    memset(sendbuf,0,BUFFLEN);
    memset(recvbuf,0x0,BUFFLEN);   
    
    snprintf(sendbuf,BUFFLEN,"%s\r\n",usr);
        send_recv_function(sockfd,sendbuf,recvbuf);
        
        snprintf(sendbuf,BUFFLEN,"%s\r\n",pwd);
        send_recv_function(sockfd,sendbuf,recvbuf);
        
        
        get_message_num(recvbuf,&messageNum);
        if (messageNum == 0)
             goto END_POP_EML_DOWN;
            
        snprintf(sendbuf,BUFFLEN,"%s\r\n","list");
        send_recv_function2(sockfd,sendbuf,maxrecvbuf);
        
        /*eml list*/
        get_message_list(msl,maxrecvbuf,messageNum);
        //Show_mes_list(msl);
    
        /*pop eml*/
        download_eml(msl,sockfd,path);
        
        snprintf(sendbuf,BUFFLEN,"%s\r\n","QUIT");
        send_recv_function(sockfd,sendbuf,recvbuf);
        
END_POP_EML_DOWN:            
        if (sockfd > 0) close(sockfd);
        Dfree_mes_list(msl)    ;
        return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值