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

📄 pop3.c

📁 Vovida 社区开源的 SIP 协议源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Program:	Post Office Protocol 3 (POP3) client routines * * Author:	Mark Crispin *		Networks and Distributed Computing *		Computing & Communications *		University of Washington *		Administration Building, AG-44 *		Seattle, WA  98195 *		Internet: MRC@CAC.Washington.EDU * * Date:	6 June 1994 * Last Edited:	13 October 2000 * * Copyright 2000 by the University of Washington * *  Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notices appear in all copies and that both the * above copyright notices and this permission notice appear in supporting * documentation, and that the name of the University of Washington not be * used in advertising or publicity pertaining to distribution of the software * without specific, written prior permission.  This software is made * available "as is", and * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */#include "mail.h"#include "osdep.h"#include <ctype.h>#include <stdio.h>#include <time.h>#include "pop3.h"#include "rfc822.h"#include "misc.h"#include "netmsg.h"#include "flstring.h"/* POP3 mail routines *//* Driver dispatch used by MAIL */DRIVER pop3driver = {  "pop3",			/* driver name */				/* driver flags */#ifdef INADEQUATE_MEMORY  DR_LOWMEM |#endif  DR_MAIL|DR_NOFAST|DR_CRLF|DR_NOSTICKY,  (DRIVER *) NIL,		/* next driver */  pop3_valid,			/* mailbox is valid for us */  pop3_parameters,		/* manipulate parameters */  pop3_scan,			/* scan mailboxes */  pop3_list,			/* find mailboxes */  pop3_lsub,			/* find subscribed mailboxes */  pop3_subscribe,		/* subscribe to mailbox */  pop3_unsubscribe,		/* unsubscribe from mailbox */  pop3_create,			/* create mailbox */  pop3_delete,			/* delete mailbox */  pop3_rename,			/* rename mailbox */  pop3_status,			/* status of mailbox */  pop3_open,			/* open mailbox */  pop3_close,			/* close mailbox */  pop3_fetchfast,		/* fetch message "fast" attributes */  NIL,				/* fetch message flags */  NIL,				/* fetch overview */  NIL,				/* fetch message structure */  pop3_header,			/* fetch message header */  pop3_text,			/* fetch message text */  NIL,				/* fetch message */  NIL,				/* unique identifier */  NIL,				/* message number from UID */  NIL,				/* modify flags */  NIL,				/* per-message modify flags */  NIL,				/* search for message based on criteria */  NIL,				/* sort messages */  NIL,				/* thread messages */  pop3_ping,			/* ping mailbox to see if still alive */  pop3_check,			/* check for new messages */  pop3_expunge,			/* expunge deleted messages */  pop3_copy,			/* copy messages to another mailbox */  pop3_append,			/* append string message to mailbox */  NIL				/* garbage collect stream */};				/* prototype stream */MAILSTREAM pop3proto = {&pop3driver};				/* driver parameters */static unsigned long pop3_maxlogintrials = MAXLOGINTRIALS;static long pop3_port = 0;static long pop3_altport = 0;static char *pop3_altname = NIL;/* POP3 mail validate mailbox * Accepts: mailbox name * Returns: our driver if name is valid, NIL otherwise */DRIVER *pop3_valid (char *name){  NETMBX mb;  char mbx[MAILTMPLEN];  return (mail_valid_net_parse (name,&mb) &&	  !strcmp (mb.service,pop3driver.name) && !mb.authuser[0] &&	  !strcmp (ucase (strcpy (mbx,mb.mailbox)),"INBOX")) ?	    &pop3driver : NIL;}/* News manipulate driver parameters * Accepts: function code *	    function-dependent value * Returns: function-dependent return value */void *pop3_parameters (long function,void *value){  switch ((int) function) {  case SET_MAXLOGINTRIALS:    pop3_maxlogintrials = (unsigned long) value;    break;  case GET_MAXLOGINTRIALS:    value = (void *) pop3_maxlogintrials;    break;  case SET_POP3PORT:    pop3_port = (long) value;    break;  case GET_POP3PORT:    value = (void *) pop3_port;    break;  case SET_ALTPOPPORT:    pop3_altport = (long) value;    break;  case GET_ALTPOPPORT:    value = (void *) pop3_altport;    break;  case SET_ALTPOPNAME:    pop3_altname = (char *) value;    break;  case GET_ALTPOPNAME:    value = (void *) pop3_altname;    break;  default:    value = NIL;		/* error case */    break;  }  return value;}/* POP3 mail scan mailboxes for string * Accepts: mail stream *	    reference *	    pattern to search *	    string to scan */void pop3_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents){  char tmp[MAILTMPLEN];  if ((ref && *ref) ?		/* have a reference */      (pop3_valid (ref) && pmatch ("INBOX",pat)) :      (mail_valid_net (pat,&pop3driver,NIL,tmp) && pmatch ("INBOX",tmp)))    mm_log ("Scan not valid for POP3 mailboxes",ERROR);}/* POP3 mail find list of all mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void pop3_list (MAILSTREAM *stream,char *ref,char *pat){  char tmp[MAILTMPLEN];  if (ref && *ref) {		/* have a reference */    if (pop3_valid (ref) && pmatch ("INBOX",pat)) {      strcpy (strchr (strcpy (tmp,ref),'}')+1,"INBOX");      mm_list (stream,NIL,tmp,LATT_NOINFERIORS);    }  }  else if (mail_valid_net (pat,&pop3driver,NIL,tmp) && pmatch ("INBOX",tmp)) {    strcpy (strchr (strcpy (tmp,pat),'}')+1,"INBOX");    mm_list (stream,NIL,tmp,LATT_NOINFERIORS);  }}/* POP3 mail find list of subscribed mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void pop3_lsub (MAILSTREAM *stream,char *ref,char *pat){  void *sdb = NIL;  char *s,mbx[MAILTMPLEN];  if (*pat == '{') {		/* if remote pattern, must be POP3 */    if (!pop3_valid (pat)) return;    ref = NIL;			/* good POP3 pattern, punt reference */  }				/* if remote reference, must be valid POP3 */  if (ref && (*ref == '{') && !pop3_valid (ref)) return;				/* kludgy application of reference */  if (ref && *ref) sprintf (mbx,"%s%s",ref,pat);  else strcpy (mbx,pat);  if (s = sm_read (&sdb)) do if (pop3_valid (s) && pmatch (s,mbx))    mm_lsub (stream,NIL,s,NIL);  while (s = sm_read (&sdb));	/* until no more subscriptions */}/* POP3 mail subscribe to mailbox * Accepts: mail stream *	    mailbox to add to subscription list * Returns: T on success, NIL on failure */long pop3_subscribe (MAILSTREAM *stream,char *mailbox){  return sm_subscribe (mailbox);}/* POP3 mail unsubscribe to mailbox * Accepts: mail stream *	    mailbox to delete from subscription list * Returns: T on success, NIL on failure */long pop3_unsubscribe (MAILSTREAM *stream,char *mailbox){  return sm_unsubscribe (mailbox);}/* POP3 mail create mailbox * Accepts: mail stream *	    mailbox name to create * Returns: T on success, NIL on failure */long pop3_create (MAILSTREAM *stream,char *mailbox){  return NIL;			/* never valid for POP3 */}/* POP3 mail delete mailbox *	    mailbox name to delete * Returns: T on success, NIL on failure */long pop3_delete (MAILSTREAM *stream,char *mailbox){  return NIL;			/* never valid for POP3 */}/* POP3 mail rename mailbox * Accepts: mail stream *	    old mailbox name *	    new mailbox name * Returns: T on success, NIL on failure */long pop3_rename (MAILSTREAM *stream,char *old,char *newname){  return NIL;			/* never valid for POP3 */}/* POP3 status * Accepts: mail stream *	    mailbox name *	    status flags * Returns: T on success, NIL on failure */long pop3_status (MAILSTREAM *stream,char *mbx,long flags){  MAILSTATUS status;  unsigned long i;  long ret = NIL;  MAILSTREAM *tstream =    (stream && LOCAL->netstream && mail_usable_network_stream (stream,mbx)) ?      stream : mail_open (NIL,mbx,OP_SILENT);  if (tstream) {		/* have a usable stream? */    status.flags = flags;	/* return status values */    status.messages = tstream->nmsgs;    status.recent = tstream->recent;    if (flags & SA_UNSEEN)	/* must search to get unseen messages */      for (i = 1,status.unseen = 0; i <= tstream->nmsgs; i++)	if (!mail_elt (tstream,i)->seen) status.unseen++;    status.uidnext = tstream->uid_last + 1;    status.uidvalidity = tstream->uid_validity;				/* pass status to main program */    mm_status (tstream,mbx,&status);    if (stream != tstream) mail_close (tstream);    ret = LONGT;  }  return ret;			/* success */}/* POP3 mail open * Accepts: stream to open * Returns: stream on success, NIL on failure */MAILSTREAM *pop3_open (MAILSTREAM *stream){  unsigned long i;  char tmp[MAILTMPLEN],usr[MAILTMPLEN];  NETMBX mb;  MESSAGECACHE *elt;				/* return prototype for OP_PROTOTYPE call */  if (!stream) return &pop3proto;  mail_valid_net_parse (stream->mailbox,&mb);  usr[0] = '\0';		/* initially no user name */  if (stream->local) fatal ("pop3 recycle stream");				/* /anonymous not supported */  if (mb.anoflag || stream->anonymous) {    mm_log ("Anonymous POP3 login not available",ERROR);    return NIL;  }				/* copy other switches */  if (mb.dbgflag) stream->debug = T;  if (mb.secflag) stream->secure = T;  mb.tryaltflag = stream->tryalt;  stream->local = fs_get (sizeof (POP3LOCAL));  stream->sequence++;		/* bump sequence number */  stream->perm_deleted = T;	/* deleted is only valid flag */  LOCAL->response = LOCAL->reply = NIL;				/* currently no message */  LOCAL->msgno = LOCAL->hdrsize = 0;  LOCAL->txt = NIL;		/* no file initially */  if ((LOCAL->netstream =	/* try to open connection */       net_open (&mb,NIL,pop3_port ? pop3_port : POP3TCPPORT,		 (NETDRIVER *) mail_parameters (NIL,GET_ALTDRIVER,NIL),		 (char *) mail_parameters (NIL,GET_ALTPOPNAME,NIL),		 (unsigned long) mail_parameters (NIL,GET_ALTPOPPORT,NIL))) &&      pop3_reply (stream)) {    mm_log (LOCAL->reply,NIL);	/* give greeting */    if (!pop3_auth (stream,&mb,tmp,usr)) pop3_close (stream,NIL);    else if (pop3_send (stream,"STAT",NIL)) {      int silent = stream->silent;      stream->silent = T;      sprintf (tmp,"{%.200s:%lu/pop3",net_host (LOCAL->netstream),	       net_port (LOCAL->netstream));      if (mb.altflag) sprintf (tmp + strlen (tmp),"/%.200s",(char *)			       mail_parameters (NIL,GET_ALTDRIVERNAME,NIL));      if (mb.altopt) sprintf (tmp + strlen (tmp),"/%.200s",(char *)			      mail_parameters (NIL,GET_ALTOPTIONNAME,NIL));      if (mb.secflag) strcat (tmp,"/secure");      sprintf (tmp + strlen (tmp),"/user=\"%s\"}%s",usr,mb.mailbox);      stream->inbox = T;	/* always INBOX */      fs_give ((void **) &stream->mailbox);      stream->mailbox = cpystr (tmp);				/* notify upper level */      mail_exists (stream,stream->uid_last = strtoul (LOCAL->reply,NIL,10));      mail_recent (stream,stream->nmsgs);				/* instantiate elt */      for (i = 0; i < stream->nmsgs;) {	elt = mail_elt (stream,++i);	elt->valid = elt->recent = T;	elt->private.uid = i;      }      stream->silent = silent;	/* notify main program */      mail_exists (stream,stream->nmsgs);				/* notify if empty */      if (!(stream->nmsgs || stream->silent)) mm_log ("Mailbox is empty",WARN);    }    else {			/* error in STAT */      mm_log (LOCAL->reply,ERROR);      pop3_close (stream,NIL);	/* too bad */    }  }  else {			/* connection failed */    if (LOCAL->reply) mm_log (LOCAL->reply,ERROR);    pop3_close (stream,NIL);	/* failed, clean up */  }  return LOCAL ? stream : NIL;	/* if stream is alive, return to caller */}/* POP3 authenticate * Accepts: stream to login *	    parsed network mailbox structure *	    scratch buffer *	    place to return user name * Returns: T on success, NIL on failure */long pop3_auth (MAILSTREAM *stream,NETMBX *mb,char *tmp,char *usr){  unsigned long i,trial,auths = 0;  char *t;  AUTHENTICATOR *at;  long flags = (stream->secure ? AU_SECURE : NIL) |    (mb->authuser[0] ? AU_AUTHUSER : NIL);				/* get list of authenticators */  if (pop3_send (stream,"AUTH",NIL)) {    while ((t = net_getline (LOCAL->netstream)) && (t[1] || (*t != '.'))) {      if (stream->debug) mm_dlog (t);      if ((i = mail_lookup_auth_name (t,flags)) &&	  (--i < (8*sizeof (unsigned long)))) auths |= (1 << i);      fs_give ((void **) &t);    }

⌨️ 快捷键说明

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