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

📄 imap4r1.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
	return elt->private.msg.env;      }    if (body) *body = NIL;	/* can't find the UID */    return NIL;  }  elt = mail_elt (stream,msgno);/* get cache pointer */  if (stream->scache) {		/* short caching? */    env = &stream->env;		/* use temporaries on the stream */    b = &stream->body;    if (msgno != stream->msgno){/* flush old poop if a different message */      mail_free_envelope (env);      mail_free_body (b);      stream->msgno = msgno;	/* this is now the current short cache msg */    }  }  else {			/* normal cache */    env = &elt->private.msg.env;/* get envelope and body pointers */    b = &elt->private.msg.body;				/* prefetch if don't have envelope */    if (!(flags & FT_NOLOOKAHEAD) &&	((!*env || (*env)->incomplete) ||	 (body && !*b && LEVELIMAP2bis (stream)))) {      if (set) {		/* have a lookahead list? */	MESSAGE *msg;	for (k = imap_fetchlookaheadlimit;	     k && set && (((s += strlen (s)) - seq) < (MAXCOMMAND - 30));	     set = set->next) {	  i = (set->first == 0xffffffff) ? stream->nmsgs :	    min (set->first,stream->nmsgs);	  if (j = (set->last == 0xffffffff) ? stream->nmsgs :	      min (set->last,stream->nmsgs)) {	    if (i > j) {	/* swap the range if backwards */	      x = i; i = j; j = x;	    }				/* find first message not msgno or in cache */	    while (((i == msgno) ||		    ((msg = &(mail_elt (stream,i)->private.msg))->env &&		     (!body || msg->body))) && (i++ < j));				/* until range or lookahead finished */	    while (k && (i <= j)) {				/* find first cached message in range */	      for (x = i + 1; (x <= j) &&		     !((msg = &(mail_elt (stream,x)->private.msg))->env &&		       (!body || msg->body)); x++);	      if (i == --x) {	/* only one message? */		sprintf (s += strlen (s),",%lu",i++);		k--;		/* prefetching one message */	      }	      else {		/* a range to prefetch */		sprintf (s += strlen (s),",%lu:%lu",i,x);		i = 1 + x - i;	/* number of messages in this range */				/* still can look ahead some more? */		if (k = (k > i) ? k - i : 0)				/* yes, scan further in this range */		  for (i = x + 2; (i <= j) &&			 ((i == msgno) || 			  ((msg = &(mail_elt (stream,i)->private.msg))->env &&			   (!body || msg->body)));		       i++);	      }	    }	  }	  else if ((i != msgno) && !mail_elt (stream,i)->private.msg.env) {	    sprintf (s += strlen (s),",%lu",i);	    k--;		/* prefetching one message */	  }      }      }				/* build message number list */      else for (i = msgno+1,k = imap_lookahead; k && (i <= stream->nmsgs); i++)	if (!mail_elt (stream,i)->private.msg.env) {	  s += strlen (s);	/* find string end, see if nearing end */	  if ((s - seq) > (MAILTMPLEN - 20)) break;	  sprintf (s,",%lu",i);	/* append message */ 	  for (j = i + 1, k--;	/* hunt for last message without an envelope */	       k && (j <= stream->nmsgs) &&	       !mail_elt (stream,j)->private.msg.env; j++, k--);				/* if different, make a range */	  if (i != --j) sprintf (s + strlen (s),":%lu",i = j);	}    }  }  if (!stream->lock) {		/* no-op if stream locked */    /* Build the fetch attributes.  Unlike imap_fetch(), this tries not to     * fetch data that is already cached.  However, since it is based on the     * message requested and not on any of the prefetched messages, it can     * goof, either by fetching data already cached or not prefetching data     * that isn't cached (but was cached in the message requested).     * Fortunately, no great harm is done.  If it doesn't prefetch the data,     * it will get it when the affected message(s) are requested.     */    if (!elt->private.uid && LEVELIMAP4 (stream)) strcpy (tmp," UID");    else tmp[0] = '\0';		/* initialize command */				/* need envelope? */    if (!*env || (*env)->incomplete) {      strcat (tmp," ENVELOPE");	/* yes, get it and possible extra poop */      if (!(flags & FT_NOHDRS) && LEVELIMAP4rev1 (stream)) {	if (imap_extrahdrs) sprintf (tmp + strlen (tmp)," %s %s %s",				     hdrheader[LOCAL->cap.extlevel],				     imap_extrahdrs,hdrtrailer);	else sprintf (tmp + strlen (tmp)," %s %s",		      hdrheader[LOCAL->cap.extlevel],hdrtrailer);      }    }				/* need body? */    if (body && !*b && LEVELIMAP2bis (stream))      strcat (tmp,LEVELIMAP4 (stream) ? " BODYSTRUCTURE" : " BODY");    if (!elt->day) strcat (tmp," INTERNALDATE");    if (!elt->rfc822_size) strcat (tmp," RFC822.SIZE");    if (tmp[0]) {		/* anything to do? */      tmp[0] = '(';		/* make into a list */      strcat (tmp," FLAGS)");	/* always get current flags */      aatt.text = (void *) tmp;	/* do the built command */      if (!imap_OK (stream,reply = imap_send (stream,"FETCH",args))) {				/* failed, probably RFC-1176 server */	if (!LEVELIMAP4 (stream) && LEVELIMAP2bis (stream) && body && !*b){	  aatt.text = (void *) "ALL";	  if (imap_OK (stream,reply = imap_send (stream,"FETCH",args)))				/* doesn't have body capabilities */	    LOCAL->cap.imap2bis = NIL;	  else mm_log (reply->text,ERROR);	}	else mm_log (reply->text,ERROR);      }    }  }  if (body) {			/* wants to return body */    if (!*b && !LEVELIMAP2bis (stream)) {				/* simulate body structure fetch for IMAP2 */      *b = mail_initbody (mail_newbody ());      (*b)->subtype = cpystr (rfc822_default_subtype ((*b)->type));      ((*b)->parameter = mail_newbody_parameter ())->attribute =	cpystr ("CHARSET");      (*b)->parameter->value = cpystr ("US-ASCII");      s = mail_fetch_text (stream,msgno,NIL,&i,flags);      (*b)->size.bytes = i;      while (i--) if (*s++ == '\n') (*b)->size.lines++;    }    *body = *b;			/* return the body */  }  return *env;			/* return the envelope */}/* IMAP fetch message data * Accepts: MAIL stream *	    message number *	    section specifier *	    offset of first designated byte or 0 to start at beginning *	    maximum number of bytes or 0 for all bytes *	    lines to fetch if header *	    flags * Returns: T on success, NIL on failure */long imap_msgdata (MAILSTREAM *stream,unsigned long msgno,char *section,		   unsigned long first,unsigned long last,STRINGLIST *lines,		   long flags){  int i;  char *t,tmp[MAILTMPLEN],partial[40],seq[40];  char *noextend,*nopartial,*nolines,*nopeek,*nononpeek;  char *cmd = (LEVELIMAP4 (stream) && (flags & FT_UID)) ? "UID FETCH":"FETCH";  IMAPPARSEDREPLY *reply;  IMAPARG *args[5],*auxargs[3],aseq,aatt,alns,acls,aflg;  noextend = nopartial = nolines = nopeek = nononpeek = NIL;				/* does searching desire a lookahead? */  if ((flags & FT_SEARCHLOOKAHEAD) && (msgno < stream->nmsgs) &&      !stream->scache) {    sprintf (seq,"%lu:%lu",msgno,	     (unsigned long) min (msgno + IMAPLOOKAHEAD,stream->nmsgs));    aseq.type = SEQUENCE;    aseq.text = (void *) seq;  }  else {			/* no, do it the easy way */    aseq.type = NUMBER;    aseq.text = (void *) msgno;  }  aatt.type = ATOM;		/* assume atomic attribute */  alns.type = LIST; alns.text = (void *) lines;  acls.type = BODYCLOSE; acls.text = (void *) partial;  aflg.type = ATOM; aflg.text = (void *) "FLAGS";  args[0] = &aseq; args[1] = &aatt; args[2] = args[3] = args[4] = NIL;  auxargs[0] = &aseq; auxargs[1] = &aflg; auxargs[2] = NIL;  partial[0] = '\0';		/* initially no partial specifier */  if (LEVELIMAP4rev1 (stream)) {/* easy if IMAP4rev1 server */				/* HEADER fetching with special handling? */    if (!strcmp (section,"HEADER") && (lines || (flags & FT_PREFETCHTEXT))) {      if (lines) {		/* want specific header lines? */	aatt.type = (flags & FT_PEEK) ? BODYPEEK : BODYTEXT;	aatt.text = (void *) ((flags & FT_NOT) ?			      "HEADER.FIELDS.NOT" : "HEADER.FIELDS");	args[2] = &alns; args[3] = &acls;      }				/* must be prefetching */      else aatt.text = (void *) ((flags & FT_PEEK) ?				 "(BODY.PEEK[HEADER] BODY.PEEK[TEXT])" :				 "(BODY[HEADER] BODY[TEXT])");    }    else {			/* simple case */      aatt.type = (flags & FT_PEEK) ? BODYPEEK : BODYTEXT;      aatt.text = (void *) section;      args[2] = &acls;    }    if (first || last) sprintf (partial,"<%lu.%lu>",first,last ? last:-1);  }  /* IMAP4 did not have:   * . HEADER body part (can simulate with BODY[0] or BODY.PEEK[0])   * . TEXT body part (can simulate top-level with RFC822.TEXT or   *			RFC822.TEXT.PEEK)   * . MIME body part   * . (usable) partial fetching   * . (usable) selective header line fetching   */  else if (LEVEL1730 (stream)) {/* IMAP4 (RFC 1730) compatibility */				/* BODY[HEADER] becomes BODY.PEEK[0] */    if (!strcmp (section,"HEADER"))      aatt.text = (void *)	((flags & FT_PREFETCHTEXT) ?	 ((flags & FT_PEEK) ? "(BODY.PEEK[0] RFC822.TEXT.PEEK)" :	  "(BODY[0] RFC822.TEXT)") :	 ((flags & FT_PEEK) ? "BODY.PEEK[0]" : "BODY[0]"));				/* BODY[TEXT] becomes RFC822.TEXT */    else if (!strcmp (section,"TEXT"))      aatt.text = (void *) ((flags & FT_PEEK) ? "RFC822.TEXT.PEEK" :			    "RFC822.TEXT");    else if (!section[0])	/* BODY[] becomes RFC822 */      aatt.text = (void *) ((flags & FT_PEEK) ? "RFC822.PEEK" : "RFC822");				/* nested header */    else if (t = strstr (section,".HEADER")) {      aatt.type = (flags & FT_PEEK) ? BODYPEEK : BODYTEXT;      args[2] = &acls;		/* will need to close section */      aatt.text = (void *) tmp;	/* convert .HEADER to .0 */      strncpy (tmp,section,t-section);      strcpy (tmp+(t-section),".0");    }    else {			/* IMAP4 body part */      aatt.type = (flags & FT_PEEK) ? BODYPEEK : BODYTEXT;      args[2] = &acls;		/* will need to close section */      aatt.text = (void *) section;    }    if (strstr (section,".MIME") || strstr (section,".TEXT")) noextend = "4";    if (first || last) nopartial = "4";    if (lines) nolines = "4";  }  /* IMAP2bis did not have:   * . HEADER body part (can simulate peeking top-level with RFC822.HEADER)   * . TEXT body part (can simulate non-peeking top-level with RFC822.TEXT)   * . MIME body part   * . partial fetching   * . selective header line fetching   * . non-peeking header fetching   * . peeking body fetching   */				/* IMAP2bis compatibility */  else if (LEVELIMAP2bis (stream)) {				/* BODY[HEADER] becomes RFC822.HEADER */    if (!strcmp (section,"HEADER")) {      aatt.text = (void *)	((flags & FT_PREFETCHTEXT) ?	 "(RFC822.HEADER RFC822.TEXT)" : "RFC822.HEADER");      if (flags & FT_PEEK) flags &= ~FT_PEEK;      else nononpeek = "2bis";    }				/* BODY[TEXT] becomes RFC822.TEXT */    else if (!strcmp (section,"TEXT")) aatt.text = (void *) "RFC822.TEXT";				/* BODY[] becomes RFC822 */    else if (!section[0]) aatt.text = (void *) "RFC822";    else {			/* IMAP2bis body part */      aatt.type = BODYTEXT;      args[2] = &acls;		/* will need to close section */      aatt.text = (void *) section;    }    if (strstr (section,".HEADER") || strstr (section,".MIME") ||	     strstr (section,".TEXT")) noextend = "2bis";    if (first || last) nopartial = "2bis";    if (lines) nolines = "2bis";    if (flags & FT_PEEK) nopeek = "2bis";  }  /* IMAP2 did not have:   * . HEADER body part (can simulate peeking top-level with RFC822.HEADER)   * . TEXT body part (can simulate non-peeking top-level with RFC822.TEXT)   * . MIME body part   * . multiple body parts (can simulate BODY[1] with RFC822.TEXT)   * . partial fetching   * . selective header line fetching   * . non-peeking header fetching   * . peeking body fetching   */  else {			/* IMAP2 (RFC 1176/1064) compatibility */				/* BODY[HEADER] */    if (!strcmp (section,"HEADER")) {      aatt.text = (void *) ((flags & FT_PREFETCHTEXT) ?			    "(RFC822.HEADER RFC822.TEXT)" : "RFC822.HEADER");      if (flags & FT_PEEK) flags &= ~FT_PEEK;      nononpeek = "2";    }				/* BODY[TEXT] becomes RFC822.TEXT */    else if (!strcmp (section,"TEXT")) aatt.text = (void *) "RFC822.TEXT";				/* BODY[1] treated like RFC822.TEXT */    else if (!strcmp (section,"1")) {      SIZEDTEXT text;      MESSAGECACHE *elt = mail_elt (stream,msgno);				/* have a cached RFC822.TEXT? */      if (elt->private.msg.text.text.data) {	text.size = elt->private.msg.text.text.size;				/* should move instead of copy */	text.data = memcpy (fs_get (text.size+1),			    elt->private.msg.text.text.data,text.size);	(t = (char *) text.data)[text.size] = '\0';	imap_cache (stream,msgno,"1",NIL,&text);	return LONGT;		/* don't have to do any fetches */      }				/* otherwise do RFC822.TEXT */      aatt.text = (void *) "RFC822.TEXT";    }				/* BODY[] becomes RFC822 */    else if (!section[0]) aatt.text = (void *) "RFC822";    else noextend = "2";	/* how did we get here? */    if (flags & FT_PEEK) nopeek = "2";    if (first || last) nopartial = "2";    if (lines) nolines = "2";  }  /* Report unavailable functionalities.  The application can use the helpful   * LEVELIMAPREV1, LEVELIMAP4, and LEVELIMAP2bis operations provided in   * imap4r1.h to avoid triggering these errors.  There aren't any workarounds   * for these restrictions.   */  if (noextend) {    sprintf (tmp,"[NOTIMAP4REV1] IMAP%s server can't do extended body fetch",	     noextend);    mm_log (tmp,ERROR);    return NIL;			/* can't do anything close either */  }  if (nopartial) {    sprintf (tmp,"[NOTIMAP4REV1] IMAP%s server can't do partial fetch",	     nopartial);    mm_notify (stream,tmp,WARN);  }  if (nolines) {    sprintf(tmp,"[NOTIMAP4REV1] IMAP%s server can't do selective header fetch",	    nolines);    mm_notify (stream,tmp,WARN);  }				/* trying to do unsupported peek behavior? */  if ((t = nopeek) || (t = nononpeek)) {				/* get most recent \Seen setting */    if (!imap_OK (stream,reply = imap_send (stream,cmd,auxargs)))      mm_log (reply->text,WARN);				/* note current setting of \Seen flag */    if (!(i = mail_elt (stream,msgno)->seen)) {      sprintf (tmp,nopeek ?	/* only babble if \Seen not set */	       "[NOTIMAP4] Simulating peeking fetch in IMAP%s" :	       "[NOTIMAP4] Simulating non-peeking header fetch in IMAP%s",t);      mm_notify (stream,tmp,NIL);    }				/* send the fetch command */    if (!imap_OK (stream,

⌨️ 快捷键说明

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