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

📄 imap4r1.c

📁 SIP 1.5.0源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    imap_send (stream,"FETCH",args);    fs_give ((void **) &s);  }  ov.optional.lines = 0;	/* now overview each message */  ov.optional.xref = NIL;  if (ofn) for (i = 1; i <= stream->nmsgs; i++)    if (((elt = mail_elt (stream,i))->sequence) &&	(env = mail_fetch_structure (stream,i,NIL,NIL)) && ofn) {      ov.subject = env->subject;      ov.from = env->from;      ov.date = env->date;      ov.message_id = env->message_id;      ov.references = env->references;      ov.optional.octets = elt->rfc822_size;      (*ofn) (stream,mail_uid (stream,i),&ov);    }  return LONGT;}/* IMAP fetch structure * Accepts: MAIL stream *	    message # to fetch *	    pointer to return body *	    option flags * Returns: envelope of this message, body returned in body value * * Fetches the "fast" information as well */ENVELOPE *imap_structure (MAILSTREAM *stream,unsigned long msgno,BODY **body,			  long flags){  unsigned long i,j,k;  char *s,seq[128],tmp[MAILTMPLEN];  MESSAGECACHE *elt;  ENVELOPE **env;  BODY **b;  IMAPPARSEDREPLY *reply = NIL;  IMAPARG *args[3],aseq,aatt;  args[0] = &aseq; args[1] = &aatt; args[2] = NIL;  aseq.type = SEQUENCE; aseq.text = (void *) seq;  aatt.type = ATOM; aatt.text = NIL;  if (flags & FT_UID)		/* see if can find msgno from UID */    for (i = 1; i <= stream->nmsgs; i++)      if ((elt = mail_elt (stream,i))->private.uid == msgno) {	msgno = i;		/* found msgno, use it from now on */	flags &= ~FT_UID;	/* no longer a UID fetch */      }  sprintf (seq,"%lu",msgno);	/* initial sequence */				/* IMAP UID fetching is a special case */  if (LEVELIMAP4 (stream) && (flags & FT_UID)) {    strcpy (tmp,allheader);    if (LEVELIMAP4rev1(stream)){/* get extra headers if IMAP4rev1 */      if (imap_extrahdrs) sprintf (tmp + strlen (tmp)," %s %s %s",				   hdrheader,imap_extrahdrs,hdrtrailer);      else sprintf (tmp + strlen (tmp)," %s %s",hdrheader,hdrtrailer);    }    if (body) strcat (tmp," BODYSTRUCTURE");    sprintf (tmp + strlen (tmp)," %s",fasttrailer);    aatt.text = (void *) tmp;	/* do the built command */    if (!imap_OK (stream,reply = imap_send (stream,"UID FETCH",args))) {      mm_log (reply->text,ERROR);    }				/* now hunt for this UID */    for (i = 1; i <= stream->nmsgs; i++)      if ((elt = mail_elt (stream,i))->private.uid == msgno) {	if (body) *body = elt->private.msg.body;	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 ((k = imap_lookahead) && (!*env || (*env)->incomplete))				/* build message number list */      for (i = msgno + 1, s = seq; 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 (LEVELIMAP4 (stream)) {	/* has extensible body structure and UIDs */    tmp[0] = '\0';		/* initialize command */				/* need envelope? */    if (!*env || (*env)->incomplete) {      strcat (tmp," ENVELOPE");	/* yes, get it and possible extra poop */      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);      }    }				/* need anything else? */    if (body && !*b) strcat (tmp," BODYSTRUCTURE");    if (!elt->private.uid) strcat (tmp," UID");    if (!elt->day) strcat (tmp," INTERNALDATE");    if (!elt->rfc822_size) strcat (tmp," RFC822.SIZE");    if (tmp[0]) {		/* anything to do? */      strcat (tmp," FLAGS)");	/* always get current flags */      tmp[0] = '(';		/* make into a list */      aatt.text = (void *) tmp;	/* do the built command */    }  }				/* has non-extensive body */  else if (LEVELIMAP2bis (stream)) {    if (!*env || (*env)->incomplete)       aatt.text = (body && !*b) ? (void *) "FULL" : (void *) "ALL";    else if (body && !*b) aatt.text = (void *) "BODY";    else if (!(elt->rfc822_size && elt->day)) aatt.text = (void *) "FAST";  }  else if (!*env || (*env)->incomplete) aatt.text = (void *) "ALL";  else if (!(elt->rfc822_size && elt->day)) aatt.text = (void *) "FAST";  if (aatt.text) {		/* need to fetch anything? */    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)))	  LOCAL->imap2bis = NIL;/* doesn't have body capabilities */	else mm_log (reply->text,ERROR);      }      else mm_log (reply->text,ERROR);    }  }  if (body) *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){  char *t,tmp[MAILTMPLEN],part[40];  char *cmd = (LEVELIMAP4 (stream) && (flags & FT_UID)) ? "UID FETCH":"FETCH";  IMAPPARSEDREPLY *reply;  IMAPARG *args[5],aseq,aatt,alns,acls;  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 *) part;  args[0] = &aseq; args[1] = &aatt; args[2] = args[3] = args[4] = NIL;  part[0] = '\0';		/* initially no partial specifier */  if (!(flags & FT_PREFETCHTEXT) &&      LEVELIMAP4rev1 (stream)) {/* easy if IMAP4rev1 server and no prefetch */    aatt.type = (flags & FT_PEEK) ? BODYPEEK : BODYTEXT;    if (lines) {		/* want specific header lines? */      sprintf (tmp,"%s.FIELDS%s",section,(flags & FT_NOT) ? ".NOT" : "");      aatt.text = (void *) tmp;      args[2] = &alns; args[3] = &acls;    }    else {      aatt.text = (void *) section;      args[2] = &acls;    }    if (first || last) sprintf (part,"<%lu.%lu>",first,last ? last:-1);  }#if 0  /* I don't think that this is a good idea.  If partial fetch isn't available,   * the application is going to have to do a full fetch anyway if it wants to   * get the data.  The mailgets call will indicate what happened.   */  else if (first || last) {	/* partial fetching is only on IMAP4rev1 */    mm_notify (stream,"[NOTIMAP4REV1] Can't do partial fetch",WARN);    return NIL;  }#endif				/* BODY.PEEK[HEADER] becomes RFC822.HEADER */  else if (!strcmp (section,"HEADER")) {    if (flags & FT_PEEK) aatt.text = (void *)      ((flags & FT_PREFETCHTEXT) ? "(RFC822.HEADER RFC822.TEXT)" :       "RFC822.HEADER");    else {      mm_notify (stream,"[NOTIMAP4] Can't do non-peeking header fetch",WARN);      return NIL;    }  }				/* other peeking was introduced in RFC-1730 */  else if ((flags & FT_PEEK) && !LEVEL1730 (stream)) {    mm_notify (stream,"[NOTIMAP4] Can't do peeking fetch",WARN);    return NIL;  }				/* BODY[TEXT] becomes RFC822.TEXT */  else if (!strcmp (section,"TEXT")) aatt.text = (void *)    ((flags & FT_PEEK) ? "RFC822.TEXT.PEEK" : "RFC822.TEXT");				/* BODY[] becomes RFC822 */  else if (!section[0]) aatt.text = (void *)    ((flags & FT_PEEK) ? "RFC822.PEEK" : "RFC822");				/* nested header */  else if (t = strstr (section,".HEADER")) {    if (!LEVEL1730 (stream)) {	/* this was introduced in RFC-1730 */      mm_notify (stream,"[NOTIMAP4] Can't do nested header fetch",WARN);      return NIL;    }    aatt.type = (flags & FT_PEEK) ? BODYPEEK : BODYTEXT;    args[2] = &acls;		/* will need to close section */    aatt.text = (void *) tmp;	/* convert .HEADER to .0 for RFC-1730 server */    strncpy (tmp,section,t-section);    strcpy (tmp+(t-section),".0");  }				/* extended nested text */  else if (strstr (section,".MIME") || strstr (section,".TEXT")) {    mm_notify (stream,"[NOTIMAP4REV1] Can't do extended body part fetch",WARN);    return NIL;  }				/* nested message */  else if (LEVELIMAP2bis (stream)) {    aatt.type = (flags & FT_PEEK) ? BODYPEEK : BODYTEXT;    args[2] = &acls;		/* will need to close section */    aatt.text = (void *) section;  }  else {			/* ancient server */    mm_notify (stream,"[NOTIMAP2BIS] Can't do body part fetch",WARN);    return NIL;  }				/* send the fetch command */  if (!imap_OK (stream,reply = imap_send (stream,cmd,args))) {    mm_log (reply->text,ERROR);    return NIL;			/* failure */  }  return T;}/* IMAP fetch UID * Accepts: MAIL stream *	    message number * Returns: UID */unsigned long imap_uid (MAILSTREAM *stream,unsigned long msgno){  MESSAGECACHE *elt;  IMAPPARSEDREPLY *reply;  IMAPARG *args[3],aseq,aatt;  char *s,seq[MAILTMPLEN];  unsigned long i,j,k;				/* IMAP2 didn't have UIDs */  if (!LEVELIMAP4 (stream)) return msgno;				/* do we know its UID yet? */  if (!(elt = mail_elt (stream,msgno))->private.uid) {    aseq.type = SEQUENCE; aseq.text = (void *) seq;    aatt.type = ATOM; aatt.text = (void *) "UID";    args[0] = &aseq; args[1] = &aatt; args[2] = NIL;    sprintf (seq,"%lu",msgno);    if (k = imap_uidlookahead) {/* build UID list */      for (i = msgno + 1, s = seq; k && (i <= stream->nmsgs); i++)	if (!mail_elt (stream,i)->private.uid) {	  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 a UID */	       k && (j <= stream->nmsgs) && !mail_elt (stream,j)->private.uid;	       j++, k--);				/* if different, make a range */	  if (i != --j) sprintf (s + strlen (s),":%lu",i = j);	}    }				/* send "FETCH msgno UID" */    if (!imap_OK (stream,reply = imap_send (stream,"FETCH",args)))      mm_log (reply->text,ERROR);  }  return elt->private.uid;	/* return our UID now */}/* IMAP fetch message number from UID * Accepts: MAIL stream *	    UID * Returns: message number */unsigned long imap_msgno (MAILSTREAM *stream,unsigned long uid){  IMAPPARSEDREPLY *reply;  IMAPARG *args[3],aseq,aatt;  char seq[MAILTMPLEN];  unsigned long msgno;				/* IMAP2 didn't have UIDs */  if (!LEVELIMAP4 (stream)) return uid;				/* have server hunt for UID */  aseq.type = SEQUENCE; aseq.text = (void *) seq;  aatt.type = ATOM; aatt.text = (void *) "UID";  args[0] = &aseq; args[1] = &aatt; args[2] = NIL;  sprintf (seq,"%lu",uid);				/* send "UID FETCH uid UID" */  if (!imap_OK (stream,reply = imap_send (stream,"UID FETCH",args)))    mm_log (reply->text,ERROR);  for (msgno = 1; msgno <= stream->nmsgs; msgno++)    if (mail_elt (stream,msgno)->private.uid == uid) return msgno;  return 0;			/* didn't find the UID anywhere */}/* IMAP modify flags * Accepts: MAIL stream *	    sequence *	    flag(s) *	    option flags */void imap_flag (MAILSTREAM *stream,char *sequence,char *flag,long flags){  char *cmd = (LEVELIMAP4 (stream) && (flags & ST_UID)) ? "UID STORE":"STORE";  IMAPPARSEDREPLY *reply;  IMAPARG *args[4],aseq,ascm,aflg;  aseq.type = SEQUENCE; aseq.text = (void *) sequence;  ascm.type = ATOM; ascm.text = (void *)    ((flags & ST_SET) ?     ((LEVELIMAP4 (stream) && (flags & ST_SILENT)) ?      "+Flags.silent" : "+Flags") :     ((LEVELIMAP4 (stream) && (flags & ST_SILENT)) ?      "-Flags.silent" : "-Flags"));  aflg.type = FLAGS; aflg.text = (void *) flag;  args[0] = &aseq; args[1] = &ascm; args[2] = &aflg; args[3] = NIL;				/* send "STORE sequence +Flags flag" */  if (!imap_OK (stream,reply = imap_send (stream,cmd,args)))    mm_log (reply->text,ERROR);}/* IMAP search for messages * Accepts: MAIL stream *	    character set *	    search program *	    option flags */void imap_search (MAILSTREAM *stream,char *charset,SEARCHPGM *pgm,long flags){  char *cmd = (LEVELIMAP4 (stream) && (flags & SE_UID)) ?"UID SEARCH":"SEARCH";  unsigned long i,j,k;  char *s,tmp[MAILTMPLEN];  IMAPPARSEDREPLY *reply;  MESSAGECACHE *elt;  IMAPARG *args[4],apgm,aseq,aatt,achs;  args[1] = args[2] = args[3] = NIL;  apgm.type = SEARCHPROGRAM; apgm.text = (void *) pgm;  aseq.type = SEQUENCE;  aatt.type = ATOM;  achs.type = ASTRING;  if (charset) {		/* optional charset argument requested */    args[0] = &aatt; args[1] = &achs; args[2] = &apgm;    aatt.text = (void *) "CHARSET";    achs.text = (void *) charset;  }  else args[0] = &apgm;				/* be sure that receiver understands */  LOCAL->uidsearch = (flags & SE_UID) ? T : NIL;  if (!LEVELIMAP4 (stream) &&	/* if old server but new functions... */      (charset || LOCAL->uidsearch || pgm->msgno || pgm->uid || pgm->search_or ||       pgm->search_not || pgm->header || pgm->larger || pgm->smaller ||       pgm->sentbefore || pgm->senton || pgm->sentsince || pgm->draft ||       pgm->undraft || pgm->return_path || pgm->sender || pgm->reply_to ||       pgm->message_id || pgm->in_reply_to || pgm->newsgroups ||

⌨️ 快捷键说明

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