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

📄 pop3.c

📁 Vovida 社区开源的 SIP 协议源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (t) {			/* flush end of text indicator */      if (stream->debug) mm_dlog (t);      fs_give ((void **) &t);    }  }  if (auths) {			/* got any authenticators? */    for (t = NIL; LOCAL->netstream && auths &&	 (at = mail_lookup_auth (find_rightmost_bit (&auths)+1)); ) {      if (t) {			/* previous authenticator failed? */	sprintf (tmp,"Retrying using %.80s authentication after %.80s",		 at->name,t);	mm_log (tmp,NIL);	fs_give ((void **) &t);      }      trial = 0;		/* initial trial count */      tmp[0] = '\0';		/* empty buffer */      if (LOCAL->netstream) do {	if (tmp[0]) mm_log (tmp,WARN);	if (pop3_send (stream,"AUTH",at->name) &&	    (*at->client) (pop3_challenge,pop3_response,mb,stream,&trial,usr)&&	    LOCAL->response) {	  if (*LOCAL->response == '+') return LONGT;	  if (!trial) {		/* if main program requested cancellation */	    mm_log ("POP3 Authentication cancelled",ERROR);	    return NIL;	  }	}	t = cpystr (LOCAL->reply);	sprintf (tmp,"Retrying %s authentication after %s",at->name,t);      } while (LOCAL->netstream && trial && (trial < pop3_maxlogintrials));    }    if (t) {			/* previous authenticator failed? */      sprintf (tmp,"Can not authenticate to POP3 server: %.80s",t);      mm_log (tmp,ERROR);      fs_give ((void **) &t);    }  }  else if (stream->secure)    mm_log ("Can't do secure authentication with this server",ERROR);  else if (mb->authuser[0])    mm_log ("Can't do /authuser with this server",ERROR);  else {			/* traditional login */    for (i = 0; LOCAL->netstream && (i < pop3_maxlogintrials); ++i) {      tmp[0] = '\0';		/* prompt user for password */      mm_login (mb,usr,tmp,i);      if (tmp[0]) {		/* send login sequence */	if (pop3_send (stream,"USER",usr) && pop3_send (stream,"PASS",tmp))	  return LONGT;		/* success */	mm_log (LOCAL->reply,WARN);      }      else {			/* user refused to give a password */	mm_log ("Login aborted",ERROR);	return NIL;      }    }    mm_log ("Too many login failures",ERROR);  }  return NIL;			/* ran out of authenticators */}/* Get challenge to authenticator in binary * Accepts: stream *	    pointer to returned size * Returns: challenge or NIL if not challenge */void *pop3_challenge (void *s,unsigned long *len){  MAILSTREAM *stream = (MAILSTREAM *) s;  return ((*LOCAL->response == '+') && (LOCAL->response[1] == ' ')) ?    rfc822_base64 ((unsigned char *) LOCAL->reply,strlen (LOCAL->reply),len) :      NIL;}/* Send authenticator response in BASE64 * Accepts: MAIL stream *	    string to send *	    length of string * Returns: T if successful, else NIL */long pop3_response (void *s,char *response,unsigned long size){  MAILSTREAM *stream = (MAILSTREAM *) s;  unsigned long i,j,ret;  char *t,*u;  if (response) {		/* make CRLFless BASE64 string */    if (size) {      for (t = (char *) rfc822_binary ((void *) response,size,&i),u = t,j = 0;	   j < i; j++) if (t[j] > ' ') *u++ = t[j];      *u = '\0';		/* tie off string for mm_dlog() */      if (stream->debug) mm_dlog (t);				/* append CRLF */      *u++ = '\015'; *u++ = '\012'; *u = '\0';      ret = net_sout (LOCAL->netstream,t,u - t);      fs_give ((void **) &t);    }    else ret = net_sout (LOCAL->netstream,"\015\012",2);  }				/* abort requested */  else ret = net_sout (LOCAL->netstream,"*\015\012",3);				/* get response */  if (!pop3_reply (stream)) ret = NIL;  return ret;}/* POP3 mail close * Accepts: MAIL stream *	    option flags */void pop3_close (MAILSTREAM *stream,long options){  int silent = stream->silent;  if (LOCAL) {			/* only if a file is open */    if (LOCAL->netstream) {	/* close POP3 connection */      stream->silent = T;      if (options & CL_EXPUNGE) pop3_expunge (stream);      stream->silent = silent;      pop3_send (stream,"QUIT",NIL);      mm_notify (stream,LOCAL->reply,BYE);    }				/* close POP3 connection */    if (LOCAL->netstream) net_close (LOCAL->netstream);    if (LOCAL->txt) fclose (LOCAL->txt);    LOCAL->txt = NIL;    if (LOCAL->response) fs_give ((void **) &LOCAL->response);				/* nuke the local data */    fs_give ((void **) &stream->local);    stream->dtb = NIL;		/* log out the DTB */  }}/* POP3 mail fetch fast information * Accepts: MAIL stream *	    sequence *	    option flags * This is ugly and slow */void pop3_fetchfast (MAILSTREAM *stream,char *sequence,long flags){  unsigned long i;  MESSAGECACHE *elt;				/* get sequence */  if (stream && LOCAL && ((flags & FT_UID) ?			  mail_uid_sequence (stream,sequence) :			  mail_sequence (stream,sequence)))    for (i = 1; i <= stream->nmsgs; i++)      if ((elt = mail_elt (stream,i))->sequence &&	  !(elt->day && !elt->rfc822_size)) {	ENVELOPE **env = NIL;	ENVELOPE *e = NIL;	if (!stream->scache) env = &elt->private.msg.env;	else if (stream->msgno == i) env = &stream->env;	else env = &e;	if (!*env || !elt->rfc822_size) {	  STRING bs;	  unsigned long hs;	  char *ht = (*stream->dtb->header) (stream,i,&hs,NIL);				/* need to make an envelope? */	  if (!*env) rfc822_parse_msg (env,NIL,ht,hs,NIL,BADHOST,				       stream->dtb->flags);				/* need message size too, ugh */	  if (!elt->rfc822_size) {	    (*stream->dtb->text) (stream,i,&bs,FT_PEEK);	    elt->rfc822_size = hs + SIZE (&bs) - GETPOS (&bs);	  }	}				/* if need date, have date in envelope? */	if (!elt->day && *env && (*env)->date)	  mail_parse_date (elt,(*env)->date);				/* sigh, fill in bogus default */	if (!elt->day) mail_parse_date (elt,"01-JAN-1969 00:00:00 +0000");	mail_free_envelope (&e);      }}/* POP3 fetch header as text * Accepts: mail stream *	    message number *	    pointer to return size *	    flags * Returns: header text */char *pop3_header (MAILSTREAM *stream,unsigned long msgno,unsigned long *size,		   long flags){  MESSAGECACHE *elt;  if ((flags & FT_UID) && !(msgno = mail_msgno (stream,msgno))) return NIL;				/* have header text? */  if (!(elt = mail_elt (stream,msgno))->private.msg.header.text.data) {    elt->private.msg.header.text.size = pop3_cache (stream,elt);				/* read the header */    fread (elt->private.msg.header.text.data = (unsigned char *)	   fs_get ((size_t) elt->private.msg.header.text.size + 1),	   (size_t) 1,(size_t) elt->private.msg.header.text.size,LOCAL->txt);    elt->private.msg.header.text.data[elt->private.msg.header.text.size] ='\0';  }				/* return size of text */  if (size) *size = elt->private.msg.header.text.size;  return (char *) elt->private.msg.header.text.data;}/* POP3 fetch body * Accepts: mail stream *	    message number *	    pointer to stringstruct to initialize *	    flags * Returns: T if successful, else NIL */long pop3_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags){  MESSAGECACHE *elt;  INIT (bs,mail_string,(void *) "",0);  if ((flags & FT_UID) && !(msgno = mail_msgno (stream,msgno))) return NIL;  elt = mail_elt (stream,msgno);  pop3_cache (stream,elt);	/* make sure cache loaded */  if (!LOCAL->txt) return NIL;	/* error if don't have a file */  if (!(flags & FT_PEEK)) {	/* mark seen if needed */    elt->seen = T;    mm_flags (stream,elt->msgno);  }  INIT (bs,file_string,(void *) LOCAL->txt,elt->rfc822_size);  SETPOS (bs,LOCAL->hdrsize);	/* skip past header */  return T;}/* POP3 cache message * Accepts: mail stream *	    message number * Returns: header size */unsigned long pop3_cache (MAILSTREAM *stream,MESSAGECACHE *elt){				/* already cached? */  if (LOCAL->msgno != elt->msgno) {				/* no, close current file */    if (LOCAL->txt) fclose (LOCAL->txt);    LOCAL->txt = NIL;    LOCAL->msgno = LOCAL->hdrsize = 0;    if (pop3_send_num (stream,"RETR",elt->msgno)) {      LOCAL->msgno = elt->msgno;/* set as current message number */				/* load the cache */      LOCAL->txt = netmsg_slurp (LOCAL->netstream,&elt->rfc822_size,				 &LOCAL->hdrsize);    }    else elt->deleted = T;  }  return LOCAL->hdrsize;}/* POP3 mail ping mailbox * Accepts: MAIL stream * Returns: T if stream alive, else NIL */long pop3_ping (MAILSTREAM *stream){  return pop3_send (stream,"NOOP",NIL);}/* POP3 mail check mailbox * Accepts: MAIL stream */void pop3_check (MAILSTREAM *stream){  if (pop3_ping (stream)) mm_log ("Check completed",NIL);}/* POP3 mail expunge mailbox * Accepts: MAIL stream */void pop3_expunge (MAILSTREAM *stream){  char tmp[MAILTMPLEN];  unsigned long i = 1,n = 0;  while (i <= stream->nmsgs) {    if (mail_elt (stream,i)->deleted && pop3_send_num (stream,"DELE",i)) {      mail_expunged (stream,i);      n++;    }    else i++;			/* try next message */  }  if (!stream->silent) {	/* only if not silent */    if (n) {			/* did we expunge anything? */      sprintf (tmp,"Expunged %lu messages",n);      mm_log (tmp,(long) NIL);    }    else mm_log ("No messages deleted, so no update needed",(long) NIL);  }}/* POP3 mail copy message(s) * Accepts: MAIL stream *	    sequence *	    destination mailbox *	    option flags * Returns: T if copy successful, else NIL */long pop3_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options){  mailproxycopy_t pc =    (mailproxycopy_t) mail_parameters (stream,GET_MAILPROXYCOPY,NIL);  if (pc) return (*pc) (stream,sequence,mailbox,options);  mm_log ("Copy not valid for POP3",ERROR);  return NIL;}/* POP3 mail append message from stringstruct * Accepts: MAIL stream *	    destination mailbox *	    append callback *	    data for callback * Returns: T if append successful, else NIL */long pop3_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data){  mm_log ("Append not valid for POP3",ERROR);  return NIL;}/* Internal routines *//* Post Office Protocol 3 send command with number argument * Accepts: MAIL stream *	    command *	    number * Returns: T if successful, NIL if failure */long pop3_send_num (MAILSTREAM *stream,char *command,unsigned long n){  char tmp[MAILTMPLEN];  sprintf (tmp,"%lu",mail_uid (stream,n));  return pop3_send (stream,command,tmp);}/* Post Office Protocol 3 send command * Accepts: MAIL stream *	    command *	    command argument * Returns: T if successful, NIL if failure */long pop3_send (MAILSTREAM *stream,char *command,char *args){  long ret;  char *s = (char *) fs_get (strlen (command) + (args ? strlen (args) + 1: 0)			     + 3);  mail_lock (stream);		/* lock up the stream */  if (!LOCAL->netstream) ret = pop3_fake (stream,"No-op dead stream");  else {			/* build the complete command */    if (args) sprintf (s,"%s %s",command,args);    else strcpy (s,command);    if (stream->debug) mm_dlog (s);    strcat (s,"\015\012");				/* send the command */    ret = net_soutr (LOCAL->netstream,s) ? pop3_reply (stream) :      pop3_fake (stream,"POP3 connection broken in command");  }  fs_give ((void **) &s);  mail_unlock (stream);		/* unlock stream */  return ret;}/* Post Office Protocol 3 get reply * Accepts: MAIL stream * Returns: T if success reply, NIL if error reply */long pop3_reply (MAILSTREAM *stream){  char *s;				/* flush old reply */  if (LOCAL->response) fs_give ((void **) &LOCAL->response);  				/* get reply */  if (!(LOCAL->response = net_getline (LOCAL->netstream)))    return pop3_fake (stream,"POP3 connection broken in response");  if (stream->debug) mm_dlog (LOCAL->response);  LOCAL->reply = (s = strchr (LOCAL->response,' ')) ? s + 1 : LOCAL->response;				/* return success or failure */  return (*LOCAL->response =='+') ? T : NIL;}/* Post Office Protocol 3 set fake error * Accepts: MAIL stream *	    error text * Returns: NIL, always */long pop3_fake (MAILSTREAM *stream,char *text){  mm_notify (stream,text,BYE);	/* send bye alert */  if (LOCAL->netstream) net_close (LOCAL->netstream);  LOCAL->netstream = NIL;	/* farewell, dear TCP stream */				/* flush any old reply */  if (LOCAL->response) fs_give ((void **) &LOCAL->response);  LOCAL->reply = text;		/* set up pseudo-reply string */  return NIL;			/* return error code */}

⌨️ 快捷键说明

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