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

📄 imap4r1.c

📁 SIP 1.5.0源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
       pgm->followup_to || pgm->references))    mail_search_default (stream,charset,pgm,flags);				/* do the SEARCH */  else if (!imap_OK (stream,reply = imap_send (stream,cmd,args)))    mm_log (reply->text,ERROR);				/* can never pre-fetch with a short cache */  else if ((k = imap_prefetch) && !(flags & (SE_NOPREFETCH|SE_UID)) &&	   !stream->scache) {	/* only if prefetching permitted */    s = LOCAL->tmp;		/* build sequence in temporary buffer */    *s = '\0';			/* initially nothing */				/* search through mailbox */    for (i = 1; k && (i <= stream->nmsgs); ++i) 				/* for searched messages with no envelope */      if ((elt = mail_elt (stream,i)) && elt->searched &&	  !mail_elt (stream,i)->private.msg.env) {				/* prepend with comma if not first time */	if (LOCAL->tmp[0]) *s++ = ',';	sprintf (s,"%lu",j = i);/* output message number */	s += strlen (s);	/* point at end of string */	k--;			/* count one up */				/* search for possible end of range */	while (k && (i < stream->nmsgs) &&	       (elt = mail_elt (stream,i+1))->searched &&	       !elt->private.msg.env) i++,k--;	if (i != j) {		/* if a range */	  sprintf (s,":%lu",i);	/* output delimiter and end of range */	  s += strlen (s);	/* point at end of string */	}      }    if (LOCAL->tmp[0]) {	/* anything to pre-fetch? */      args[0] = &aseq; args[1] = &aatt; args[2] = NIL;      aseq.text = (void *) cpystr (LOCAL->tmp);      if (LEVELIMAP4 (stream)) {/* IMAP4 fetching does more */	strcpy (tmp,allheader);	if (LEVELIMAP4rev1 (stream)) {	  if (imap_extrahdrs) sprintf (tmp + strlen (tmp)," %s %s %s",				       hdrheader,imap_extrahdrs,hdrtrailer);	  else sprintf (tmp + strlen (tmp)," %s %s",hdrheader,hdrtrailer);	}	sprintf (tmp + strlen (tmp)," %s",fasttrailer);	aatt.text = (void *) tmp;      }      else aatt.text = (void *) "ALL";      if (!imap_OK (stream,reply = imap_send (stream,"FETCH",args)))	mm_log (reply->text,ERROR);				/* flush copy of sequence */      fs_give ((void **) &aseq.text);    }  }}/* IMAP sort messages * Accepts: mail stream *	    character set *	    search program *	    sort program *	    option flags * Returns: vector of sorted message sequences or NIL if error */unsigned long *imap_sort (MAILSTREAM *stream,char *charset,SEARCHPGM *spg,			  SORTPGM *pgm,long flags){  unsigned long i,j,start,last;  unsigned long *ret = NIL;  pgm->nmsgs = 0;		/* start off with no messages */				/* can use server-based sort? */  if (LEVELSORT (stream) && !(flags & SO_NOSERVER)) {    char *cmd = (flags & SE_UID) ? "UID SORT" : "SORT";    IMAPARG *args[4],apgm,achs,aspg;    IMAPPARSEDREPLY *reply;    SEARCHSET *ss = NIL;    apgm.type = SORTPROGRAM; apgm.text = (void *) pgm;    achs.type = ASTRING; achs.text = (void *) (charset ? charset : "US-ASCII");    aspg.type = SEARCHPROGRAM;				/* did he provide a searchpgm? */    if (!(aspg.text = (void *) spg)) {      for (i = 1,start = last = 0; i <= stream->nmsgs; ++i)	if (mail_elt (stream,i)->searched) {	  if (ss) {		/* continuing a sequence */	    if (i == last + 1) last = i;	    else {		/* end of range */	      if (last != start) ss->last = last;	      (ss = ss->next = mail_newsearchset ())->first = i;	      start = last = i;	/* begin a new range */	    }	  }	  else {		/* first time, start new searchpgm */	    (spg = mail_newsearchpgm ())->msgno = ss = mail_newsearchset ();	    ss->first = start = last = i;	  }	}				/* nothing to sort if no messages */      if (!(aspg.text = (void *) spg)) return NIL;				/* else install last sequence */      if (last != start) ss->last = last;    }    args[0] = &apgm; args[1] = &achs; args[2] = &aspg; args[3] = NIL;    if (imap_OK (stream,reply = imap_send (stream,cmd,args))) {      pgm->nmsgs = LOCAL->sortsize;      ret = LOCAL->sortdata;      LOCAL->sortdata = NIL;	/* mail program is responsible for flushing */    }    else mm_log (reply->text,ERROR);				/* free any temporary searchpgm */    if (ss) mail_free_searchpgm (&spg);  }				/* not much can do if short caching */  else if (stream->scache) ret = mail_sort_msgs (stream,charset,spg,pgm,flags);  else {			/* try to be a bit more clever */    char *s,*t;    unsigned long len;    MESSAGECACHE *elt;    SORTCACHE **sc;    SORTPGM *sp;    int needenvs = 0;				/* see if need envelopes */    for (sp = pgm; sp && !needenvs; sp = sp->next) switch (sp->function) {    case SORTDATE: case SORTFROM: case SORTSUBJECT: case SORTTO: case SORTCC:      needenvs = T;    }    if (spg) {			/* only if a search needs to be done */      int silent = stream->silent;      stream->silent = T;	/* don't pass up mm_searched() events */				/* search for messages */      mail_search_full (stream,charset,spg,NIL);      stream->silent = silent;	/* restore silence state */    }				/* initialize progress counters */    pgm->nmsgs = pgm->progress.cached = 0;				/* pass 1: count messages to sort */    for (i = 1,len = start = last = 0,s = t = NIL; i <= stream->nmsgs; ++i)      if ((elt = mail_elt (stream,i))->searched) {	pgm->nmsgs++;	if (needenvs ? !elt->private.msg.env : !elt->day) {	  if (s) {		/* continuing a sequence */	    if (i == last + 1) last = i;	    else {		/* end of range */	      if (last != start) sprintf (t,":%lu,%lu",last,i);	      else sprintf (t,",%lu",i);	      start = last = i;	/* begin a new range */	      if ((j = ((t += strlen (t)) - s)) > (MAILTMPLEN - 20)) {		fs_resize ((void **) s,len += MAILTMPLEN);		t = s + j;	/* relocate current pointer */	      }	    }	  }	  else {		/* first time, start new buffer */	    s = (char *) fs_get (len = MAILTMPLEN);	    sprintf (s,"%lu",start = last = i);	    t = s + strlen (s);	/* end of buffer */	  }	}      }				/* last sequence */    if (last != start) sprintf (t,":%lu",last);    if (s) {			/* prefetch needed data */      IMAPARG *args[7],aseq,aatt[5];      args[0] = &aseq; args[1] = &aatt[0];      aseq.type = SEQUENCE; aseq.text = (void *) s;				/* send the hairier form if IMAP4rev1 */      if (needenvs && LEVELIMAP4rev1 (stream)) {	aatt[0].type = aatt[1].type = aatt[2].type = aatt[3].type =	  aatt[4].type = ATOM;	aatt[0].text = (void *) allheader;	aatt[1].text = (void *) hdrheader;	aatt[3].text = (void *) hdrtrailer;	aatt[4].text = (void *) fasttrailer;	args[i = 2] = &aatt[1];	if (aatt[2].text = (void *) imap_extrahdrs) args[++i] = &aatt[2];	args[++i] = &aatt[3];	args[++i] = &aatt[4];	args[++i] = NIL;      }      else {			/* just do FETCH ALL */	aatt[0].type = ATOM;	aatt[0].text = (void *) (needenvs ? "ALL" : "FAST");	args[2] = NIL;      }      imap_send (stream,"FETCH",args);      fs_give ((void **) &s);    }    if (pgm->nmsgs) {		/* pass 2: sort cache */      sortresults_t sr = (sortresults_t)	mail_parameters (NIL,GET_SORTRESULTS,NIL);      sc = mail_sort_loadcache (stream,pgm);				/* pass 3: sort messages */      if (!pgm->abort) ret = mail_sort_cache (stream,pgm,sc,flags);      fs_give ((void **) &sc);	/* don't need sort vector any more */				/* also return via callback if requested */      if (sr) (*sr) (stream,ret,pgm->nmsgs);    }  }  return ret;}/* IMAP thread messages * Accepts: mail stream *	    thread type *	    character set *	    search program *	    option flags * Returns: thread node tree */THREADNODE *imap_thread (MAILSTREAM *stream,char *type,char *charset,			 SEARCHPGM *spg,long flags){  THREADNODE *ret = NIL;  THREADER *thr;				/* does server have this threader type? */  for (thr = LOCAL->threader; thr && mail_compare_cstring (thr->name,type);       thr = thr->next);  if (thr) {			/* found threader? */    unsigned long i,start,last;    char *cmd = (flags & SE_UID) ? "UID THREAD" : "THREAD";    IMAPARG *args[4],apgm,achs,aspg;    IMAPPARSEDREPLY *reply;    SEARCHSET *ss = NIL;    apgm.type = ATOM; apgm.text = (void *) type;    achs.type = ASTRING; achs.text = (void *) (charset ? charset : "US-ASCII");    aspg.type = SEARCHPROGRAM;				/* did he provide a searchpgm? */    if (!(aspg.text = (void *) spg)) {      for (i = 1,start = last = 0; i <= stream->nmsgs; ++i)	if (mail_elt (stream,i)->searched) {	  if (ss) {		/* continuing a sequence */	    if (i == last + 1) last = i;	    else {		/* end of range */	      if (last != start) ss->last = last;	      (ss = ss->next = mail_newsearchset ())->first = i;	      start = last = i;	/* begin a new range */	    }	  }	  else {		/* first time, start new searchpgm */	    (spg = mail_newsearchpgm ())->msgno = ss = mail_newsearchset ();	    ss->first = start = last = i;	  }	}				/* nothing to sort if no messages */      if (!(aspg.text = (void *) spg)) return NIL;				/* else install last sequence */      if (last != start) ss->last = last;    }    args[0] = &apgm; args[1] = &achs; args[2] = &aspg; args[3] = NIL;    if (imap_OK (stream,reply = imap_send (stream,cmd,args))) {      ret = LOCAL->threaddata;      LOCAL->threaddata = NIL;	/* mail program is responsible for flushing */    }    else mm_log (reply->text,ERROR);				/* free any temporary searchpgm */    if (ss) mail_free_searchpgm (&spg);  }  else ret = mail_thread_msgs (stream,type,charset,spg,flags | SO_NOSERVER,			       imap_sort);  return ret;}/* IMAP ping mailbox * Accepts: MAIL stream * Returns: T if stream still alive, else NIL */long imap_ping (MAILSTREAM *stream){  return (LOCAL->netstream &&	/* send "NOOP" */	  imap_OK (stream,imap_send (stream,"NOOP",NIL))) ? T : NIL;}/* IMAP check mailbox * Accepts: MAIL stream */void imap_check (MAILSTREAM *stream){				/* send "CHECK" */  IMAPPARSEDREPLY *reply = imap_send (stream,"CHECK",NIL);  mm_log (reply->text,imap_OK (stream,reply) ? (long) NIL : ERROR);}/* IMAP expunge mailbox * Accepts: MAIL stream */void imap_expunge (MAILSTREAM *stream){				/* send "EXPUNGE" */  IMAPPARSEDREPLY *reply = imap_send (stream,"EXPUNGE",NIL);  mm_log (reply->text,imap_OK (stream,reply) ? (long) NIL : ERROR);}/* IMAP copy message(s) * Accepts: MAIL stream *	    sequence *	    destination mailbox *	    option flags * Returns: T if successful else NIL */long imap_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long flags){  char *cmd = (LEVELIMAP4 (stream) && (flags & CP_UID)) ? "UID COPY" : "COPY";  char *s;  IMAPPARSEDREPLY *reply;  IMAPARG *args[3],aseq,ambx;  imapreferral_t ir =    (imapreferral_t) mail_parameters (stream,GET_IMAPREFERRAL,NIL);  mailproxycopy_t pc =    (mailproxycopy_t) mail_parameters (stream,GET_MAILPROXYCOPY,NIL);  aseq.type = SEQUENCE; aseq.text = (void *) sequence;  ambx.type = ASTRING; ambx.text = (void *) mailbox;  args[0] = &aseq; args[1] = &ambx; args[2] = NIL;				/* send "COPY sequence mailbox" */  if (!imap_OK (stream,reply = imap_send (stream,cmd,args))) {    if (ir && pc && LOCAL->referral && mail_sequence (stream,sequence) &&	(s = (*ir) (stream,LOCAL->referral,REFCOPY)))      return (*pc) (stream,sequence,s,flags);    mm_log (reply->text,ERROR);    return NIL;  }				/* delete the messages if the user said to */  if (flags & CP_MOVE) imap_flag (stream,sequence,"\\Deleted",				  ST_SET + ((flags & CP_UID) ? ST_UID : NIL));  return T;}/* IMAP mail append message from stringstruct * Accepts: MAIL stream *	    destination mailbox *	    append callback *	    data for callback * Returns: T if append successful, else NIL */long imap_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data){  MAILSTREAM *st = stream;  IMAPARG *args[3],ambx,amap;  IMAPPARSEDREPLY *reply;  APPENDDATA map;  STRING *message;  char *flags,*date,tmp[MAILTMPLEN];  long ret = NIL;  imapreferral_t ir =    (imapreferral_t) mail_parameters (stream,GET_IMAPREFERRAL,NIL);				/* barf if bad mailbox */  if (mail_valid_net (mailbox,&imapdriver,NIL,tmp)) {				/* create a stream if given one no good */    if (!(stream && LOCAL && LOCAL->netstream) &&	!(stream =  mail_open (NIL,mailbox,OP_HALFOPEN|OP_SILENT)))      mm_log ("Can't access server for append",ERROR);				/* use multi-append? */    else if (LEVELMULTIAPPEND (stream)) {      ambx.type = ASTRING; ambx.text = (void *) tmp;      amap.type = MULTIAPPEND; amap.text = (void *) &map;      map.af = af; map.data = data;      args[0] = &ambx; args[1] = &amap; args[2] = NIL;				/* success if OK */      if (imap_OK (stream,reply = imap_send (stream,"APPEND",args)))	ret = LONGT;				/* failed, is there a referral? */      else if (ir && LOCAL->referral &&	       (mailbox = (*ir) (stream,LOCAL->referral,REFAPPEND)))	ret = imap_append (NIL,mailbox,af,data);      else mm_log (reply->text,ERROR);    }				/* do multiple single appends */    else while ((ret = ((*af) (stream,data,&flags,&date,&message))) &&		message &&		(ret = imap_append_single (stream,tmp,flags,date,message,ir)));				/* toss out temporary stream */    if (st != stream) mail_close (stream);  }  return ret;			/* return */}/* IMAP append single message * Accepts: mail stream *	    dest

⌨️ 快捷键说明

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