⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pop3smtp.c

📁 一个功能全面的电子邮件客户端
💻 C
📖 第 1 页 / 共 3 页
字号:
  MAILSTREAM *stream ;  PopAccount *curpop=seek_popaccount (id);  char flags[4096] ;  char *mailbox;  char *snum ;  int msgs;  stream = NULL ;  mailbox=(char *)calloc(4096,sizeof(char));  /* check to see if the popaccount struct exists */#ifdef DMALLOC  dmalloc_verify( 0 ) ;#endif  if (curpop==NULL) {#ifdef DEBUG    printf ("pop3smtp: pop3login: Pop account %d not defined\n", id);#endif    if(mailbox) free(mailbox);    return NDEFACCOUNT;  }  if (curpop->phost==NULL) {#ifdef DEBUG    printf ("pop3smtp: pop3login: Host not defined for account '%s', id=%d\n", curpop->name, id);#endif    if(mailbox) free(mailbox);    return NDEFHOST;  }  if (curpop->puser==NULL) {#ifdef DEBUG    printf ("pop3smtp: pop3login: User not defined for account '%s', id=%d\n", curpop->name, id);#endif    if(mailbox) free(mailbox);    return NDEFUSER;  }  if( (curpop -> ppasswd == NULL) ||   ( (curpop -> ppasswd) && (!strlen(curpop -> ppasswd)) ) ) {#ifdef DEBUG    printf ("pop3smtp: pop3login: Password not defined for account '%s', id=%d\n", curpop->name, id);#endif     if(mailbox) free(mailbox);    return NDEFPASSWORD;  }  flags[0] = 0x00 ;#if WANTSSL  /*   * See if we need to modify the mailbox specification by adjusting   * for SSL.  Also notice that we support the certification validation   * request flags too.   */  if( curpop -> flags & SSL_CONN ) {    strcat( flags, "/ssl" ) ;    if( curpop -> flags & SSL_VERIFY_CERT ) strcat( flags, "/validate-cert" ) ;    else strcat( flags, "/novalidate-cert" ) ;  }#endif    switch( curpop -> type ) {  case POP3:    sprintf(mailbox,"{%s:%d/pop3%s/user=\"%s\"}%s",curpop->phost,curpop->pport,	    flags, curpop->puser, "Inbox" ) ;    break ;      case IMAP:    sprintf(mailbox,"{%s:%d/imap%s/user=\"%s\"}%s",curpop->phost,curpop->pport,	    flags, curpop->puser, "Inbox" ) ;    break ;  }#ifdef DEBUG  printf("try to open mailbox: %s\n", mailbox);#endif  mmpopid=id;	#if DEBUG > 4  if( curpop -> flags & DELETEFROMSERVER ) stream = mail_open( stream, mailbox, OP_EXPUNGE | OP_DEBUG ) ;  else stream = mail_open( stream, mailbox, OP_DEBUG ) ;#else  if( curpop -> flags & DELETEFROMSERVER ) stream = mail_open( stream, mailbox, OP_EXPUNGE ) ;  else stream = mail_open( stream, mailbox, 0 ) ;#endif  if( !stream ) {    printf("ERROR:  %s mailbox failed to open.\n", mailbox );    if(mailbox) free(mailbox);    return UNKNOWNERR;  }#if DEBUG > 3  printf( "$mailbox ok - messages: %lu   - recent: %lu\n", stream->nmsgs, stream->recent ) ;  printf( "cmsg = %d and tmsg = %d.\n", curpop -> popcmsg, curpop -> poptmsg ) ;  if( stream -> recent > curpop -> popcmsg ) printf( "Looks like we need to be fetching some mail!\n" ) ;#endif  if(mailbox) free(mailbox);  /*   * Tell everyone how many TOTAL messages we have on account.   */#if DEBUG > 5  printf( "Sending 'TOTALMESSAGES' to parent with id = %d.\n", curpop -> id ) ;#endif  snum = disassemble_long( (unsigned long)stream -> nmsgs ) ;  pipe_parent_stat_put( TOTALMESSAGES, snum, 4 ) ;  free( snum ) ;  /*   * We need this to guard against multiple fetches!   * The logic works like this.  As long as we are   * in non-delete mode, popcmsg should always be equal to   * or less than the recent messages.  Otherwise, that   * means that the account has been manipulated else where   * and/or had some deleted, which means that we need to   * attempt to fetch all messages since they could all   * be new messages.   */#ifdef DEBUG#ifdef DMALLOC  dmalloc_verify( 0 ) ;#endif#endif  /*   * If this is an IMAP account, directly report the number of new messages   * reported by the server.  Otherwise, we need to jump through hoops to   * deduce the value.  Likewise, if we are not in delete mode,    */  if( curpop -> type == IMAP ) {#if DEBUG > 4    printf( "account type is IMAP\n" ) ;#endif    msgs = stream -> recent ;  } else {#if DEBUG > 4    printf( "account type is POP3\n" ) ;#endif    if( curpop -> flags & DELETEFROMSERVER) {      if( curpop -> popcmsg > stream -> recent ) curpop -> popcmsg = 0 ;      else curpop -> popcmsg = stream -> nmsgs ;      msgs = curpop -> popcmsg ;    } else {      msgs = abs(stream -> recent - curpop -> popcmsg) ;    }  }  /*   * Now, if forced fetch is enable, we're going to override the   * above computed values.   */  if( curpop -> flags & FORCE_FETCH ) {    msgs = stream -> nmsgs ;    curpop -> popcmsg = 0 ;  }  /* just go ahead and force download whatever is in the mailbox */    msgs = stream -> nmsgs ;    curpop -> popcmsg = 0 ;  /* No matter what, we always do this */  curpop -> poptmsg = stream -> nmsgs ;  *retStream = stream ;  return msgs ;}int new_pop3_logout (int id, MAILSTREAM *stream) {  PopAccount *curpop=seek_popaccount(id);#if DEBUG > 4	  printf("**POP3logout: doing logout!\n");#endif	  if (((curpop->flags&REMBER_PASSWORD)!=REMBER_PASSWORD)&&      ((curpop->flags&REMBER_PASSWORD_ALWAYS)!=REMBER_PASSWORD_ALWAYS))    destroy_popaccount_password (id);#if DEBUG >4		  printf("DOING LOGOUT\n");	#endif	#ifdef DMALLOC  dmalloc_verify( 0 ) ;#endif  if( curpop -> flags & DELETEFROMSERVER ) {    /* just to be extra sure */    mail_expunge( stream ) ;    mail_close_full( stream, CL_EXPUNGE ) ;  }  else mail_close_full( stream, 0 ) ;#ifdef DMALLOC  dmalloc_verify( 0 ) ;#endif  return 0;}char *new_pop3_get_message(int id, int message, int *error, MAILSTREAM *stream ) {  PopAccount *curpop;  char *msgbuf = NULL;  char *snum,*data,*msgbuf2,*ret,*smsg;  unsigned long stype, ssize;  int msgsize, hdrsize, bodysize ;  int index, serror ;  *error=0;  ret = NULL ;  curpop=seek_popaccount(id);#if DEBUG > 6  puts( "new_pop3_get_message()\n" ) ;  printf("*************\nnew pop3msg init: %d    nmsgs: %ld   account:%d\n",message, stream->nmsgs, id ) ;#endif	#ifdef DMALLOC  dmalloc_verify( 0 ) ;#endif  if (curpop==NULL) {    *error=NDEFACCOUNT;    goto error;  }  /* make sure we have messages available to fetch, otherwise c-client blows chunks */#ifdef DMALLOC  dmalloc_verify( 0 ) ;#endif  /* Figure out which message to get */  index = message ;  msgsize = 0 ;  #ifdef DEBUG	  printf( "fetching header and it's length while using an index value of %d...\n", index ) ;#endif	  /* Fetch the data lengths */  if( (hdrsize = strlen( mail_fetchheader( stream, index ) )) ) {#ifdef DEBUG	    printf( "fetching text body and it's length...\n" ) ;#endif	    bodysize = strlen( mail_fetchtext( stream, index ) ) ;    msgsize = hdrsize + bodysize + (1 + 1) ;     // NULL and '\n' stuff#ifdef DEBUG	    printf("Counting OK w/%d\n", msgsize ) ;#endif#ifdef DEBUG#ifdef DMALLOC    dmalloc_verify( 0 ) ;#endif    printf( "Getting ready to do a pipe_parent_stat_put with the MSGSIZE...\n" ) ;#endif    snum=disassemble_long (((unsigned long)msgsize));    pipe_parent_stat_put (MSGSIZE, snum, 4);    free (snum);#if DEBUG > 4#ifdef DMALLOC    dmalloc_verify( 0 ) ;#endif    printf("try to setup the msgbuf (size:%d)\n",msgsize);#endif	    msgbuf = mail_fetchheader( stream, index ) ;    msgbuf2 = mail_fetchtext( stream, index ) ;	    ret = (char *)calloc( msgsize, sizeof(char) ) ;    sprintf( ret, "%s\n%s", msgbuf, msgbuf2 ) ;#if DEBUG > 6#ifdef DMALLOC    dmalloc_verify( 0 ) ;#endif    printf("****we said we put %d of data %d real done!\n",msgsize,strlen(ret));    printf("do child_stat_get()\n");#endif	    /* Get the status from the child */    data=pipe_child_stat_get( &stype, &ssize, &serror ) ;#ifdef DMALLOC    dmalloc_verify( 0 ) ;#endif    if (stype==STOP) {      *error=PARENTSTOP;      goto error;     } else if (stype==SKIP) {      *error=PARENTSKIP;      goto error;    } else if (stype!=-1) {      pipe_child_stat_put (stype, data, ssize);    }    if ((curpop->flags&DELETEFROMSERVER)==DELETEFROMSERVER) {#ifdef DEBUG           printf("Deleting messages from server:\n");#endif             smsg=(char *)calloc(256,sizeof(char));      sprintf(smsg,"%d",index);#ifdef DEBUG             printf("Flags: %d\n",stream->perm_seen);#endif             mail_setflag (stream,smsg,"\\deleted");      if(smsg) free(smsg);    }    goto done ;  error:    if(msgbuf) free(msgbuf);    ret = NULL ;  } else {#ifdef DMALLOC    dmalloc_verify( 0 ) ;#endif#ifdef DEBUG    printf("Counting FAILED on header and got %d.\n", hdrsize ) ;#endif	    *error = 0xfaded ;  } done:#ifdef DMALLOC  dmalloc_verify( 0 ) ;#endif  return ret ;}/* * Okay, it works like this: * c-client calls this function and so on, and so on... * c-client -> post_rfc_output -> tradeclient_rfc822_output -> * tradeclient_encode_body; tradeclient_rfc822_header;  * tradeclient_rfc822_output_body * The end result is that we wind up creating the message * within the framework of c-client. */intpost_rfc822_output( char *tmp, ENVELOPE *env, BODY *body, soutr_t f, TCPSTREAM *s ) {  return( tradeclient_rfc822_output( env, body, f, s ) ) ;}inttradeclient_rfc822_output( ENVELOPE *env, BODY *body, soutr_t f, TCPSTREAM *s ) {  int retval;  /* Encode the body and any body parts as needed */  tradeclient_encode_body( body ) ;  /* build and output RFC822 header, output body */  retval = tradeclient_rfc822_header( env, body, f, s ) &&    (body ? tradeclient_rfc822_output_body( body, f, s ) : 1 ) ;    return( retval ) ;}/* * This function is heavily influenced by PINE.  Then again, using * this model, it's hard to do it much different! */voidtradeclient_encode_body( BODY *body ) {  int p ;  PART *bp ;  time_t t ;  char tmp[4*1024] ;  /* See if we have a message body, if so, then we'll do out fancy body encoding */  if( body ) {    switch( body -> type ) {    case TYPEMULTIPART:      /*       * if we have a multipart message, create a unique message boundry and then       * attach the various body parts by walking through the list of nested parts.       */      t = time( NULL ) ;      p = getpid() ;      if( !body -> parameter ) {	/* This should always be less than our 4k buffer above! */	sprintf( tmp, "---TradeClientMIMEBOUNDRY---%ld-%ld-%ld=:%ld", 		 gethostid(), random()*t/p, t, (long)p ) ;	body -> parameter = mail_newbody_parameter();	body -> parameter -> attribute = cpystr( "BOUNDARY" ) ;	body -> parameter -> value = cpystr( tmp ) ;      }      /* Now, encode all of the body parts - nested parts, notice that we are recursive! */      bp = body -> nested.part ;      while( bp ) {	tradeclient_encode_body( &bp -> body ) ;	bp = bp -> next ;      }      break ;    default:      /*       * Like PINE, I don't think we have to do anything at this point because       * everything is either encoded as MIME (see above) else it's quoted       * printable?  Need to verify this.       */#if DEBUG > 4      printf( "Got a body type of %d when looking to MIME encode.\n", body -> type ) ;#endif      break ;    }  }  return ;}inttradeclient_rfc822_header( ENVELOPE *env, BODY *body, soutr_t f, TCPSTREAM *s ) {  return 0 ;}longtradeclient_rfc822_output_body( BODY *body, soutr_t f, TCPSTREAM *s ) {#if 0  PART *part ;  char *delim ;  PARAMETER *parm ;  char temp[MAILTMPLEN] ;#endif#if 0  if( body -> type == TYPEMULTIPART ) {    part = body -> nested.part ;    for( parm = body -> parameter ; parm ; parm = parm -> next )      if( ) ;    /*     * Output verbose text explaining this is MIME and what it is.     */    if( f && !(*f)( s, "This message has been encoding in MIME format.  If you are reading this,\015\012then your email client does not support this format.  As such, it is\015\012recommended that you contact your system administrator to find out how to\015\012obtain a MIME compliant email client or contact the message originator and\015\012request this email be resent in a format that is supported by your email client.\015\012\015\012" ) )      return 0 ;    do {      #endif  return 0L ;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -