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

📄 imap4r1.c

📁 SIP 1.5.0源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Accepts: mail stream *	    mailbox to delete from manage list * Returns: T on success, NIL on failure */long imap_unsubscribe (MAILSTREAM *stream,char *mailbox){  MAILSTREAM *st = stream;  long ret = ((stream && LOCAL && LOCAL->netstream) ||	      (stream = mail_open (NIL,mailbox,OP_HALFOPEN|OP_SILENT))) ?		imap_manage (stream,mailbox,LEVELIMAP4 (stream) ?			     "Unsubscribe" : "Unsubscribe Mailbox",NIL) : NIL;				/* toss out temporary stream */  if (st != stream) mail_close (stream);  return ret;}/* IMAP create mailbox * Accepts: mail stream *	    mailbox name to create * Returns: T on success, NIL on failure */long imap_create (MAILSTREAM *stream,char *mailbox){  return imap_manage (stream,mailbox,"Create",NIL);}/* IMAP delete mailbox * Accepts: mail stream *	    mailbox name to delete * Returns: T on success, NIL on failure */long imap_delete (MAILSTREAM *stream,char *mailbox){  return imap_manage (stream,mailbox,"Delete",NIL);}/* IMAP rename mailbox * Accepts: mail stream *	    old mailbox name *	    new mailbox name * Returns: T on success, NIL on failure */long imap_rename (MAILSTREAM *stream,char *old,char *newname){  return imap_manage (stream,old,"Rename",newname);}/* IMAP manage a mailbox * Accepts: mail stream *	    mailbox to manipulate *	    command to execute *	    optional second argument * Returns: T on success, NIL on failure */long imap_manage (MAILSTREAM *stream,char *mailbox,char *command,char *arg2){  MAILSTREAM *st = stream;  IMAPPARSEDREPLY *reply;  long ret = NIL;  char mbx[MAILTMPLEN],mbx2[MAILTMPLEN];  IMAPARG *args[3],ambx,amb2;  imapreferral_t ir =    (imapreferral_t) mail_parameters (stream,GET_IMAPREFERRAL,NIL);  ambx.type = amb2.type = ASTRING; ambx.text = (void *) mbx;  amb2.text = (void *) mbx2;  args[0] = &ambx; args[1] = args[2] = NIL;				/* require valid names and open stream */  if (mail_valid_net (mailbox,&imapdriver,NIL,mbx) &&      (arg2 ? mail_valid_net (arg2,&imapdriver,NIL,mbx2) : &imapdriver) &&      ((stream && LOCAL && LOCAL->netstream) ||       (stream = mail_open (NIL,mailbox,OP_HALFOPEN|OP_SILENT)))) {    if (arg2) args[1] = &amb2;	/* second arg present? */    if (!(ret = (imap_OK (stream,reply = imap_send (stream,command,args)))) &&	ir && LOCAL->referral) {      long code = -1;      switch (*command) {	/* which command was it? */      case 'S': code = REFSUBSCRIBE; break;      case 'U': code = REFUNSUBSCRIBE; break;      case 'C': code = REFCREATE; break;      case 'D': code = REFDELETE; break;      case 'R': code = REFRENAME; break;      default:	fatal ("impossible referral command");      }      if ((code >= 0) && (mailbox = (*ir) (stream,LOCAL->referral,code)))	ret = imap_manage (NIL,mailbox,command,(*command == 'R') ?			   (mailbox + strlen (mailbox) + 1) : NIL);    }    mm_log (reply->text,ret ? NIL : ERROR);				/* toss out temporary stream */    if (st != stream) mail_close (stream);  }  return ret;}/* IMAP status * Accepts: mail stream *	    mailbox name *	    status flags * Returns: T on success, NIL on failure */long imap_status (MAILSTREAM *stream,char *mbx,long flags){  IMAPARG *args[3],ambx,aflg;  char tmp[MAILTMPLEN];  NETMBX mb;  unsigned long i;  long ret = NIL;  MAILSTREAM *tstream = stream;  imapreferral_t ir =    (imapreferral_t) mail_parameters (stream,GET_IMAPREFERRAL,NIL);  mail_valid_net_parse (mbx,&mb);				/* can't use stream if not IMAP4rev1, STATUS,				   or halfopen and right host */  if (stream && (!(LEVELSTATUS (stream) || stream->halfopen)		 || strcmp (ucase (strcpy (tmp,imap_host (stream))),			    ucase (mb.host))))    return imap_status (NIL,mbx,flags);				/* make stream if don't have one */  if (!(stream || (stream = mail_open (NIL,mbx,OP_HALFOPEN|OP_SILENT))))    return NIL;  args[0] = &ambx;args[1] = NIL;/* set up first argument as mailbox */  ambx.type = ASTRING; ambx.text = (void *) mb.mailbox;  if (LEVELSTATUS (stream)) {	/* have STATUS command? */    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,LEVELIMAP4rev1 (stream) ?				    " UIDNEXT" : " UID-NEXT");    if (flags & SA_UIDVALIDITY) strcat (tmp,LEVELIMAP4rev1 (stream) ?					" UIDVALIDITY" : " UID-VALIDITY");    tmp[0] = '(';    strcat (tmp,")");				/* send "STATUS mailbox flag" */    if (imap_OK (stream,imap_send (stream,"STATUS",args))) ret = T;    else if (ir && LOCAL->referral &&	     (mbx = (*ir) (stream,LOCAL->referral,REFSTATUS)))      ret = imap_status (NIL,mbx,flags);  }				/* 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 (stream != tstream) mail_close (stream);  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 */    if (LOCAL->netstream) {	/* recycle if still alive */      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",imap_host (stream));	if (LOCAL->user) sprintf (tmp + strlen (tmp),"/user=\"%s\"",				  LOCAL->user);	if (!stream->silent) mm_log (tmp,(long) NIL);      }      else imap_close (stream,NIL);    }    else imap_close (stream,NIL);  }				/* copy flags from name */  if (mb.dbgflag) stream->debug = T;  if (mb.anoflag) stream->anonymous = T;  if (mb.secflag) stream->secure = T;  mb.tryaltflag = stream->tryalt;  if (!LOCAL) {			/* open new connection if no recycle */    NETDRIVER *altd = (NETDRIVER *) mail_parameters (NIL,GET_ALTDRIVER,NIL);    char * alts = (char *) mail_parameters(NIL,GET_ALTIMAPNAME,NIL);    unsigned long altp =      (unsigned long) mail_parameters (NIL,GET_ALTIMAPPORT,NIL);    unsigned long defprt = imap_defaultport ? imap_defaultport : IMAPTCPPORT;    stream->local =		/* instantiate localdata */      (void *) memset (fs_get (sizeof (IMAPLOCAL)),0,sizeof (IMAPLOCAL));				/* assume IMAP2bis server */    LOCAL->imap2bis = LOCAL->rfc1176 = T;    /* 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 alt is     * set, do net_open() since those conditions override everything else.     */    if (stream->anonymous || mb.port || mb.altflag)      reply = (LOCAL->netstream = net_open (&mb,NIL,defprt,altd,alts,altp)) ?	imap_reply (stream,NIL) : NIL;    /*      * No overriding conditions, so get the best connection that we can.  In     * order, attempt to open via simap, tryalt, rimap, and finally TCP.     */				/* try simap */    else if (reply = imap_rimap (stream,"*imap",&mb,usr,tmp));    else if (altd &&		/* try tryalt if enabled */	     (mb.tryaltflag || mail_parameters (NIL,GET_TRYALTFIRST,NIL)) &&	     (LOCAL->netstream =	      net_open_work (altd,mb.host,alts,altp,mb.port,			     NET_SILENT | (mb.altopt ? NET_ALTOPT : 0))) &&	     (reply = imap_reply (stream,NIL))) mb.altflag = T;				/* no alt, 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);				/* if have a connection */    if (LOCAL->netstream && reply && imap_OK (stream,reply)) {				/* if not preauthenticated */      if (strcmp (reply->key,"PREAUTH")) {	LOCAL->authflags = (stream->secure ? AU_SECURE : NIL) |	  (mb.authuser[0] ? AU_AUTHUSER : NIL);				/* get server capabilities */	if (!LOCAL->gotcapability) imap_send (stream,"CAPABILITY",NIL);				/* remote name for authentication */	strncpy (mb.host,net_remotehost (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->use.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);	    stream->mailbox = s;/* set as new mailbox name to open */	    return imap_open (stream);	  }	  return NIL;		/* authentication failed */	}      }    }    else {			/* log error if there was one */      if (reply) mm_log (reply->text,ERROR);      return NIL;		/* lost during greeting */    }				/* get server capabilities again */    if (!LOCAL->gotcapability) imap_send (stream,"CAPABILITY",NIL);  }  if (LOCAL->netstream) {	/* still have a connection? */    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 */      return imap_open (stream);/* recurse to log in on real site */    }    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",net_host (LOCAL->netstream));    if (!((i = net_port (LOCAL->netstream)) & 0xffff0000))      sprintf (tmp + strlen (tmp),":%lu",i);    strcat (tmp,"/imap");    if (mb.altflag) sprintf (tmp + strlen (tmp),"/%s",(char *)			     mail_parameters (NIL,GET_ALTDRIVERNAME,NIL));    if (mb.altopt) sprintf (tmp + strlen (tmp),"/%s",(char *)			    mail_parameters (NIL,GET_ALTOPTIONNAME,NIL));    if (mb.secflag) strcat (tmp,"/secure");    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);      else 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;      if (imap_OK (stream,reply = imap_send (stream,stream->rdonly ?					     "EXAMINE": "SELECT",args))) {				/* mailbox name */	sprintf (tmp + strlen (tmp),"}%s",mb.mailbox);	if (!stream->nmsgs && !stream->silent)	  mm_log ("Mailbox is empty",(long) NIL);				/* note if an INBOX or not */	stream->inbox = !strcmp (ucase (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 (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 */

⌨️ 快捷键说明

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