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

📄 imap4r1.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
    imapreferral_t ir;    aflg.type = FLAGS; aflg.text = (void *) tmp;    args[1] = &aflg; args[2] = NIL;    tmp[0] = tmp[1] = '\0';	/* build flag list */    if (flags & SA_MESSAGES) strcat (tmp," MESSAGES");    if (flags & SA_RECENT) strcat (tmp," RECENT");    if (flags & SA_UNSEEN) strcat (tmp," UNSEEN");    if (flags & SA_UIDNEXT) strcat (tmp," UIDNEXT");    if (flags & SA_UIDVALIDITY) strcat (tmp," UIDVALIDITY");    tmp[0] = '(';    strcat (tmp,")");				/* send "STATUS mailbox flag" */    if (imap_OK (stream,imap_send (stream,"STATUS",args))) ret = T;    else if ((ir = (imapreferral_t)	      mail_parameters (stream,GET_IMAPREFERRAL,NIL)) &&	     LOCAL->referral &&	     (mbx = (*ir) (stream,LOCAL->referral,REFSTATUS)))      ret = imap_status (NIL,mbx,flags | (stream->debug ? SA_DEBUG : NIL));  }				/* IMAP2 way */  else if (imap_OK (stream,imap_send (stream,"EXAMINE",args))) {    MAILSTATUS status;    status.flags = flags & ~ (SA_UIDNEXT | SA_UIDVALIDITY);    status.messages = stream->nmsgs;    status.recent = stream->recent;    status.unseen = 0;    if (flags & SA_UNSEEN) {	/* must search to get unseen messages */				/* clear search vector */      for (i = 1; i <= stream->nmsgs; ++i) mail_elt (stream,i)->searched = NIL;      if (imap_OK (stream,imap_send (stream,"SEARCH UNSEEN",NIL)))	for (i = 1,status.unseen = 0; i <= stream->nmsgs; i++)	  if (mail_elt (stream,i)->searched) status.unseen++;    }    strcpy (strchr (strcpy (tmp,stream->mailbox),'}') + 1,mb.mailbox);				/* pass status to main program */    mm_status (stream,tmp,&status);    ret = T;			/* note success */  }  if (tstream) mail_close (tstream);  return ret;			/* success */}/* IMAP open * Accepts: stream to open * Returns: stream to use on success, NIL on failure */MAILSTREAM *imap_open (MAILSTREAM *stream){  unsigned long i,j;  char *s,tmp[MAILTMPLEN],usr[MAILTMPLEN];  NETMBX mb;  IMAPPARSEDREPLY *reply = NIL;  imapreferral_t ir =    (imapreferral_t) mail_parameters (stream,GET_IMAPREFERRAL,NIL);				/* return prototype for OP_PROTOTYPE call */  if (!stream) return &imapproto;  mail_valid_net_parse (stream->mailbox,&mb);  usr[0] = '\0';		/* initially no user name */  if (LOCAL) {			/* if stream opened earlier by us */				/* recycle if still alive */    if (LOCAL->netstream && (!stream->halfopen || LOCAL->cap.unselect)) {      i = stream->silent;	/* temporarily mark silent */      stream->silent = T;	/* don't give mm_exists() events */      j = imap_ping (stream);	/* learn if stream still alive */      stream->silent = i;	/* restore prior state */      if (j) {			/* was stream still alive? */	sprintf (tmp,"Reusing connection to %s",net_host (LOCAL->netstream));	if (LOCAL->user) sprintf (tmp + strlen (tmp),"/user=\"%s\"",				  LOCAL->user);	if (!stream->silent) mm_log (tmp,(long) NIL);				/* unselect if now want halfopen */	if (stream->halfopen) imap_send (stream,"UNSELECT",NIL);      }      else imap_close (stream,NIL);    }    else imap_close (stream,NIL);  }				/* copy flags from name */  if (mb.dbgflag) stream->debug = T;  if (mb.readonlyflag) stream->rdonly = T;  if (mb.anoflag) stream->anonymous = T;  if (mb.secflag) stream->secure = T;  if (mb.trysslflag || imap_tryssl) stream->tryssl = T;  if (!LOCAL) {			/* open new connection if no recycle */    NETDRIVER *ssld = (NETDRIVER *) mail_parameters (NIL,GET_SSLDRIVER,NIL);    unsigned long defprt = imap_defaultport ? imap_defaultport : IMAPTCPPORT;    unsigned long sslport = imap_sslport ? imap_sslport : IMAPSSLPORT;    stream->local =		/* instantiate localdata */      (void *) memset (fs_get (sizeof (IMAPLOCAL)),0,sizeof (IMAPLOCAL));				/* assume IMAP2bis server */    LOCAL->cap.imap2bis = LOCAL->cap.rfc1176 = T;				/* in case server is a loser */    if (mb.loser) LOCAL->loser = T;				/* desirable authenticators */    LOCAL->authflags = (stream->secure ? AU_SECURE : NIL) |      (mb.authuser[0] ? AU_AUTHUSER : NIL);    /* IMAP connection open logic is more complex than net_open() normally     * deals with, because of the simap and rimap hacks.     * If the session is anonymous, a specific port is given, or if /ssl or     * /tls is set, do net_open() since those conditions override everything     * else.     */    if (stream->anonymous || mb.port || mb.sslflag || mb.tlsflag)      reply = (LOCAL->netstream = net_open (&mb,NIL,defprt,ssld,"*imaps",					    sslport)) ?	imap_reply (stream,NIL) : NIL;    /*      * No overriding conditions, so get the best connection that we can.  In     * order, attempt to open via simap, tryssl, rimap, and finally TCP.     */				/* try simap */    else if (reply = imap_rimap (stream,"*imap",&mb,usr,tmp));    else if (ssld &&		/* try tryssl if enabled */	     (stream->tryssl || mail_parameters (NIL,GET_TRYSSLFIRST,NIL)) &&	     (LOCAL->netstream =	      net_open_work (ssld,mb.host,"*imaps",sslport,mb.port,			     (mb.novalidate ? NET_NOVALIDATECERT : 0) |			     NET_SILENT | NET_TRYSSL))) {      if (net_sout (LOCAL->netstream,"",0)) {	mb.sslflag = T;	reply = imap_reply (stream,NIL);      }      else {			/* flush fake SSL stream */	net_close (LOCAL->netstream);	LOCAL->netstream = NIL;      }    }				/* try rimap first, then TCP */    else if (!(reply = imap_rimap (stream,"imap",&mb,usr,tmp)) &&	     (LOCAL->netstream = net_open (&mb,NIL,defprt,NIL,NIL,NIL)))      reply = imap_reply (stream,NIL);				/* make sure greeting is good */    if (!reply || strcmp (reply->tag,"*") ||	(strcmp (reply->key,"OK") && strcmp (reply->key,"PREAUTH"))) {      if (reply) mm_log (reply->text,ERROR);      return NIL;		/* lost during greeting */    }				/* if connected and not preauthenticated */    if (LOCAL->netstream && strcmp (reply->key,"PREAUTH")) {      sslstart_t stls = (sslstart_t) mail_parameters (NIL,GET_SSLSTART,NIL);				/* get server capabilities */      if (!LOCAL->gotcapability) imap_capability (stream);      if (LOCAL->netstream &&	/* does server support STARTTLS? */	  stls && LOCAL->cap.starttls && !mb.sslflag && !mb.notlsflag &&	  imap_OK (stream,imap_send (stream,"STARTTLS",NIL))) {	mb.tlsflag = T;		/* TLS OK, get into TLS at this end */	LOCAL->netstream->dtb = ssld;	if (!(LOCAL->netstream->stream =	      (*stls) (LOCAL->netstream->stream,mb.host,		       (mb.tlssslv23 ? NIL : NET_TLSCLIENT) |		       (mb.novalidate ? NET_NOVALIDATECERT : NIL)))) {				/* drat, drop this connection */	  if (LOCAL->netstream) net_close (LOCAL->netstream);	  LOCAL->netstream = NIL;	}				/* get capabilities now that TLS in effect */	if (LOCAL->netstream) imap_capability (stream);      }      else if (mb.tlsflag) {	/* user specified /tls but can't do it */	mm_log ("Unable to negotiate TLS with this server",ERROR);	return NIL;      }      if (LOCAL->netstream) {	/* still in the land of the living? */	if ((long) mail_parameters (NIL,GET_TRUSTDNS,NIL)) {				/* remote name for authentication */	  strncpy (mb.host,(long) mail_parameters(NIL,GET_SASLUSESPTRNAME,NIL)?		   net_remotehost (LOCAL->netstream) :		   net_host (LOCAL->netstream),NETMAXHOST-1);	  mb.host[NETMAXHOST-1] = '\0';	}				/* need new capabilities after login */	LOCAL->gotcapability = NIL;	if (!(stream->anonymous ? imap_anon (stream,tmp) :	      (LOCAL->cap.auth ? imap_auth (stream,&mb,tmp,usr) :	       imap_login (stream,&mb,tmp,usr)))) {				/* failed, is there a referral? */	  if (ir && LOCAL->referral &&	      (s = (*ir) (stream,LOCAL->referral,REFAUTHFAILED))) {	    imap_close (stream,NIL);	    fs_give ((void **) &stream->mailbox);				/* set as new mailbox name to open */	    stream->mailbox = s;	    return imap_open (stream);	  }	  return NIL;		/* authentication failed */	}	else if (ir && LOCAL->referral &&		 (s = (*ir) (stream,LOCAL->referral,REFAUTH))) {	  imap_close (stream,NIL);	  fs_give ((void **) &stream->mailbox);	  stream->mailbox = s;	/* set as new mailbox name to open */				/* recurse to log in on real site */	  return imap_open (stream);	}      }    }				/* get server capabilities again */    if (LOCAL->netstream && !LOCAL->gotcapability) imap_capability (stream);				/* save state for future recycling */    if (mb.tlsflag) LOCAL->tlsflag = T;    if (mb.tlssslv23) LOCAL->tlssslv23 = T;    if (mb.notlsflag) LOCAL->notlsflag = T;    if (mb.sslflag) LOCAL->sslflag = T;    if (mb.novalidate) LOCAL->novalidate = T;    if (mb.loser) LOCAL->loser = T;  }  if (LOCAL->netstream) {	/* still have a connection? */    stream->perm_seen = stream->perm_deleted = stream->perm_answered =      stream->perm_draft = LEVELIMAP4 (stream) ? NIL : T;    stream->perm_user_flags = LEVELIMAP4 (stream) ? NIL : 0xffffffff;    stream->sequence++;		/* bump sequence number */    sprintf (tmp,"{%s",(long) mail_parameters (NIL,GET_TRUSTDNS,NIL) ?	     net_host (LOCAL->netstream) : mb.host);    if (!((i = net_port (LOCAL->netstream)) & 0xffff0000))      sprintf (tmp + strlen (tmp),":%lu",i);    strcat (tmp,"/imap");    if (LOCAL->tlsflag) strcat (tmp,"/tls");    if (LOCAL->tlssslv23) strcat (tmp,"/tls-sslv23");    if (LOCAL->notlsflag) strcat (tmp,"/notls");    if (LOCAL->sslflag) strcat (tmp,"/ssl");    if (LOCAL->novalidate) strcat (tmp,"/novalidate-cert");    if (LOCAL->loser) strcat (tmp,"/loser");    if (stream->secure) strcat (tmp,"/secure");    if (stream->rdonly) strcat (tmp,"/readonly");    if (stream->anonymous) strcat (tmp,"/anonymous");    else {			/* record user name */      if (!LOCAL->user && usr[0]) LOCAL->user = cpystr (usr);      if (LOCAL->user) sprintf (tmp + strlen (tmp),"/user=\"%s\"",				LOCAL->user);    }    strcat (tmp,"}");    if (!stream->halfopen) {	/* wants to open a mailbox? */      IMAPARG *args[2];      IMAPARG ambx;      ambx.type = ASTRING;      ambx.text = (void *) mb.mailbox;      args[0] = &ambx; args[1] = NIL;      stream->nmsgs = 0;      if (imap_OK (stream,reply = imap_send (stream,stream->rdonly ?					     "EXAMINE": "SELECT",args))) {	strcat (tmp,mb.mailbox);/* mailbox name */	if (!stream->nmsgs && !stream->silent)	  mm_log ("Mailbox is empty",(long) NIL);				/* note if an INBOX or not */	stream->inbox = !compare_cstring (mb.mailbox,"INBOX");      }      else if (ir && LOCAL->referral &&	       (s = (*ir) (stream,LOCAL->referral,REFSELECT))) {	imap_close (stream,NIL);	fs_give ((void **) &stream->mailbox);	stream->mailbox = s;	/* set as new mailbox name to open */	return imap_open (stream);      }      else {	mm_log (reply->text,ERROR);	if (imap_closeonerror) return NIL;	stream->halfopen = T;	/* let him keep it half-open */      }    }    if (stream->halfopen) {	/* half-open connection? */      strcat (tmp,"<no_mailbox>");				/* make sure dummy message counts */      mail_exists (stream,(long) 0);      mail_recent (stream,(long) 0);    }    fs_give ((void **) &stream->mailbox);    stream->mailbox = cpystr (tmp);  }				/* success if stream open */  return LOCAL->netstream ? stream : NIL;}/* IMAP rimap connect * Accepts: MAIL stream *	    NETMBX specification *	    service to use *	    user name *	    scratch buffer * Returns: parsed reply if success, else NIL */IMAPPARSEDREPLY *imap_rimap (MAILSTREAM *stream,char *service,NETMBX *mb,			     char *usr,char *tmp){  unsigned long i;  char c[2];  NETSTREAM *tstream;  IMAPPARSEDREPLY *reply = NIL;				/* try rimap open */  if (!mb->norsh && (tstream = net_aopen (NIL,mb,service,usr))) {				/* if success, see if reasonable banner */    if (net_getbuffer (tstream,(long) 1,c) && (*c == '*')) {      i = 0;			/* copy to buffer */      do tmp[i++] = *c;      while (net_getbuffer (tstream,(long) 1,c) && (*c != '\015') &&	     (*c != '\012') && (i < (MAILTMPLEN-1)));      tmp[i] = '\0';		/* tie off */				/* snarfed a valid greeting? */      if ((*c == '\015') && net_getbuffer (tstream,(long) 1,c) &&	  (*c == '\012') &&	  !strcmp ((reply = imap_parse_reply (stream,cpystr (tmp)))->tag,"*")){				/* parse line as IMAP */	imap_parse_unsolicited (stream,reply);				/* make sure greeting is good */	if (!strcmp (reply->key,"OK") || !strcmp (reply->key,"PREAUTH")) {	  LOCAL->netstream = tstream;	  return reply;		/* return success */	}      }    }    net_close (tstream);	/* failed, punt the temporary netstream */  }  return NIL;}/* IMAP log in as anonymous * Accepts: stream to authenticate *	    scratch buffer * Returns: T on success, NIL on failure */long imap_anon (MAILSTREAM *stream,char *tmp){  IMAPPARSEDREPLY *reply;  char *s = net_localhost (LOCAL->netstream);  if (LOCAL->cap.authanon) {    char tag[16];    unsigned long i;    char *broken = "[CLOSED] IMAP connection broken (anonymous auth)";    sprintf (tag,"%08lx",0xffffffff & (stream->gensym++));				/* build command */    sprintf (tmp,"%s AUTHENTICATE ANONYMOUS",tag);    if (!imap_soutr (stream,tmp)) {      mm_log (broken,ERROR);      return NIL;    }    if (imap_challenge (stream,&i)) imap_response (stream,s,strlen (s));				/* get response */    if (!(reply = &LOCAL->reply)->tag) reply = imap_fake (stream,tag,broken);				/* what we wanted? */    if (compare_cstring (reply->tag,tag)) {				/* abort if don't have tagged response */      while (compare_cstring ((reply = imap_reply (stream,tag))->tag,tag))	imap_soutr (stream,"*");    }  }  else {    IMAPARG *args[2];    IMAPARG ausr;    ausr.type = ASTRING;    ausr.text = (void *) s;    args[0] = &ausr; args[1] = NIL;				/* send "LOGIN anonymous <host>" */    reply = imap_send (stream,"LOGIN ANONYMOUS",args);  }				/* success if reply OK */  if (imap_OK (stream,reply)) return T;  mm_log (reply->text,ERROR);  return NIL;}

⌨️ 快捷键说明

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